Openstreetmap, mapnik and gps tracks
01 June 2009
Open street map is a cool
project with the aim to make geographic maps freely available
to anyone. It can be used online as a slippy map (similar to google maps)
or the entire map data can be downloaded in vector format to the local
hard drive and used offline and even be uploaded to many gps receivers.
The map data is entirely contributed by users - like wikipedia.
Download
To download the map data there are a couple of ways depending on the area of interest.- entire planet - download the file planet-latest.osm.bz2 (currently 5.9GB)
- selected regions - for example the UK is currently 150MB and Germany 471MB in size, compressed osm
- map within a bounding box defined by latitude/longitude coordinates
wget "http://api.openstreetmap.org/api/0.6/trackpoints?bbox=left,bottom,right,top -O tracks.gpx"
wget "http://api.openstreetmap.org/api/0.6/map?bbox=left,bottom,right,top -O map.osm" - interactively on openstreetmap using the Export tab.
Applications
There are a many open source applications which can read osm data files and use the map offline. Here only a few.- merkaartor: map viewer and editor, can upload changes to openstreetmap
- JOSM: openstreetmap editor written in JAVA
- mapnik: general purpose map renderer, i.e. it generates png images of vector data
Mapnik
The setup of mapnik to render openstreetmap data is a bit complicated as it requires the osm map file to be imported into a postgres database for performance reasons. The full procedure is described in the openstreetmap wiki. Once it has been fully installed and configured mapnik provides a python interface to draw images. A programming example is provided ingenerate_image.py
, in which only a bounding box in terms of
longitude/latitude coordinates and image resolution need to be adjusted.
Very detailed customisation of the final map image can be made by
editing the config file osm.xml
which contains all the
directives on how to render the map.
Mapnik and gps tracks
In order to overlay a gps track onto the map add the following rule to the fileosm.html
. I'm using mapnik version 0.5.1-6.19
which cannot import gpx files so I need to convert gpx to shape and
the programme gpx2shp
works for me. Newer versions of mapnik can apparently read gpx files
directly. Make sure the gpx file contains tracks and not waypoints
or routes for the following to work.
<!-- User defined gps style --> <Style name="gpxlines"> <Rule> <LineSymbolizer> <CssParameter name="stroke">#fff</CssParameter> <CssParameter name="stroke-width">5</CssParameter> <CssParameter name="stroke-linejoin">round</CssParameter> <CssParameter name="stroke-linecap">round</CssParameter> <CssParameter name="stroke-opacity">0.4</CssParameter> </LineSymbolizer> <LineSymbolizer> <CssParameter name="stroke">blue</CssParameter> <CssParameter name="stroke-width">2.5</CssParameter> <CssParameter name="stroke-dasharray">4,2</CssParameter> </LineSymbolizer> </Rule> </Style> <!-- User defined gps track --> <Layer name="gps" status="on" srs="+proj=latlong +datum=WGS84"> <StyleName>gpxlines</StyleName> <Datasource> <Parameter name="type">shape</Parameter> <Parameter name="file">/path/track_trk</Parameter> </Datasource> </Layer>Below two random examples. Background images like satellite maps can also be added to the map, if the coordinates of the lower left and upper right corner of the image are know. Also the image needs to be in the same projection as the main map. Openstreetmap as well as google map use Mercator projection. Since mapnik requires the coordinates to be in the projection coordinate system of the main map we need to convert longitude/latitude into Mercator x,y coordinates. The following pseudo C code achieves this.
R_Earth = 6378137.0; deg2rad = M_PI/180.0; x=R_Earth*deg2rad*lon; y=R_Earth*log((1.0+sin(deg2rad*lat))/cos(deg2rad*lat));With the right coordinates the background image can be added to
osm.xml
.
<!-- User defined background map style --> <Style name="rastersty"> <Rule> <RasterSymbolizer> <CssParameter name="scaling">bilinear</CssParameter> </RasterSymbolizer> </Rule> </Style> <!-- User defined background map --> <Layer name="bg_cumbria_village" status="on" srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over"> <StyleName>raster</StyleName> <Datasource> <Parameter name="type">raster</Parameter> <Parameter name="format">tiff</Parameter> <Parameter name="file">/path/cumbria_village.tif</Parameter> <Parameter name="lox">-364146.003</Parameter> <Parameter name="loy">7218407.203</Parameter> <Parameter name="hix">-357113.796</Parameter> <Parameter name="hiy">7222687.677</Parameter> </Datasource> </Layer>
Uploading osm data onto a garmin gps
There is a simple utility mkgmap which converts osm files into img files readable by garmin gps units. I then upload the file(s) onto my garmin vista c (bought end of 2005) using qlandkarte. Yes, this is an old project but it works. On newer models it can be uploaded using the USB mass storage mode, apparently. For more details see the openstreetmap wiki. The following generates a garmin map, e.g. a file 63240001.imgmkgmap file.osm --country-name="United_Kingdom" --country-abbr="GBR"In qlandkarte the upload works like this:
file → load map → select garmin img map file
F1 (map) → F5 (select map) → click on map
F9 (upload)