Mkgmap/help/How to create a map

From OpenStreetMap Wiki
< Mkgmap‎ | help
Jump to navigation Jump to search

Introduction

If you want to load OSM data onto a Garmin GPS device, you can either download pre-compiled maps, or you can compile them yourself. This page describes the latter option. The maps produced support routing (for cars) and searching for addresses.

Pre-Requisites

You need to download the following software / tools:

Install Java Runtime Environment 1.8. Both mkgmap and splitter depend upon it.

information sign

Java is commonly available, and it may already be installed on your machine.

Walkthrough

Download OSM data (.osm, .osm.pbf or .osm.gz) for a certain region. Mirrors offering extracts are listed here. Geofabrik is a good starting point.

Use splitter to split the raw map data into smaller pieces, called tiles. This is necessary because most of the downloaded region extracts are too big to be processed by mkgmap. For example:

$ java -jar splitter.jar us-northeast-latest.osm.pbf

information sign

Command detailed explanation: java -jar splitter.jar runs the java code from the splitter.jar file (please make sure this file is in the current folder or can be found by your system), and us-northeast-latest.osm.pbf is the file containing the osm data that you want to split in smaller regions' files in order to process them afterwards with the mkgmap program (other acceptable file formats: .osm, .o5m)

The resultant tiles are named 6324xxxx.osm.pbf, where xxxx is 0001, 0002, 0003...

These tiles can be compiled into a map as-is, but the resultant map would lack addressing data (e.g. city or zip code). Addressing data comes from preprocessed bounds tiles, and you can either download them from mkgmap.org or create them yourself as described in Mkgmap/help/options#Using_preprocessed_bounds_for_the_address_index. Place the resultant files into a subdirectory named bounds.

Finally, you can use mkgmap to compile the tiles and bounding information into something comprehensible by a Garmin GPS.

$ java -jar mkgmap.jar \
    --route \
    --add-pois-to-areas \
    --bounds=bounds \
    --index \
    --gmapsupp \
    6324*.osm.pbf

information sign

Command detailed explanation: this time we run the java code from the mkgmap.jar file, passing the following options --route, --add-pois-to-area,--bounds=bounds, --index, and --gmapsupp on each files in format .osm.pbf in the current directory whose names starts with 6324.... \ is used to split the command over several lines as it should be fed to the shell on a single line otherwise.

This creates several files, including the coveted gmapsupp.img file. Copy this file onto the SD card used by the GPS. The details are listed here, but here's a quick refresher:

  • The SD card should be formatted as FAT32.
  • There should be a folder called "Garmin" at the root of the SD card.
  • The gmapsupp.img goes into the "Garmin" folder.

information sign

If you get an "OutOfMemoryError: java heap space" error, you'll need to increase the available memory by using the -Xmx parameter. (eg. java -Xmx2000M -jar mkgmap.jar ...)

Tweak your map

You can use several options and the style files of mkgmap to tweak your map to your requirements. Read the following for details:

Detailed custom map creation and integration in BaseCamp

This is a more detailed tutorial for the creation of the French road network accessible to cars (in order to update a nüvi 250 gps device) and the creation of an installator to enable using the map on Garmin Basecamp program in windows.

Pre-requisites

We tested the following on Ubuntu 14.04 and the installer on windows 10

Software / tools

information sign

Command detailed explanation: sudo ask for superuser rights (admin) and runs apt to install osmctools or nsis package from repository.

We work from a folder named "map" from which we can run "splitter.jar" and "mkgmap.jar". This can be made by downloading the "mkgmap-r3676.zip" and "splitter-r437.zip" files from http://www.mkgmap.org.uk/download/ in our current folder "map", extract the archives content there, then create a symbolic link to the .jar files in our current folder ~.../map$ ln -s ./mkgmap-r3676/mkgmap.jar mkgmap.jar.

OpenStreetMap data

We download up-to-date osm data from the geofabrik server (France data) : france-latest.osm.pbf. The .pbf format used here is a binary format much more compressed than the original xml human readable .osm format. For our project we would like to use a somehow in between choice using .o5m that is faster to write than .pbf using osmconvert tool: osmconvert france-latest.osm.pbf france-latest.o5m.

Preprocessed OpenStreetMap data

We will ask Mkgmaps to encode post adresses of places in order to find them on our gps. Also we will ask it to define blue patches for seas. Those elements are not defined directly as openstreetmap objects, but by indicating their boundaries. In order to define which elements are inside the bondaries or not, those former have to be processed first. This process generates files useful to generate adresses and sea area. Up-to-date Sea and administrative preprocessed boundaries can be downloaded from the mkgmap web site (files Sea.zip and bounds.zip).

Reference places data:

The list of cities populated with more than 1500 persons is kept by the geonames project. Download cities15000.zip in order to automatically label splitted map tiles from splitter

Walkthrough

First we will use splitter to split our large france-latest.o5m file in smaller processable files in the same format:

~.../map$java -jar splitter.jar france-latest.o5m --output=o5m --output-dir=francesplittertempfile --max-areas=4096 --max-nodes=3000000 --wanted-admin-level=8 --geonames-file=cities15000.txt > francesplitter.log

information sign

Command detailed explanation: java -jar splitter.jar runs the java code from the splitter.jar file on france-latest.o5m. Options: --output=o5m ask for .o5m output files, --output-dir=francesplittertempfile put the output files in ./francesplittertempfile folder, --precomp-sea=sea.zip gives splitter the sea border file, --geonames-file=cities15000.zip ask him to use the name of the largest city in cities15000.zip also found in the newly generated subarea file to autogenerate its description field in template.args (latter used by mkgmap) that will identify the tile in the gps device/basecamp, --max-areas=4096 and --max-nodes=3000000 respectively gives the maximum size and number of nodes allowed in the output files. --wanted-admin-level=8 ask splitter to maintain object relation complete up to the level of a city. > francesplitterlog redirect the shell output to the text file splitterlog

Please note that I adapted the maximum size and number of nodes allowed in the output files in order to limit the number of tiles in the final Garmin .img map, on the other hand it augment the risk of running out of memory in the next steps... I asked to keep element linked together up to the level of the cities because it seemed that obtained better address search results this way.

This step produces a new folder ./francesplittertempfile and a log file francesplitterlog in our current directory. The new folder contains among others a mkgmap option file template.arg with name and description field of all the 6324xxxx.o5m files of the subregions generated by the operation.

Second, we will generate our custom mkgmap style rule files that contains all the rules about how to process the osm objects/include them in the .img files. We will start modifying the default style file that can be found in ~/map$./mkgmap-r3676/examples/styles/ and make a copy the default folder in our map folder to edit the rules with name road_only.

We let the options file as it is. New style description can be updated in the info file. In relations, lines, and points we comment all the line corresponding to elements that we do not want to show in the map (OSM object that are not covered by a rule are disregarded by default). Hence in the points file, we comment all the lines but those that correspond to car necessities, routing and addressing:

  • place=...
  • amenity=fuel ...
  • amenity=parking ...
  • highway=...
  • <finalize> name=* { name '${name}' } include 'inc/address';

an include line is used for readability and refer to another file that is incorporated as it is. Thoses files such as road_only/inc/address must be checked also...

Third, we will use mkgmap program to generate the garmin .img maps note that options order matters a lot:

~.../map$java -jar mkgmap.jar --max-jobs --gmapsupp --tdbfile --nsis --output-dir=OSMFRANCE_light --mapname=OSM_FRANCE_light --country-name="FRANCE" --family-id=6324 --family-name="OSM_light france 2016" --series-name="OSM france map" --area-name="France" --country-abbr="FRA" --style-file=./road_only --precomp-sea=sea.zip --generate-sea --route --drive-on=detect,right --process-destination --process-exits --index --bounds=bounds.zip --location-autofill=is_in,nearest --x-split-name-index --housenumbers --remove-ovm-work-files --verbose -c ./francesplittertempfile/template.args

information sign

Command options detailed explanation: --max-jobs allows to process several files at once if you have many processor (time gain) --gmapsupp generate a file gmapsupp.img ready to copy on gps sdcard folder /garmin, --tdbfile an adress index code for the basecamp installer, --nsis the nsis script to generate the windows installer, --output-dir=OSMFRANCE_light name of the sub directory to output generated files, --mapname=OSM_FRANCE_light --country-name="FRANCE" --family-id=6324 mind that basecamp will display only one of two maps build with the same familly ID, --family-name="OSM_light france 2016" the name that Basecamp will use to designate the map --series-name="OSM france map" --area-name="France" --country-abbr="FRA" the abbreviation seems to be a used entry for address index generation from the preprocessed bounds file, --style-file=./road_only the directory where we set the rules to process and include OSM data in the map, --precomp-sea=sea.zip --generate-sea to generate blue area for sea using the downloaded preprocessed file, --route--drive-on=detect,right --process-destination --process-exits enable routing with detection of the used road side and motorway exit directions indication, --index --bounds=bounds.zip --location-autofill=is_in,nearest --x-split-name-index --housenumbers enable address lookup generating an index with street numbers and trying to guess unlabeled building addresses, --remove-ovm-work-files remove temporary work files after running, -c ./francesplittertempfile/template.args give the emplacement of the splitter generated options file

Fourth we will build the windows installer for Basecamp map usage running the script osmmap.nsi automatically generated by mkgmap to makensis:

~.../map$ makensis ./OSMFRANCE_light/osmmap.nsi

Note that the .img files are compressed in the installer. By default, mkgmap generates a building script asking for a lzma compression that has excellent compression ration and extraction time properties but can takes a very long time to complete. You might be interested to build a bigger file in less time using the simpler zlib compression algorithm by changing the corresponding option value line in the .nsi script file befor you build the installer (using sed -i 's_SetCompressor /SOLID lzma_SetCompressor /SOLID zlib_g' ./OSMFRANCE_light/osmmap.nsi)

information sign

Command detailed explanation: sed -i run sed for an infile modification of ./OSMFRANCE_light/osmmap.nsi, as 's_chaine1_chaine2_g' substitute all occurrences of chaine1 by chaine2

(Once the installer is build, all 6324xxxx.img files can be deleted using for i in "./$DIR/6324*.img"; do rm $i; done)