Rules allow you to take a map feature in the OSM format, which uses a set
of tags to describe the feature into the format required by Garmin maps,
where features are identified by a number.

The rules for converting points, lines and polygons are held in correspondingly named
files.

Each file contains a number of rules where you test the values of the
tags of an OSM node or way and select a specific Garmin type based on the
result of those tests.

See also: [[mkgmap/help/style examples|Style examples]] | [[Mkgmap/help/Custom_styles|Custom styles]].

==Simple example==
In the majority of cases everything is very simple, say you want roads
that are tagged as <tt>highway=motorway</tt> to have the Garmin type 0x01
and for it to appear up until the zoom level 3.

You would write the following rule.

 highway=motorway  [ 0x01  level 3 ]

This will be explained in more detail in the following sections along
with how to use more than one tag to make the choice.
However with that one form of rule, you can do everything that the old map-features
file could do.

== More detail ==
A rule is made up of two parts.  The first part is a set of tests that are
performed on the tags of the item to be converted.  The second part is the
Garmin type that will used if the tests match and associated details.  This
part is contained in square brackets <tt>[ ... ]</tt>.

As a general point, space and newlines don't matter.  There is no need to
have rule all on the same line (although I will present most of the
examples in that way), and you can spread them out over several lines and add
extra spaces where ever you like.

== Tag tests ==
The main test is that a particular tag exists and has a given value.
So in the example above we had:

 highway=motorway

This means that we look up the highway tag and if it exists and has the value
'motorway' then this test has matched.

You can also compare numeric quantities:

 population > 10000
 maxspeed >= 30
 population < 10000000

This means a population greater than ten thousand, a max speed greater than or equal
to 30 and a population less than one million respectively.
You will be able to compare quantities that have units too, for example

 maxspeed > 30mph

If a different unit is given in the tag (say km/h) then conversion will
be performed.  This is not implemented at the time of writing, so please let
me know real useful cases that you come across that you would like to
work.

=== Combining tag tests ===
Although it is possible to convert most OSM nodes and ways just using the
one tags, it is occasionally necessary to use more than one.  For
special purpose maps it is more likely that you will need to look at more
than one tag too.

For example, say you want to take roads that are tagged both as
<tt>highway=unclassified</tt> and <tt>abutters=residential</tt>
differently than roads that just have a plain
<tt>highway=unclassified</tt>, you might have the following rules:

 highway=unclassified & abutters=residential [ 0x06 ]
 highway=unclassified [ 0x05 ]

This means that roads that have both tags would have Garmin element type
of 6, whereas unclassified roads without would have the type 5.

It is important to note that the order is important here.  The rules are
matched in the order that they occur and stop at the first one that
matches.  If you had them in the other order, then the
<tt>highway=unclassified</tt> rule would match both cases.
In general you want the most specific rules first and simpler, more
general rules later on to catch the cases that are not caught be the more
complex rules.

You can also combine alternatives into the one rule.  For example

 highway=footway | highway=path [ 0x7 ]

This means if the road has either the <tt>highway=footway</tt> tag or the
<tt>highway=path</tt> tags (or both), then the condition matches and it would
be represented with type 0x07.  It is exactly the same in behaviour and
speed as writing the two rules, one for footway and one for path and is
converted to those two rules internally.

You are not limited to two tests and you can combine and group them
almost in whatever way you like (with one exception, see below).
So for a slightly forced example the following would be possible:

 place=town & (population > 1000000 | capital=true) | place=city

This would match if there was a <tt>place</tt> tag with the value
<tt>city</tt>, or if <tt>place</tt> had the value <tt>town</tt>
and either the population was over a million or it was tagged a capital.

=== Important note ===
You must start each test with a simple test for tag equality.
It may be possible in future that this restriction will be relaxed, although it is
likely to be slower if you make use of it.

=== Additional tests ===
To wrap up this section here are the other available tests.
; <tt>highway!=motorway</tt>
: This will be true when the highway tag exists, but it does NOT have the value <tt>motorway</tt>
; <tt>highway=*</tt>
: This will be true when the highway tag exists on the element.  It doesn't matter what the value is. This is especially useful for tags where it is just their presence that matters
; <tt>highway!=*</tt>
: This is true when there is no highway tag.

== Element type definition ==
As noted above this is contained in square brackets.

The first thing must be the element type and this is the only thing that is
required to be there.
Following the type you can have a number of optional keywords and values.

; level
: This is the highest zoom level that this element should appear at (like EndLevel in the mp format).  If this is not given then it defaults to 0 and so the feature will only appear at the most detailed level.  You can also give a range 1-3 and it will appear between those levels (not implemented at the time of writing).
; resolution
: This is an alternative way of specifying the level.  It is the number from 0-24 which corresponds to one of the zoom levels that the hardware recognises.  You should not use this if you have given the level and it is usually simpler to use 'level'.
; default_name
: If you give this, then if the element does not already have a name, then it will be given this name.  This might be useful for things that usually don't have names and don't have a recognisable separate Garmin symbol.  You could give a default name of 'bus stop' for example and all bus stops that didn't have their own name would now be labeled as such.
; road_class
: Used for routing; gives the class of the road where 4 is the best roads eg. motorways and 0 are residential roads etc.
; road_speed
: Used for routing; an indication of how fast traffic on the road is.  0 is the slowest and 7 the fastest.

Example: <tt>[0x2 road_class=3 road_speed=5 level 2]</tt>

== Action block ==
An action block is enclosed in braces <tt>{ }</tt> and contains a number
of statements that can alter the element being displayed.  When there
is an action block, the element type definition is optional, but if it
occurs it comes after the action block.

=== name ===
This sets the final name of the element, that is the name that will be used on the map.
It is distinct from any 'name' tag on the element.
You can give a list of alternatives separated by '|' pipe symbols.  This first alternative that matches
will be used.  Once the name is set it cannot be overridden, so if more than one 'name' command matches then 
only the first to set the name will take effect.

Tags can be used in the value by using the notation: <tt>${tagname}</tt>.

Example for roads we do this:
 name '${name} (${ref})' | '${ref}' | '${name}';

This means that if name='Main St' and ref=A1 the name would be "Main St (A1)", but if there
was no 'name' tag then the result would be just "A1".  If the name tag was set and not the ref tag, then
the element-name would just be the value of the name tag.
This emulates the historical behaviour of mkgmap.

=== add ===
The add command adds a tag if it does not already exist.
The only tag where this is directly useful is the 'oneway' or 'name' tags.
For example make motorways oneway unless the oneway tag is set:
 highway=motorway { add oneway=yes }

The other use is in in relations with the 'apply' command.

All the same you can set any tag you want, it might be useful so you can match
on it elsewhere in the rules.

You can also use substitutions.
 { set name='${ele}'; set name='${ref}'; }

These two commands would set the 'name' tag to the value of the 'ele' tag if it exists, or to the value of the 'ref' tag
if that exists.

=== set ===
The 'set' command is just like the 'add' command, except that it sets the tag, even if the tag
already exists.


=== apply ===
The apply command only makes sense in relations.
Say you have a relation marking a bus route but none of the ways that are in the relation have any special tags
to indicate that it is a bus route.  You want to display the bus route specially.  You might write a rule
in the relations file such as:

<pre>
 type=route & route=bus {
 	apply {
		set route=bus;
		set route_ref='${route_ref}';
	}
 }
</pre>

Then in the lines file you can write a rule to match on <tt>route=bus</tt>.
All the relation rules are run before any others so that this works.

The substitution '${route_ref}' takes the value of the tag on the '''relation''' and applies it to each of the
ways in the relation.

== Note on backward compatibility ==
If you convert an old map-features.csv file to the new style-rules files
then you will get exactly the same output as you did with the old
map-features file and it will run at the same speed.
There is a script for doing this called new_style.py in the scripts directory (requires python
to run).

The following two sets of examples show how the map-features lines can be
converted into identical rules.

 OLD: point|amenity|bank|0x2f|0x06|21
 NEW: amenity=bank [0x2f06 resolution 21]

 OLD: polyline|highway|primary|0x04||19
 NEW: highway=primary [0x04 resolution 19]

If you have both a map-features.csv file and the points, lines, polygons
rule files, then the result is exactly the same as if you wrote the
corresponding rules for each line in map-features as above and appended
to the bottom of the rule files.
