OSM Map On Garmin/Topographic maps

From OpenStreetMap Wiki
Jump to: navigation, search

OSM Map On Garmin

This article describes how to make topographic maps for Garmin devices from SRTM3 data and OpenStreetMap data in the form of .img tiles by User:Computerteddy. The result of the whole exercise is a gmapsupp.img file that you can transfer to Garmin GPS units that support USB mass storage mode or those having an external SD card (and maybe others). The main advantage of using Computerteddy's tiles is that an update of the map requires no computation and is thus very fast and fail-safe. The price you pay is that you cannot customize the rendering of the OpenStreetMap data.

For an alternative method to create contour maps, see OSM Map on Garmin/Contours using phygtmap

Before you start

Look on the OSM_Map_On_Garmin/Download page to see if what you want to make does not already exist. You will save time and effort if you just download a map made by someone else. If the region that you need a map for is not covered by those resources or you're not happy with what you can get there, the procedure described below will help you make your own map. For small areas you can also use OSM_Composer.

Several sections in the text are marked as 'Advanced topics' you should probably skip the first time you read this.

Prerequisites

Download and install Mkgmap and Srtm2osm, gzip and bzip2. Mkgmap needs Java 1.6, Srtm2osm needs .NET or Mono. In principle, you can download the map tiles manually from your browser, but this is quite tedious for large areas. The procedure described below uses curl and bash for an automatted download. On Unix-like systems both are usually pre-installed; on Windows you can install bash, curl, gzip, gunzip and bzip2 with Cygwin.

Getting the OpenStreetMap data

  • Go to http://touren.mospace.de/kachel.html, select an area using one of the techniques described there, tick the "Elevation contours" checkbox, and hit submit. You will get a list of URLs such as this
http://osm.ammit.de/osm/latest/img/63273978.img.gz
http://osm.ammit.de/osm/latest/img/63273979.img.gz
http://osm.ammit.de/osm/latest/img/63274158.img.gz
http://osm.ammit.de/osm/latest/img/63274159.img.gz
http://osm.ammit.de/osm/latest/img/63274338.img.gz
http://osm.ammit.de/osm/latest/img/63274339.img.gz
http://osm.ammit.de/osm/latest/img/63274518.img.gz
http://osm.ammit.de/osm/latest/img/63274519.img.gz

These URLs are the addresses of compressed Garmin .img tiles that contain the OpenStreetMap data of your area of interest.

  • Download and decompress all tiles. The recommended procedure is as follows:
    • Create a directory OSMdata.
    • Save the list of tile URLs to a text file OSMdata/tiles.txt.
    • Download the provided download.sh script to OSMdata.
    • Open a bash shell and cd to OSMdata.
    • Run the download script by typing ./download.sh. This will download and decompress the image tiles.
  • You now have several 6xxxxxxx.img files in the OSMdata directory.

Note: you can also get OpenStreetMap data in some other ways, such as using the OSM API or ready to use excerpts from Geofabrik or Cloudmade and build your own .img tiles using mkgmap.

Getting the topographic data

You will use srtm2osm to download the topographic data and create contour lines in .osm format. The basic commands needed are also generated by the "Garmin tiles" bookmarklet. It is recommended that you define an alias for srtm2osm that includes the options you want to use. In bash:

alias srtm2osm='/path/to/srtm2osm/Srtm2Osm.exe -step 25 -cat 400 100 -large'

Now, run srtm2osm by copy-pasting the corresponding section of the output of http://touren.mospace.de/kachel.html to the shell (in the OSMdata directory), in our example

srtm2osm  -bounds1 47 8 48 9 -o 53273978.osm
srtm2osm  -bounds1 48 8 49 9 -o 53273979.osm
srtm2osm  -bounds1 47 9 48 10 -o 53274158.osm
srtm2osm  -bounds1 48 9 49 10 -o 53274159.osm
srtm2osm  -bounds1 47 10 48 11 -o 53274338.osm
srtm2osm  -bounds1 48 10 49 11 -o 53274339.osm
srtm2osm  -bounds1 47 11 48 12 -o 53274518.osm
srtm2osm  -bounds1 48 11 49 12 -o 53274519.osm

This will take some time.

The generated .osm contour files can become quite large. If you have limited disk space, you can compress the new data after every (second, third, ...) call to srtm2osm by typing:

gzip *.osm

Mkgmap can deal with both compressed and uncompressed .osm files.

You now have several 6*.img and several 5*.osm or 5*.osm.gz files in the OSMdata directory.


Advanced topic

If you define an srtm2osm shell function instead of an alias you can avoid recreating topo tiles that you have already made and automatically split large tiles. Let us assume that you moved the previously made .img topo tiles to OSMdata/topoimg to avoid deleting them accidentally. In bash, an srtm2osm shell function definition could then look as follows

srtm2osm() {
    tileno=$7;
    tileno=${tileno:1:7}
    img5=topoimg/5${tileno}.img 
    img4=topoimg/4${tileno}.img
    if [[ -f $img4 || -f $img5 ]]
    then
        echo Topo tile exists 5$tileno >&2
    else
        echo $7 >&2
        srtm2osm/Srtm2Osm.exe -step 25 -cat 400 100 -large \
                                $1 $2 $3 $4 $5 $6 $7 | grep -v vertices
        gzip $7
	filesize=$(stat -tc '%s' $7.gz)
	if [[ $filesize -gt 20000000 ]]
	then
		java -jar osmosis.jar \
			--read-xml enableDateParsing=no file=$7.gz \
			--tee 2 \
			--bounding-box right=$3.5 --wx 3${tileno}.osm.gz \
			--bounding-box left=$3.5 --wx 4${tileno}.osm.gz
	        mv $7.gz toobig/
	fi
    fi
}


Converting the topographic data to Garmin .img format

Use mkgmap to convert the contour lines generated by srtm2osm from .osm to the Garmin .img format.

Define an alias

alias mkgmap='java -Xmx512m -enableassertions -jar /path/to/mkgmap.jar --draw-priority=10000 --transparent'

and run mkgmap by typing

for f in 5*.osm 5*.osm.gz; do echo $f; mkgmap $f; done

Alternatively, you can just do

java -Xmx512m -jar "C:/path/to/mkgmap.jar" --draw-priority=10000 --transparent 5*.osm 5*.osm.gz

with the disadvantage that progress is not indicated.

Mkgmap creates a Garmin .img file for each .osm or .osm.gz input file. If you encountered no problems you can delete the .osm and .osm.gz files.

You now have several 6*.img and several 5*.img files in the OSMdata directory.

Advanced topic

Use a style, as described in Mkgmap/help/Custom_styles, to change the resolution at which the contour lines show up. For example, if you use the default style shipped with mkgmap, you can see the relevant definitions in the lines file:

contour=elevation & contour_ext=elevation_minor
	{ name '${ele|conv:m=>ft}'; }
	[0x20 resolution 23]
contour=elevation & contour_ext=elevation_medium
	{ name '${ele|conv:m=>ft}'; }
	[0x21 resolution 21]
contour=elevation & contour_ext=elevation_major
	{ name '${ele|conv:m=>ft}'; }
	[0x22 resolution 20]
contour=elevation | contour_ext=elevation
	{ name '${ele|conv:m=>ft}'; }
	[0x21 resolution 20]

According to these settings, minor contour lines will first show up in the '300 m' zoom level when the map detail is set to 'Most', medium contour lines at '1 km' and mayor contour lines at '2 km'. It may vary from one device model to another.


Problems and workarounds

Thrashing on Linux

My new Linux (Ubuntu Hardy) will start thrashing when mkgmap needs virtual memory. The CPU load goes down, the system becomes unresponsive, kswapd0 pops up repeatedly in top output, and mkgmap never finishes. So far, I have not found a satisfactory solution. The strategy I am using right now is

  • eliminate unnecessary memory usage: run Linux without X (e. g. via the debug boot option)
  • decrease the maximum heap size (java -Xmx argument) such that virtual memory is not used
  • split those input files that cannot be processed with this heap size into smaller chunks (see below)

Map is too big and will not work

If the region covered by a tile is very mountainous the topo .img file may become larger than the maximum .img file size and mkgmap will emit a "map is too big and will not work" warning. Possible workarounds (mostly untested)

  • The best option is to split the input *.osm(gz) file using Splitter, which is a tool specifically designed to output files ready to use by mkgmap.
java -Xmx2048m -jar splitter.jar --mapid=63240101 --mixed=yes --cache=/some/path/ --max-nodes=5000000 srtm_file.osm.gz

Required memory will vary depending on the size of the input file. The above -Xmx2048m is able to handle several GB input files. Output files names may be specified using the --mapid switch, as well as the output file size using --max-nodes.

java -jar osmosis.jar \
    --read-xml enableDateParsing=no file=53274338.osm.gz \
    --tee 2 \
    --bounding-box right=10.5 --wx 33274338.osm.gz \
    --bounding-box left=10.5 --wx 43274338.osm.gz

Give the output .osm files names with unique 8-digit numbers to avoid name clashes with any of the other .osm, .osm.gz, or .img files.

  • Split the .osm file with osmcut.c (osmcut does not compile on windows).
  • Increase the -step size in the call to srtm2osm.
  • Reduce the tile size on http://touren.mospace.de/kachel.html and repeat the "Getting the topographic data" step (the numbers of the topo tiles will no longer correspond to the numbers of the OSM tiles).

Combining the data

In the directory OSMdata, you should now have the OpenStreetMap data as 6*.img files and the topographic data as 5*.img files. From these you create a joint map file gmapsupp.img with

mkgmap --gmapsupp 6*.img 5*.img

You can also use the Windows application GMapTool to assemble the gmapsupp.img file. GMapTool seems to make more robust gmapsupp.img files than mkgmap. On Linux, GMapTool can be run with wine.

It's a good idea to put an internal description into the resulting file: this description is displayed when Enabling/Disabling maps in your Garmin device. If you don't do this, you will have no easy way to distinguish the maps in the 'Select Map' dialog on your Garmin. This is especially significant if you have several .img files on your Garmin, or are sharing the .img files with your friends. For example:

mkgmap --gmapsupp --description=Qld_Australia 6*.img 5*.img
Advanced topic

In order to be able to activate/deactivate selectively the contour tiles and the OpenStreetMap tiles it is necessary to give them different family ids. You can do it both with mkgmap and GMapTool.

  • For mkgmap you can use:
mkgmap --gmapsupp --family-id=60 --product-id=1 6*.img --family-id=50 --product-id=1 5*.img
  • Here is how you would do this with the command line version of GMapTool:
gmt.exe -f 700,1 -jo ElevationContours.img -m SRTM3 5*.img
gmt.exe -f 248,1 -jo Streets.img -m OSM 6*.img
gmt.exe -jo gmapsupp.img ElevationContours.img Streets.img 

On the GPSMap 60CSx you can then switch the maps on or off as follows:

  • On the map page, press MENU
  • select 'Setup Map'
  • highlight the (i) sign
  • highlight 'OSM street map, Srtm3'
  • press MENU
  • highlight e. g. 'Hide Srtm3' and press ENTR

The procedure should be similar for other devices.


Copying the map to the GPS unit

Copy the gmapsupp.img file to the /Garmin directory of your GPS unit as described in OSM Map On Garmin. If the map works you can delete the gmapsupp.img file and the 6*.img files from the computer disk. You should keep the 5*.img files with the topographic data in Garmin format if you plan to update the map later.

Updating the map

  • Download new OpenStreetMap data as described in Getting the OpenStreetMap data. If you have used the download procedure described there and you have kept the tiles.txt file, you just need to re-run the download.sh bash script.

See also