From OpenStreetMap Wiki
Jump to: navigation, search

How to get started with Mkgmap style rules on Windows 7

For the setup how it is done here the following programs are required:

  1. Windows 7 PC (this setup was originaly done on a Windows 7 virtual machine)
  2. latest Java version
  3. Mkgmap (command line tool was used here)
  4. Gmaptool
  5. JOSM
  6. wget for Windows (optional)
  7. Mapsource
  8. Cgpsmapper
  9. Notepad++ or similar text editor

Java setup

Download and install the latest version of Java from . Java is required to use JOSM and Mkgmap. For easier use of Mkgmap on the command line the Windows path variable has to be edited. From the desktop, right-click My Computer and click Properties. In the System Properties window, click on the Advanced tab. In the Advanced section, click the Environment Variables button. Finally, in the Environment Variables window, highlight the Path variable in the Systems Variable section and click the Edit button. Add or modify the path to your Java installation. Each different entry is separated with a semicolon.

Data download and style rules dictionary

To get started OSM data of your choice is necessary. OSM data can be downloaded via JOSM, which comes in handy later while editing style rules for mkgmap. JOSM can be found here: . Optional you can use wget for Windows to download larger portions of data from the OSM servers. The amount of data you can download using JOSM is fairly small, especially for heavy populated areas.
Example of wget for Windows:

wget -O <filename> "*[bbox=minlon,minlat,maxlon,maxlat]"

The values minlon, minlat, maxlon and maxlat are geographic degrees. They can be easily found through when selecting “export” from in the menu bar above the map. Move the map to the desired area, on the left side you will see the values you need to enter.


When this download is finished you can find the osm-file as you named it. In the next step you need to add the boundaries (the values you entered in bbox)to the just downloaded osm data. Open the file and add your values below this (or similar) line “<osm version="0.6" generator="Overpass API">” which can be found right at the beginning of the file:

<bounds minlat='minlat value' minlon='minlon value' maxlat='maxlat value' maxlon='maxlon value' />

Without this bounds definition the resulting map in mapsource will have greater boundaries then the ones you downloaded (because the file contains all values inside min&maxlon and min&maxlat which - very likely - contain information outside the box too). This can also cause errors on your map like flooded land areas or sea areas not getting rendered correctly.

Mkgmap comes with an example of a default style. Copy the folder of Mkgmaps default style to use for your costum styles or create folder and files as seen in the example default style of Mkgmap. The structure of your style folder has to look as follows:

  • Folder: "My_first_style"
    • File: "version"
    • File: "lines"
    • File: "points"
    • File: "polygons"

Note: The version file must exist as it is used by mkgmap to verify a valid style. This file only contains the version number of the latest style language. The current version is 1. Make sure you place a new line after the number.


Mkgmap can be downloaded from . Unzip Mkgmap in your preferred directory. If you have already modified your Windows path variable to use Java you can get started, otherwise you have to modify it now. For easy use of Mkgmap on the command line create a file with a name of your choice in your Mkgmap directory which will be used as configuration file later on.


Mapsource should be included with your Garmin software. Updates can be found here:[1] .
If you lost your Garmin Software Disc please follow this link:

Gmaptool and Cgpsmapper

Gmaptool will be used to install .img files created by Mkgmap on your PC to view them in Mapsource. To do so you need a compiler to create overview maps. We are using the free version of cgpsmapper. Cgpsmapper download:
Install the compiler and set the path in the options tab of Gmaptool.

Style rules

Now that we have all the necessary tools and osm data, we can have a look at style rules. Using Mkgmap style rules you can determine which data from your osm map will be transitioned into the Garmin IMG map we want to create. For beginners the easiest way to create your first custom style is to have a look at the default styles that come with Mkgmap or download an already complete set of style rules from the internet to start from there. At first style rules seem kind of complecated. Thats why we try to explain style rule basics and some of our custom rules in the following sections.

Style rule basics

As you can see in the sections above Mkgmap uses different files to read the rules we create. Every element on a map consists of points, lines and polygons. So we have to work with 3 different types of objects which each need its own file with rules. A rule consists of at least 2 parts. First is a test checking the object to be converted. Second is the definition of the element type, which sets the Garmin type and other parameters if the test part matches an object.
Example of a simple style rule in the points file:

tourism=information [0x2f0c resolution 24]

Test part of the rule:


Element type definition of the rule:

[0x2f0c resolution 24]

If there is a point in our OSM map that has the key "tourism" with the value "information" the test matches this object and mkgmap sets the type definition of this object to the Hex value definedin the rule. The resolution parameter defines the level of zoom from which it can be seen on the map.

Hints to troubleshooting style rules

“Catch all” - Rules & echoing When creating style rules it might come in handy using “catch all” rules. Those are for testing only but shows results and information which aren´t processed by specific rule.

seamark:type=* {echo 'seamark:type CATCH ALL'}[0x010508 resolution 19]
seamark=* {echo 'seamark CATCH ALL'}[0x010508 resolution 19]

What are those lines doing?
The “echo” will print the message while mkgmap is working the file - the final goal should be to not see any of those messages (this mean your rule set has caught every point with a specific rule). For a more detailed report you could replace “echo” with “echotags”. The type-definition points to a minefield in this case - but feel free to use any other value which suits you. Be careful to use a corresponding garmin type value to each of your files (point type for points file, line type for lines files and polygon type for polygons file).

Difference between “echo” and “echotags” using the "seamark=*" test operation.

“echo” output:

Time started: Wed Jun 04 15:27:48 CEST 2014
113835522: seamark CATCH ALL
178088849: seamark CATCH ALL
142099911: seamark CATCH ALL
34329207: seamark CATCH ALL
34329576: seamark CATCH ALL
205192343: seamark CATCH ALL
Time finished: Wed Jun 04 15:28:11 CEST 2014
Total time taken: 22625ms

Each line will list one object id and the pre-defined text from action-block of that “catch all” rule.

“echotags” output:

Time started: Wed Jun 04 15:29:20 CEST 2014
113835522 - [seamark:small_craft_facility:category=slipway,seamark:type=small_craft_facility,leisure=slipway,seamark:information=by car] seamark CATCH ALL
178088849 - [seamark:type=exclusive_economic_zone,FIXME=separate into affected countries!] seamark CATCH ALL
142099911 - [seamark:type=production_area,name=Baltic 1,operator=EnBW Energie Baden-W³rttemberg AG,power=plant] seamark CATCH ALL
34329207 - [seamark:light:1:range=20,seamark:light:1:sector_start=070,seamark:light:1:colour=white,seamark:type=landmark,man_made=lighthouse,
           name=Leuchtturm Warnemünde,seamark:light:1:sector_end=250] seamark CATCH ALL
34329576 - [seamark:type=landmark,amenity=restaurant,name=Hotel Neptun,tourism=hotel] seamark CATCH ALL
205192343 - seamark:light:period=4,seamark:light:character=Iso,seamark:type=beacon_lateral,seamark:light:height=12,man_made=beacon,
            name=Westmolenfeuer,seamark:beacon_lateral:colour=green,seamark:light:range=6,seamark:light:colour=green,seamark:beacon_lateral:category=starboard] seamark CATCH ALL
Time finished: Wed Jun 04 15:29:40 CEST 2014
Total time taken: 19484ms

That sample “echotags” output starts the same as the “echo” output with the object id and ends identical with the pre-defined text. In between there is the whole information available for processing for this object id. You will notice the “FIXME” message within the osm-data which isn´t jet defined correctly. More often you´ll find out which tag your rules aren't being catched and processed.

In the same manner you can apply rules to hide points:

seamark:type=production_area {echo 'seamark:type production_area INVISIBLE'}

Simply test for a specific type (of course the asterisks works to filter a whole group) and add an action-block for messaging while processing the file (for the purpose that you´ll get reminded of those “filtered” objects) without a type-definition.

Creating a map

If you got your desired OSM map and a working set of style rules you can create a map for your Garmin device. This is a step-by-step working procedure which will lead to a rule set suiting your needs.
We start by using Mkgmap to create an overview map:

C:path\to\my\mkgmap\directory>java -jar mkgmap.jar my_downloaded_map.osm

If everything worked output on your commandline should look like this:

Time started: Wed Jun 04 15:26:41 CEST 2014
Time finished: Wed Jun 04 15:26:49 CEST 2014
Total time taken: 8266ms

Now we can use Gmaptool on the just created overview map. Add the map to Gmaptool in the "Files" tab. Switch to the "Split" tab, select a Directory to save the map in, select a mapset name and a unique FID and PID. Those ID's have to be unique. In the create dropdown select "files for Mapsource". Is everything added click "Split all" or "Split selected". If you have only one map in the "Files" tab, "Split selected" will have the same effect as "Split all". This will create the necessary files in your before choosen Folder to install the map on your PC. Double click the "install.bat" and open Mapsource. You should now be able to see your map.

Our rule set

There are a lot of rule sets on the internet that can be used. Even rule sets for marine maps to show seamarks like beacons and lights. Because we could not find a rule set that could help us create a map for easy use on land and sea. So we decided to create a map that can be used on sea and land, most suitable when on vacation with your boat. This was our first style too, so we decided to start with one of the many example rule sets. Next we looked for examples of rules for marine use, what we found helped us a lot. As a basis to start our rule set we used the style rules for marine use, which included buoys and lights. The problem now was to find the objects in the map the pre-made rules did not apply to. To counter this we implemented a rule that should catch all the objects that did not have a match and give it a specific style definition that we thought will not occur very often in the area we are working with, for instance a minefield. For an example of this catch all rule see the section "Hints to troubleshooting style rules". The "echo" in the action block of the catch all rule also prints the ID of the object the rule applied to. This object ID is searchable in JOSM. That way you can get every object key to of the not yet processed objects using JOSM.

Style rules for line objects

To create style rules for lines and polygons was not a big problem. Those are really straight forward. We started by looking for lines with a seamark key by creating a "catch all" rule and looking for the object ID's via JOSM that mkgmap returned. Objects we found mostly were related to marine traffic like separation boundaries, restricted areas or recommended tracks for navigation.

seamark:type=recommended_track | seamark:type=navigation_line [0x010108 resolution 18]

Other marine related objects like a pier or nature reserves were found by compiling the not yet finised map to compare it with the map in JOSM.

man_made=pier [0x01040c resolution 22]
man_made=breakwater [0x010400 resolution 22]

In the next step we included rules for waterways, which could be found in several example rule sets also included also in mkgmap. We also created some rules to include boundaries on land as well as on sea. To do this we had to check for the "maritime" and "boundary" key on line objects.

boundary=maritime [0x010603 resolution 16]
boundary=* & maritime=yes [0x010603 resolution 16]
boundary=administrative [0x1c resolution 16]
boundary=administrative & border_type=territorial [0x1e resolution 16]

Because we had problems to display the right names on Marina points with commas we used the substitution filter in our rule to apply names to marina points and set a default name "Marina" for unnamed Marinas.

leisure=marina { name '${name|subst:,=>.}' } [0x4300 resolution 18 default_name 'Marina']

Style rules for polygon objects

The polygon rules were created to view polygons for sea and landuse in general to have a more diffenrentiated view.

amenity=parking [0x05 resolution 22]
anduse=farmyard [0x4e resolution 22]
landuse=forest|landuse=wood [0x50 resolution 20]
landuse=greenfield [0x17 resolution 20]
natural=wetland [0x51 resolution 20]
natural=water [0x3c resolution 18]
natural=sea [0x32 resolution 10]

Style rules for point objects

This rule file includes rules for marine objects like buoys and lights. We started by using pre-made rules for lights which we then edited to fit our needs and added rules based on the pr-made ones to process objects those rules did not apply to. Rules like

seamark:light:1!=* & seamark:light:1:sector_start=*
& seamark:light:1:sector_end=* & seamark:light:1:colour=*
& seamark:light:1:range=*
{add seamark:light:1='${seamark:light:1:colour}:${seamark:light:1:sector_start}:${seamark:light:1:sector_end}:${seamark:light:1:range}'}

add sectored and directional lights to marine objects using the keys "sector_start", "sector_end", "colour" and "range" to view them on the compiled map. As you can see, this rule is using the key "seamark:light:1". This means that attributes like colour are added for the light with the number 1. As you can imagine a buoy or beacon can have more than one light each with different attribute values. So this rule has to be added for the number of lights that we want to be processed using a numeric value. To apply this rule for a the second light we would have to change the existing rule to use "seamark:light:2". A list of all tags with pictures as example can be found at OpenSeaMap/Sectored and Directional Lights.
This is necessary to make navigation based on lights and buoys possible. Definition of buoys and lights has/can be done separate.
For example:

seamark:light:1=* [0x010100 resolution 18]
seamark:buoy_special_purpose:shape=barrel [0x01020d resolution 18]
seamark:type=buoy_special_purpose [0x01020b resolution 18]

At last to make the map more useable we added rules to process necessary and important points. Those rules include cafes, car rentals, drinking water, ferry terminals, police as well as toilets, hotels and informations points.

amenity=cafe [0x2a0e resolution 24]
amenity=car_rental [0x2f02 resolution 24]
amenity=drinking_water [0x5000 resolution 24 default_name 'Water']
amenity=ferry_terminal [0x2f08 resolution 22]
amenity=police [0x3001 resolution 24]
amenity=toilets [0x4e00 resolution 24 default_name 'Toilets' ]
tourism=hotel | tourism=motel [0x2b01 resolution 24]
tourism=information [0x2f0c resolution 24]

Difficulties we experienced

We have experienced a lot of difficulties throughout the whole process. First of all it seems that there are several different projects working on the same issues available, which made it hard at the beginning to get a clear overview. Mkgmap has a big community and is well documented. We wanted to avoid TYP-Files so we need to use only predefined garmin graphics (the maps should work on marine and handheld garmin devices) which are documented well. There are several -incomplete- lists floating around the net but some are lacking the graphic itself or the hex-codes. Since we had some experience with programming the rules themselves aren't quite difficult to understand and the possibility to use regular expressions within makes them more versatile. It could be that someone who isn’t experienced will see the the rules files as cryptic and unreadable and will not use mkgmap - so a graphical editor might be nice for the average internet user. Finally understanding marine navigation was a bit complicated for landsman like we are. The differences within continents or countries made this challenging and time-intensive. We focused on european symbols and we didn’t test the rule set against other regions.