This page gives an advanced look into how Maperitive rendering rules function. Although the whole concept might seem complicated at first, it's actually pretty simple. From this simplicity you can get a number of ways of how to define the rules. Sometimes these different ways end up with the same result on the map, sometimes they can differ slightly and sometimes the differences can be substantial.
But let's start from the beginning.
If you want to draw something, you need to know what color to use, what is the thickness of the line etc. This is controlled through Rendering Properties (TODO) like line-color, border-width etc.
It's important to know that all of rendering properties have default values. When Maperitive starts processing a rule, it starts by assigning these default values to properties. So, for example, you don't need to specify
define text : name
since the value "name" is already a default value of the text property.
You can set your own default values in the properties section of the ruleset, for example
properties text : name:fr
will tell Maperitive to use names in French by default.
Inside each of the rules you can change the value of a rendering property using the "define" command. You need to understand the scope of this change:
Example is worth a hundred words, so let's illustrate this with an example (I've left out feature definitions, but I think you can figure those out for yourself):
... properties font-family : Tahoma target : place country define font-family : Times New Roman draw : text target : place city draw : text
The results of these rules are:
The real power of Maperitive rules lies in the ability to define a decision tree within a single rule. This is achieved using commands like "if", "elseif", "for", "elsefor" and "else".
Let's start with a simple decision tree:
target : *road if : major road define (A) line-width : 20 else define (B) line-width : 10 draw : line (C)
I've marked the key commands with symbols so I can present the flow of the command more easily. Let's say we have three features: major road, medium road and minor road (specified in that order). Based on the rule match string ("*road"), Maperitive will execute the rule commands on these features in the following order:
I've indicated which of the commands will be executed for each of the features (I've left out the conditional commands since they can be deduced from the context).
This is not the only way to achieve the same result:
target : *road if : major road define (A) line-width : 20 draw : line (B) else define (C) line-width : 10 draw : line (D)
Notice that we have now moved the "draw" command to the inside block of each of the conditional commands (using tabs identation). The flow now is as follows:
But in our case this amounts to the same thing (setting the appropriate line width and drawing a line).
We can nest the conditional commands:
target : *road if : major road define (A) line-width : 20 else if : medium road define (B) line-width : 15 else define (C) line-width : 10 draw : line (D)
with the flow being
We can even stop some of the flows:
target : *road if : major road define (A) line-width : 20 else if : medium road define (B) line-width : 15 else stop (C) draw : line (D)
with the flow being
I gave the above two examples to illustrate the ability to nest conditional commands within other conditional commands. But a more proper way to define the rule which results with the same effect on the map would be
target : *road if : major road define (A) line-width : 20 elseif : medium road define (B) line-width : 15 else define (C) line-width : 10 draw : line (D)
again, the flow is exactly the same as in the example before the previous one:
The only difference is that the rule is more readable, since we only use one level of nesting.
TO BE CONTINUED