Version 10 of Geographic mapping the Tcl way

Updated 2002-01-31 10:04:32

Purpose: propose and discuss a megawidget for easy map display


BREAKING NEWS: Get TkWorld (a zoomable, scrollable world map on a canvas, based on data from http://dss.ucar.edu/datasets/ds780.0/ ) as TclKit (39kb) from http://www.digital-smarties.com/pub/tkworld.bin , or mailto:[email protected] for the 111KB source (single file with all data)

Vince How does one zoom? There are no controls and all the keypresses and clicks I've tried (WinTk 8.4a4) don't do anything.


Richard Suchenwirth -- Recently the wish for geographic data was seen again on comp.lang.tcl, and I have also had that for quite some time. Wouldn������������������������������´t it be nice to be able to say

   set M [gmap .m -title France -height 500 -width 500]
   $M add France Paris Lyon Marseille Bordeaux Toulouse
   $M postscript -file france.ps

.. and you can imagine what these few commands would do. Basically, it would be a value-added canvas for display, and a well-stocked database of geodata that, asked for "France", would give the coordinates of France������������������������������´s boundary line, which would be transformed to canvas coordinates and rendered as a polygon.

The Tcl way is to do things simply, evidently, and effectively. How could geodata be implemented in Tcl? We might have three kinds of objects: points, lines, and areas.

Points would be characterized by latitude, longitude, elevation (meters over standard sea level, optional and defaulting to 0). Internally floating points, there would be converters

   gmap scan "51 09 N/07 56 E" ==> {51.15 -7.933 0}
   gmap format {51.15 -7.93 100} ==> "51������������������������������°09'N 07������������������������������°56'E"

assuming North and West to be positive. Points would further have a name (e.g. "Paris") and other freely choosable attributes as array elements, for instance

   gmap set Paris ==>
   loc {48.4 -2.4 0} name Paris type city capital 1 pop 2.2m

where the "capital" attribute might lead to underlining the city name in the map, and the "pop" attribute might control the size of the oval drawn at "loc".

Lines would have a list of points, by location or by name, so

   $M add [gmap set L1 {loc {Paris London} carrier "Air France"}]

would draw a straight line between these cities, possibly labeled with the carrier.

Areas would have a list of lines, explicit or by name. As boundaries are shared by two areas, it would be clever to define them only once, and let the neighboring areas both refer to that, using a naming convention that facilitates [array names] searches, e.g. "+DE+FR" would be the borderline between Germany and France. Rendering an area would consist in concatenating the lines into one and, after transforming the coordinates, draw a polygon.

Labels for points, lines, and areas would be displayed next to their objects. Before we have a clever layout mechanism, they'd be movable so you can manually arrange them on the canvas for best looks. To make these operations persistent, a "$M dump" operation would include such edited positions in the resulting huge list, which could be saved to file and redisplayed with a "$M set" operation. One Tk extension such gmaps could really use would be rotated canvas text.

Lots of work - now it's only for the doing ;-) I will start it right away sometime in my spare time, and put the pieces here on the Wiki, but can't guarantee a completion date. Maybe others would like to join and contribute code or geodata, here on the Wiki?


Took me over a year, but now see my first shot at Mapping Colorado.


For starters, here's initial scan-format routines to be called from gmap:

 proc gmap:scan s {
        set ele 0
        regexp {([0-9][0-9]) *([0-5][0-9]) *([NS]) */ *([01]?[0-9][0-9]) *([0-5][0-9]) *([EW])} $s -> latd latm latl lond lonm lonl
        scan $latd %d latd
        scan $latm %d latm
        scan $lond %d lond
        scan $lonm %d lonm
        set lat [expr $latd+$latm/60.]
        if {$latl=="S"} {set lat -$lat}
        set lon [expr $lond+$lonm/60.]
        if {$lonl=="E"} {set lon -$lon}
        list $lat $lon $ele
 }
 proc gmap:format g {
        set latf [lindex $g 0]
        set lonf [lindex $g 1]
        set latl N; set lonl W
        if {$latf<0} {set latl S; set latf [expr -$latf]}
        if {$lonf<0} {set lonl E; set lonf [expr -$lonf]}
        set latd [expr int($latf)]
        set latm [expr int(round(($latf-$latd)*60))]
        set lond [expr int($lonf)]
        set lonm [expr int(round(($lonf-$lond)*60))]
        format "%02d %02d %s/%02d %02d %s" \
                $latd $latm $latl $lond $lonm $lonl
 }

I think it should be also possible to display point and spatial information into such a widget. And dealing with different coordinate systems is also quite a mess but must be reflected IMO. BTW I found on FreeGIS a link to a library reading ARC-View Files to which a TCL-binding could be nice. JH

See GRASS [L1 ] too. Free GIS, UI with Tcl/Tk.

More links:

  • Rmap [L2 ]
  • FreeGIS [L3 ]: Collection of links to many more packages.
  • Belgian Geographical Interface [L4 ]: ActiveX interface?
  • tkGeoMap [L5 ] specialty canvas widget & supporting libraries
  • Tnm/Scotty/TkInEd also has node-plotting with a GIS orientation
  • a magazine article on GIS with a Tcl flavor appeared in November 2001 [L6 ], then a more elaborate version of the same program design showed up again in December 2001 [L7 ]
  • klimb [L8 ] is a specialized mapping program that displays USGS topo maps of the SF Bay Area. It lets you interactively map out bike routes while displaying the routes total distance and amount of climbing.