Creating a routable map for a Garmin GPS device using OpenStreetmap data.

Introduction

In this article I will describe the steps to convert OpenStreetMap data to a routable map for Garmin GPS devices. This will be a straight walkthrough, avoiding side tracking to extra possibilities. The end result will be a working, but very limited routable map on the GPS unit. Customization and Basecamp / Mapsource integration will be described in later articles.

Four steps

Map generation consists of four steps:

  1. Download OpenStreetMap data
  2. Clip the region of interest
  3. Create tiles
  4. Generate Garmin map

But before I start, some preparation is necessary.

Directories

I use the following directory structure for all files and programs:

osm2garmin/
├─ bin/
│  ├─ mkgmap/
│  ├─ osmconvert/
│  └─ splitter/
├─ data
│  ├─ openstreetmap/
│  ├─ poly/
│  ├─ tiles/
│  └─ tmp/
├─ garmin/
└─ styles/

Commands to create this tree in the home directory:

mkdir -p ~/osm2garmin/bin/mkgmap
mkdir -p ~/osm2garmin/bin/osmconvert
mkdir -p ~/osm2garmin/bin/splitter

mkdir -p ~/osm2garmin/data/openstreetmap
mkdir -p ~/osm2garmin/data/poly
mkdir -p ~/osm2garmin/data/tiles
mkdir -p ~/osm2garmin/data/tmp

mkdir -p ~/osm2garmin/garmin
mkdir -p ~/osm2garmin/styles

Software

First of all, install Java SE Runtime Environment 8, as required by the mkgmap and splitter programs.

Required software:

mkgmap: download and extract in the bin/mkgmap directory. This will put a subdirectory in the mkgmap directory, named after the mkgmap version, e.g. mkgmap-r4905.

splitter: download and extract in the bin/splitter directory. This will put a subdirectory in the splitter directory, named after the splitter version, e.g. splitter-r653.

osmconvert: download and extract in the bin/osmconvert directory. Note: this is an executable1, so set the privileges correctly: chmod u+x osmconvert64.

Download OpenStreetMap data

Download the required continent from https://download.geofabrik.de/, or choose another mirror. I will use the “osm.pbf” file. Other file types will be larger and slower to process. This file is still huge (over 26 Gb for Europe at the time of writing), so depending on your internet connection, this might take a while.

Put the downloaded file in the data/openstreetmap directory.

Clip the region of interest

This step will clip the part of the map you want to use from the downloaded continent file.

First, I need to create a polygon definition file to define the section I want from the map. For this I need the list of coordinates from the corners of the polygon. The easiest way to create a polygon file is by using uMap. As an example, I will create a small map of Swifterbant. I zoom into the area I need, then click the “Draw a polygon” icon at the top right. Now I draw a polygon around the area and click the last point again to finish the polygon.

Image

Now, at the left, I click the “Embed and share this map” icon. At the right, under “Download data”, I select “kml” and click “Download data”. A file untitled_map.kml is downloaded. I manually edit this file: I only need the text between <coordinates> and </coordinates>. I transform these coordinates to the format below, and save as data/poly/swifterbant.poly. Note that there is no comma between the coordinates, and some blank space before each pair of coordinates:

 File: data/poly/swifterbant.poly
swifterbant
1
  5.61264  52.568647
  5.626116 52.574472
  5.648346 52.577184
  5.664139 52.571238
  5.645256 52.55351
  5.631008 52.558418
  5.614357 52.558626
  5.61264  52.568647
END
END

Using this file, I can now clip the part of the map I need from the big Europe map:

bin/osmconvert/osmconvert64 -v -B=data/poly/swifterbant.poly -o=data/tmp/swifterbant.o5m data/openstreetmap/europe.osm.pbf

This will take some time, a big file needs to be processed. After processing, the resulting file (as specified by the -o switch) is: data/tmp/swifterbant.o5m.

Create tiles

Now I need to split the clipped section into portions that the Garmin software can handle. This is done with the following command.

java -jar bin/splitter/splitter-r653/splitter.jar \
     --output-dir=data/tiles \
     data/tmp/swifterbant.o5m

Output files are placed in the data/tiles/ folder. My example has a very small region, so only one tile is created, the 63240001.osm.pbf file. After running the splitter, I remove the swifterbant.o5m file from the previous step.

[tj@nixos:~/osm2garmin]$ ls -l data/tiles
total 556
-rw-r--r-- 1 tj users 294702 18 apr 13:56 63240001.osm.pbf
-rw-r--r-- 1 tj users    154 18 apr 13:56 areas.list
-rw-r--r-- 1 tj users    125 18 apr 13:56 areas.poly
-rw-r--r-- 1 tj users    105 18 apr 13:56 densities-out.txt
-rw-r--r-- 1 tj users    339 18 apr 13:56 template.args

[tj@nixos:~/osm2garmin]$ rm data/tmp/swifterbant.o5m
[tj@nixos:~/osm2garmin]$

Generate Garmin map

All preparations are now complete! The final step is to generate a file that can be uploaded to the Garmin device.

java -jar bin/mkgmap/mkgmap-r4905/mkgmap.jar --output-dir=output --gmapsupp --route -c data/tiles/template.args

This will generate a couple of files in the output/ directory:

[tj@nixos:~/osm2garmin]$ ls -l output
total 236
-rw-r--r-- 1 tj users 108032 18 apr 13:59 63240001.img
-rw-r--r-- 1 tj users 110080 18 apr 13:59 gmapsupp.img
-rw-r--r-- 1 tj users   5120 18 apr 13:59 osmmap.img
-rw-r--r-- 1 tj users    843 18 apr 13:59 osmmap.tdb
-rw-r--r-- 1 tj users   6144 18 apr 13:59 ovm_63240001.img

The file that can be copied to the Garmin device is gmapsupp.img.

Important: Copy the file to a memory card in your GPS, not to the internal memory of the GPS! I’ve seen documentation that copying the file to internal memory won’t work and could brick the device. Now I suspect that these are edge cases and normally not a problem, but I never took the chance.

So I plug in my Garmin, navigate to the garmin/ folder on the SD card and copy the gmapsupp.img file there. Remove the USB cable, restart the Garmin and presto:

Image

Next steps

Now this is a very basic setup, just to get started. The map generation is a very technical process with a lot of possibilities and also a lot of pitfalls. In later articles I will describe additional features, such as:

  • Loading the map into Basecamp and Mapsource
  • Include height information and hill shading
  • Getting the address search to work
  • Changing the way the map looks
  • Fine tune the data used by the route calculations
  • Hiding most of the complexity behind scripts

  1. I am running NixOS, which means I can usually not use Linux executables that were not compiled on NixOS. This is the case here, I had to compile osmconvert from source. I think on all other distro’s the downloaded executable is fine. ↩︎