How to make a topographic map for Garmin GPS devices from OpenStreetmap and SRTM data

You can get a lot more info on this topic from the OpenStreetMap wiki.

Here is how I make my topo map

OSM map

I do all this on a Fedora Linux box and I mostly use command line tools because I can script them. All tools I use run on Windows, too, and most of them have a GUI. If you prefer some mouse clicking you should be fine.

First get some OSM data. I use the Geofabrik download page, but any other way should be fine. Since none of the ready made country downloads match my needs I download the Europe excerpt. Then I cut out a rectangular piece with Osmosis:

osmosis --read-xml enableDateParsing=no file=europe.osm.bz2 --bounding-box left=5.8 right=15.1 bottom=47.2 top=55.2 completeWays=no --write-xml file=germany.osm

If you want a map for a big area like the whole of Germany you will have to split it into map tiles. Otherwise the GPS cannot handle it. I use the mkgmap splitter for this:

java -Xmx2048M -jar splitter.jar --mapid=30000001 --max-nodes=800000 germany.osm

If your computer runs out of memory you can use the "--max-areas=X" option. Then the splitter will only process X areas at a time. You can use a different "--mapid" number.

Now you can edit the template.args file that was created to get some better descriptions for the map tiles.

The next step is to convert the OSM data into the Garmin format and bundle it with the TYP file . If you want your map to look like mine you need my mkgmap style. If you modify it you may have to modify the TYP file accordingly. This can be done with the online editor or using a tool like cgpsmapper. For owners of Garmin Edge devices, which have problems when displaying some of the track lines, I suggest to try this TYP file.

java -Xmx2048M -jar mkgmap.jar \
--description=OSM_DE \
--country-name=Germany --country-abbr=DE \
--name-tag-list="name:de,name,int_name" \
--style-file=./mkgmap-style-toponew/ \
--family-id=1331 --product-id=1 \
--series-name=OSM_Germany --family-name=OSM_Germany \
--area-name=Germany \
--overview-name=OSM_Germany \
--net --gmapsupp --tdbfile --route \
--road-name-pois=0x640a \
--draw-priority=25 \
--latin1 \
--make-opposite-cycleways --remove-short-arcs \
-c template.args 1331.typ

The "--family-id" number must match the one in the TYP file. After this step you will have a gmapsupp.img file. If you don't need contour lines you are done. Copy the gmapsupp.img to your GPS' SD card and enjoy ;-).

If you want to add contour lines I suggest to rename the gmapsupp.img:

mv gmapsupp.img osm.img

Contour lines

First get the contour line data from the NASA server and convert it into OSM format with Srtm2OSM:

mono Srtm2Osm.exe -bounds1 47.2 5.8 55.2 15.1 -step 10 -cat 100 20 -large -corrxy 0.0005 0.0005 -o srtm.osm

Split into tiles:

java -Xmx2048M -jar splitter.jar --mapid=21000001 --mixed=yes --cache=./cache/ --max-nodes=5000000 --max-areas=27 srtm.osm

I make two mapsets for the contour lines: One with one line every 20 m and one with a line every 10 m. This way the 10 m lines can be switched off independently in the GPS.

I use two copies of the template file:

cp template.args template_srtm10.args
mv template.args template_srtm20.args

And edit them so that both templates use the same OSM sources but output different map names:

mapname: 21000001
description: SRTM10
input-file: 21000001.osm.gz

mapname: 22000001
description: SRTM20
input-file: 21000001.osm.gz

Then I run mkgmap for both sets and rename the output:

java -Xmx2048M -jar mkgmap.jar \
--style-file=mkgmap-style-srtm10new/ \
--net --gmapsupp --tdbfile \
--family-id=2512 --product-id=1 \
--draw-priority=28 --transparent \
--series-name=SRTM10 --family-name=SRTM10 --area-name=Germany \
-c template_srtm10.args

mv gmapsupp.img srtm10.img

java -Xmx2048M -jar mkgmap.jar \
--style-file=mkgmap-style-srtm20new/ \
--net --gmapsupp --tdbfile \
--family-id=2513 --product-id=1 \
--draw-priority=28 --transparent \
--series-name=SRTM20 --family-name=SRTM20 --area-name=Germany \
-c template_srtm20.args

mv gmapsupp.img srtm20.img

At last I use gmaptool to join the three IMG files (SRTM10, SRTM20 and OSM):

gmt -j -o gmapsupp.img osm.img srtm10.img srtm20.img

If you want to update the map there is no need to rebuild the SRTM IMG files - contours normally don't change. You can reuse the srtm10.img and srtm20.img. If you want a map for Germany you don't have to build SRTM IMGs at all: you can extract the SRTM tiles from my topo map with gmaptool and bundle it with your OSM layer.