Tirol Atlas Topo - SVG on top of a dynamic mapping system

The Tirol Atlas (an Interreg IIIa project funded by the European Union and the regional governments of Tirol, Austria and South Tirol, Italy, carried out by the Department of Geography, University of Innsbruck) has been using SVG for three years now to visualize thematic maps, charts, diagrams and highly interactive learning applications for kids. The latest efforts target creation of a topographic map with a scale reaching from 1:2 Mio to about 1:100.000 at the most detailed level. PostgreSQL with PostGIS, University of Minnesota mapserver (UMN), GRASS-GIS, Perl, Python in conjunction with ESRI's geoprocessing capabilities and last but not least SVG at visualization level are the main components of the application that will be outlined in this abstract.

A. The basic Interface

The basic interface is more than yet another SVG mapping interface with standard components like main- and overviewmap, zoom and pan controls, scalebars and a display showing coordinates as you move the mouse in the main-, or the overviewmap. In addition, a view-history indicated by arrows below the windrose allows you to navigate to previous or next extents whenever available. Coordinate display may be switched from UTM-WGS84 32N to latitude/longitude and back by clicking on the control itself. A simple tooltip system with border-detection converts custom namespaced ta:hint-attributes of any element within the interface receiving pointer-events to tooltips.

Interface texts may be translated to different languages according to translation-arrays. These hold the type of node or attribute (e.g. text, tspan or ta:hint), node-ID and language variants per entry. Key-value pairs from the URL's query string (if present) are extracted as well, enabling calls to the interface with additional parameters. You may specify the desired language or a custom map-extent defined by x,y,width and height or cx,cy instead of x,y if you want to set focus on a certain element.

User hints can be set and displayed using an "info-line" located in the semi-transparent area at the top of the interface. A simple tabbed-style helpsystem with up to five tabs may be filled with arbitrary extern SVGs using image-tags and last but not least a "loading ..." animation may be switched on and off, whenever data has to be loaded to indicate that "something's going on" and the user should wait for it to be completed. All these features are implemented by UI.js, the central user interface javascript library that exposes interface relevant basic attributes and methods in a global UI-object that can be accessed by other parts of the interface at any time.

B. Adding the map

When the first map appears on screen, a lot of actions have been taken already. A background JPEG-image according to the current map-extent is produced on-the-fly with UMN-mapserver that combines a shaded relief, generated out of a 50m resolution DEM with transparent forest- and glacier-layers in ESRI's shape-format derived from Corine Landcover Level 3 data. Creation is triggered by getURL calling a perl-script that uses mapscript to "talk to UMN" and at the same time queries attributes like feature-names, styles and geometry from a PostGIS enhanced PostgreSQL database. Geometry is delivered using the AsSVG() function of PostGIS. AsSVG(), originally written by the author, is now part of the standard distribution and allows to output absolute and relative SVG-path notation for lines and polygons and cx,cy or x,y notation for point features. To further reduce output-size coordinate-precision may be specified as well.

At this point it is necessary to take a short look at the underlying database-schema. Geometry is kept in three tables according to feature-type point, line or polygon with unique-ID, feature-ID to identify objects, level of detail (LOD) and a class attribute to specify how a feature should appear in the output. Styles are represented in a more complex system consisting of ten tables and 5 views that allow to control and specify stacking order of layers, CSS-styles, symbols, patterns and marker-symbols independently for different LODs. Levels of detail follow a "quadtree-like" structure - choose full-view in the interface and use the zoom+ functionality to follow the five levels. At the time of writing only levels 1, 3 and 5 are filled with data, so don't be surprised to see "almost empty" maps at levels 2 and 4. Original geometry is edited with ERSI's ArcGIS9 and imported to the PostgreSQL database using a Python-geoprocessing script that takes care of distributing geometries and attributes to the appropriate tables.

To sum up, as result of the query onload, a new background-image is produced through UMN-mapserver. SVG-code for geometry along with styles is built within the perl-script, sent as UTF-8 stream to getURL's callback function, converted to XML using parsXML and appended to a group within the mainmap. Existing content in this group is erased beforehand and the background is directly set to the name of the freshly generated image. A cron-job takes care of removing these temporary images if they hit a certain age. As most of the features in the map have the former mentioned ta:hint attribute filled with their name, tooltips are created when you mouse-over these objects. A simple click pins down the tooltip and helps to create custom annotations that are automagically resized on zoom. The background image can also be changed to a NASA satellite image with ~30m cellsize by clicking on the particular preview icon.

C. Adding functionality

To provide further functionality, it is intended to add tools to the map. One of these tools has already been realized and enables the user to draw and explore interactive elevation-profiles. To activate it, the user has to click on the yellow profile-icon in the top-right corner. This starts an eventListener that records any click in the mainmap and builds a profile-line with up to 10 points or 70 kilometers length. Length is limited for performance reasons - nevertheless the first segment can be longer since there's no truncating of line segments. Double clicking finishes the line and calls a perl-script via getURL that executes GRASS-GIS' r.profile command with the given line. GRASS-GIS returns an ASCII representation of the elevation profile containing point-coords, distances and elevations. This output is converted to SVG-elements and animations that are sent back to getURL's callback function, appended to a group within the mainmap and started onload. One animation follows the profile-contour line, a second one runs along the profile-baseline and a third visualizes the profile-line within the mainmap. As soon as the user moves the mouse over the semi-transparent profile area, running animations are stopped and a javascript function displays height-values as tooltips and a position-marker on the profile-line. Mouseout restores the initial status and starts with the original animations again. Clicking anywhere in the mainmap will start a new profile-line, clicking the profile-icon will deactivate the tool.


Conclusion

The presented application is not complete yet. Additional geometry layers have to be added and generalized, styles, symbols, patterns and markers have to be designed and improved, new functionalities have to be implemented and a lot of translation work has to be done. Nevertheless it's a fine example of SVG in a real-world environment trying to integrate outstanding open-source programs like PostgreSQL, PostGIS, UMN-mapserver or GRASS and thus form an advanced dynamic mapping-system. SVG1.2 will add to that and further push the limits.


Links