Osmarender/Rules

From OpenStreetMap Wiki
Jump to: navigation, search

Contents

Developing Osma Styles

If you plan to create a new style for rendering, have a look at Osmarender Styleguide where we try to collect some guidelines.

Rule file grammar

The rule file is an xml file that specifies the drawing rules. So it needs to have an standard XML format at least. The following is the minimum format.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="osmarender.xsl"?>
<rules>
</rules>

<rule>

The basic structure is a list of selection rules containing rendering instructions that are processed sequentially. Items drawn later will be on top of items drawn earlier. For example:

<rules>
<rule e="way" k="highway" v="primary">
   ...
</rule>
<rule e="way" k="highway" v="motorway">
   ...
</rule>
 ...
</rules>

Each rule specifies what elements to select based on a matching key/value pair (for example, e="way" k="highway" v="motorway" will select all ways that have a highway tag with a value of motorway). It then specifies what to do with these nodes or segments or ways. The current instruction set allows lines, circles, symbols and text to be drawn.

Rules may be nested. This enables a rendering instruction to be based on a combination of key values. For example the following rule will select only anglican places of worship:

<rule e="node" k="amenity" v="place_of_worship">
  <rule e="node" k="denomination" v="anglican">
    ...
  </rule>
</rule>


 <rule e="elementList" k="keyList" v="valueList" 
   [s="selector"] 
   [closed="yes|no"]
   [horizontalProximity="degrees" verticalProximity="degrees"]
   [notConnectedSameTag="key"]
   [minSize="number"]>
    ...
 </rule>
Requirements
Options

<else>

<rules>
 ...
<rule e="node" k="denomination" v="anglican">
 ...
</rule>
<else>
   ...
</else>
</rules>

The <else> rule selects all elements that were not selected by the preceding <rule>.

Due to a limitation in the implementation horizontalProximity/verticalProximity, notConnectedSameTag and minSize (which are implemented as filters) don't work in the expected way with <else>, they get applied in the same way to both <rule> and <else>.

Rendering Instructions

an osm file used below examples. This illustration rendered by osm-map-features-z17.xml

Between the <rule> and </rule>, you should add at least one rendering instruction.

Each rendering instruction can contain SVG styling attributes or it can reference a class that is defined in an embedded CSS stylesheet so the full power of SVG and CSS can be used to control the look and feel of the output.

When <symbol> or <caption> is used on an area the position of the icon is calculated using the algorithm described on [1].

The current <pathText> used to be called text, and it worked on ways and nodes. For areas there was an <areaText> instruction. <symbol> used to only work for nodes, and one needed to use <areaSymbol>. The old instructions are still present for backwards compatibility, but may be removed at some future date.

The following instructions tell Osmarender what to do with the OSM elements selected by a rule:


<line>

Example for <line>

<line> draws a line. It applies to way elements.

<rule e="way" k="keyList" v="valueList">
  <line
   [smart-linecap="yes|no"]
   [honor-width="yes|no"
    width-scale-factor="factor"
    minimum-width="px"
    maximum-width="px"]
   [style="SVG style"]
   [class="class name list"]
  />
</rule>
Options


<area>

example for <area>
<rule e="way" k="keyList" v="valueList">
  <area
   [style="SVG style"]
   [class="class name list"]
  />
</rule>
Options


<wayMarker>

example for <wayMarker>
<rule e="node" k="keyList" v="valueList">
  <wayMaker
    k="key for the way"
   [style="SVG style"]
   [class="class name list"]
  />
</rule>
Requirements
Options


<circle>

example for <circle>

<circle> draws a circle. It applies to node and closed way elements.

<rule e="node|way" k="keyList" v="valueList">
  <circle
   r="radius"
   [style="SVG style"]
   [class="class name list"]
  />
</rule>
Requirements
Options


<symbol>

example for <symbol>
<rule e="node|way" k="keyList" v="valueList">
  <symbol
    ref="file name"
   [position="where"]
  />
</rule>
Requirements
Options


<caption>

example for <caption>
<rule e="node|way" k="keyList" v="valueList">
  <caption
    k="key for the text instruction"
   [dx="dx"]
   [dy="dy"]
   [text-anchor="start|middle|end"]
   [style="SVG style"]
   [class="class name list"]
  />
</rule>
Requirements
Options


<pathText>

example for <pathText>
<rule e="way" k="keyList" v="valueList">
  <pathText
    k="key for the text instruction"
   [dy="translational length"]
   [text-anchor="start|middle|end"]
   [startOffset="caption"]
   [avoid-duplicate="true|false"]
   [style="SVG style"]
   [class="class name list"]
  />
</rule>
Requirements
Options


z-index

It is possible to set instruction's stack order. That is whether instruction will be drawn below or above other instructions.

The order depends on three attributes (in order of importance): z-mode, layer and z-index. Z-mode is either bottom, normal or top. Bottom means instruction is drawn below other instructions, layer is ignored. Normal means instruction is drawn as usual, layer is respected. Top draws instruction above other instructions, layer is ignored.

Z-index sets position within the group of elements with the same z-mode (and layer in case of z-mode=normal).

Instructions can have layer attribute which overrides any layer tag that there may be on the actual element itself. This is supported only for backwards compatibility.

<defs>

<defs> is a child element of <rules>. You can script additional information for SVG file generated by osmarender here. The scripted text between <defs> and </defs> is directory copy to the output SVG file as a <defs> tag.

<style>

The most important information to be added is cascade style sheets (CSS). CSS is script between <style> and </style>:

<rules>
  <rule ...>
   ...
  </rule>
  <defs>
    <style xmlns="http://www.w3.org/2000/svg" type="text/css">
      .map-background {
	fill: #f8f8f8;
	stroke: none;
      }
     ...
    </style>
  </defs>
</rules>

Note that I strongly recommended to script this <style> tag even if you don't use any class attributes in your rules, because the map background use some CSS classes and they don't have the default values. It means that some renders show black or transparent background when you didn't specify it. What classes are used are written on the page Options.

Examples

Simple Example

This is a simple example of a rule file that selects primary roads (all ways with a key of highway and a value of primary) and draws them first in black with a 4px wide line and then in green with a 2px line (this results in a green road with a black border or casing).

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type="text/xsl" href="osmarender.xsl"?>
 
<rules 
  data="data.xml"
  scale="1"
  minimumMapWidth="4"
  minimumMapHeight="3"
  showScale="yes"
  showGrid="yes"
  showBorder="yes"
  showAttribution="yes"
  showLicense="yes"
  showZoomControls="yes"
  javaScript="yes">
 
  <rule e="way" k="highway" v="primary">
      <line style="stroke-width: 4px; stroke-linecap: round; stroke: #000000;"/>
  </rule>
 
  <rule e="way" k="highway" v="primary">
      <line style="stroke-width: 2px; stroke-linecap: round; stroke: #7FC97F;"/>
  </rule>
 
</rules>

Example of drawing nodes

Nodes can be drawn either as circles or as captions or both. This example draws towns as captions, churches as black circles with the name of the church as a caption, and hotels as uncaptioned green circles.

When a circle and a caption are both drawn for a node the caption can be offset from the circle by using the SVG attributes dx and dy.

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type="text/xsl" href="osmarender.xsl"?>
 
<rules 
  data="data.xml"
  scale="1"
  minimumMapWidth="4"
  minimumMapHeight="3"
  showScale="yes"
  showGrid="yes"
  showBorder="yes"
  showAttribution="yes"
  showLicense="yes"
  showZoomControls="yes"
  javaScript="yes">
 
  <rule e="node" k="class" v="town">
    <caption k="name" font-family='Verdana' font-size='14px' font-style='bold' fill='black'/>
  </rule>
 
  <rule e="node" k="class" v="church">
    <circle r='3px' fill='black' stroke='black' stroke-width='1px'/>
    <caption k="name" font-family='Verdana' font-size='10px' fill='black' dx='4px' dy='4px'/>
  </rule>
 
  <rule e="node" k="class" v="hotel">
    <circle r='3px' fill='green' stroke='black' stroke-width='1px'/>
  </rule>
 
</rules>

Example of using embedded CSS styles

CSS styles can be used to define the appearance of drawing elements using a style element embedded in the rules file. This is done by referencing the style using the class attribute. The following example shows minor and unclassified roads drawn using the same style.

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type="text/xsl" href="osmarender.xsl"?>
 
<rules 
  data="data.xml"
  scale="1"
  minimumMapWidth="4"
  minimumMapHeight="3"
  showScale="yes"
  showGrid="yes"
  showBorder="yes"
  showAttribution="yes"
  showLicense="yes"
  showZoomControls="yes"
  javaScript="yes">
 
  <rule e="way" k="highway" v="unclassified">
      <line class='unclassified-casing'/>
  </rule>
 
  <rule e="way" k="highway" v="minor">
      <line class='unclassified-casing'/>
  </rule>
 
  <rule e="way" k="highway" v="unclassified">
      <line class='unclassified-core'/>
  </rule>
 
  <rule e="way" k="highway" v="minor">
      <line class='unclassified-core'/>
  </rule>
 
  <defs>
    <style type="text/css" xmlns="http://www.w3.org/2000/svg">
      .unclassified-casing {
        stroke-width: 3px;
        stroke-linecap: round;
        stroke: #000000;
        }
 
      .unclassified-core {
        stroke-width: 2px; 
        stroke-linecap: round; 
        stroke: #E6E6E6;
        }
    </style>
  </defs>
 
</rules>

Example of route number captions

This example shows how to display route captions near a road. The text follows the path of the road but is offset to one side.

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type="text/xsl" href="osmarender.xsl"?>
 
<rules 
  data="data.xml"
  scale="1"
  minimumMapWidth="4"
  minimumMapHeight="3"
  showScale="yes"
  showGrid="yes"
  showBorder="yes"
  showAttribution="yes"
  showLicense="yes"
  showZoomControls="yes"
  javaScript="yes">
 
  <rule e="way" k="highway" v="primary">
      <line style="stroke-width: 4px; stroke-linecap: round; stroke: #000000;"/>
  </rule>
 
  <rule e="way" k="highway" v="primary">
      <line style="stroke-width: 2px; stroke-linecap: round; stroke: #7FC97F;"/>
      <pathText k="ref" font-family='Verdana' font-size='10px' fill='black' dx='2.5px' dy='-2.5px'/>
  </rule>
 
</rules>

Example of text on ways

This example shows how to render text along the the path of a way using the <pathText> instruction. The k="name" attribute specifies that the value of the name key should be used as the text value. The startOffset='50%' and text-anchor='middle' attributes specify that the text should centered halfway along the line of the path. The baseline-shift attribute offsets the baseline of the text from the center-line of the way.

Caveats:

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type="text/xsl" href="osmarender.xsl"?>
 
<rules 
  data="data.osm"
  scale="1"
  minimumMapWidth="4"
  minimumMapHeight="3"
  showScale="yes"
  showGrid="yes"
  showBorder="yes"
  showAttribution="yes"
  showLicense="yes"
  showZoomControls="yes"
  javaScript="yes">
 
  <rule e="way" k="highway" v="primary">
      <line style="stroke-width: 4px; stroke-linecap: round; stroke: #000000;"/>
  </rule>
 
  <rule e="way" k="highway" v="primary">
      <line style="stroke-width: 2px; stroke-linecap: round; stroke: #7FC97F;"/>
      <pathText k="name" baseline-shift='-35%' text-anchor='middle' startOffset='50%' font-family='Verdana' font-size='4px' fill='black'/>
  </rule>
 
</rules>

Example of collision detection

This example shows how to filter nodes to reduce the chance of collisions when captions are rendered. Normally, if two items, such as place names, are very close together then when they are rendered one will overlap the other.

A <rule> can filter nodes based on the distance to the next similar node by using the horizontalProximity and verticalProximity attributes. The two attributes describe a rectangle around a node. If there is another node of the same kind within this rectangle then the first node will be filtered out.

For example:

<rule e="node" k="place" v="town" horizontalProximity="0.8" verticalProximity="0.2">
  <rule e="node" k="place" v="town">
  	<caption k="name" class='caption-casing town-caption-casing'/>
  	<caption k="name" class='caption-core town-caption' />
  </rule>
</rule>

This rule will select all nodes tagged with place=town, but will filter out any nodes that are close to another node within 0.8 degrees horizontally or 0.2 degrees vertically.

Links

Personal tools
Namespaces
Variants
Actions
site
Toolbox