2. GISMO Engine Implementation
The purpose of this page
is to explain the details of data extraction and map rendering.
When GISMO is Started:
When the user types gismo at a command prompt, a global variable called gData stores the string argument containing the filename root for all of the data files. The thumbnail_map_viewer constructor gets a file listing with all of the files in the current directory containing the contents of gData and redirects the output into a file. The file is then read line by line, and a new DataAbstraction object, or "tile", is created from each of the filenames read from the file. The maximum and minimum values of the X, Y, and Z coordinates in each file are remembered for each newly created DataAbstraction object. After each tile is created, a pointer to it is added to a STL vector of tiles in the thumbnail_map_viewer's GlMapWindow. A GlMapWindow also keeps track of maximum and minimum X, Y, and Z values for all of the data it is responsible for drawing. As each tile is being added, the maximum and minimum X, Y, and Z values af each DataAbstraction object are compared to that of the GlMapWindow and updated if necessary. This is done in order to set the coordinate system for the to-be-displayed map. After all tiles have been added, the GlMapWindow now has all of the data it needs, and the thumbnail map can be drawn. The following diagram is an example thumbnail map viewer and its state at this point.
When the draw() method is
called to draw a map, the display is initialized by first setting the coordinate
system to the maximum values of X and Y found when tiles are added. A loop
then reads the data for each tile, and draws the triangles that make up
that portion of the map tile. To access the data from each tile, a STL
iterator is created from the vector of tiles, and each iteration gets three
vertices from that map tile to draw a triangle.
A color, based on the Z coordinate, is associated with each vertex as it is specified. If a point is in the upper 15% of all of the points in the map, then it will be colored a shade of white, with points closer to maximum colored closer to true white. Points in the bottom 3% will be colored a shade of dark green. Points at middle range elevations will be given extra amounts of green for greater values of Z, making them lighter in color. Points with Z coordinates less than or equal to 0 will be colored Blue, in order to represent water. When the triangle is drawn, OpenGL will blend the colors of all three vertices.
The final version of our project has a fix that helps find lakes that are not at sea level. To do this, we introduced a new class, GlMath, that performs basic vector operations, such as dot products and cross products. In order to determine the color of a triangle, the triangle is tested to see if it is "flat". To do this, we first find the vectors between two of the triangle's three points by subtracting coordinates. From these two vectors the normal vector is computed. If it is parallel to <0,0,1>, or if it is perpendicular to the screen, then the triangle is flat and will be colored blue. The following diagram shows this process pictorially.
GlMapWindow events are handled
differently depending on whether or not a map window is a thumbnail or
terrain map. An integer flag determines whether or not a map is a thumbnail.
No keyboard or mouse events are handled if a map is a terrain map. The
map is simply redrawn. If a thumbnail map, a user selected region is drawn
to the overlay. The starting and ending coordinates of the region are remembered
for terrain map creation.
The method makeDisplay() will take these coordinates and convert them before passing them to a new terrain_map viewer along with a pointer to the vector of tiles. Thus all maps read the same data, so the expensive triangulate and file I/O operations only have to be performed once. When the triangles in a terrain map are drawn, those lying outside the smaller coordinate system will be ignored. The following diagram shows the state after a user has selected two separate regions.