Skip to content

Latest commit

 

History

History
278 lines (215 loc) · 13.3 KB

Rendertheme.md

File metadata and controls

278 lines (215 loc) · 13.3 KB

RenderTheme

This article describes how to use XML-based render-themes to style maps.

Introduction

A render-theme is an XML file which contains rules and rendering instructions. Such files can be used to customize the visual style of the rendered map. The vtm map library comes with built-in render-themes similar to the Osmarender style. External render-theme files are also supported and can be activated via the map.setTheme(ThemeLoader.load(File)) method at runtime.

Syntax and semantics of render-theme files are similar but not identical to Osmarender rules. A formal render-theme description exists as an XML schema document, it can be found in the repository.

It is always recommended to study the default built-in render theme.

Rules

A rule element <m/> (match) has several attributes to specify which map elements the rule matches. Non of them is required.

Attribute Valid values Description Default
e
  • node
  • way
  • any
Defines which map element type will be matched. any
k string The key of the tile source tag.
  • A vertical bar "|" can be used to specify multiple keys.
any key
v string The value of the tile source tag.
  • A vertical bar "|" can be used to specify multiple values.
  • A minus sign "-" excludes the other values after "|". It never works alone.
  • A tilde "~" matches if the map element does not have a tag with the specified key.
any value
closed
  • yes
  • no
  • any
Defines which ways will be matched. A way is considered as closed if its first node and its last node are equal. any
select
  • first
  • when-matched
  • any
  • Only add the first matching sub-rule in this rule section (the others are ignored)
  • Select all matches of the enclosing rule section
  • Select all (whether it was matched or not)
any
zoom-min unsigned byte The minimum zoom level on which the rule will be matched. 0
zoom-max unsigned byte The maximum zoom level on which the rule will be matched. 127

Rules can be nested to any level of depth. This can be used to define rendering instructions which depend on multiple rules. It may also be used to structure complex declarations and to avoid redundancy:

<m e="way" closed="no">
    <m k="highway" v="motorway">
        <m k="tunnel" v="true|yes">
            …
        </m>
        <m k="tunnel" v="~|no|false">
            …
        </m>
    </m>
</m>

Here is an example how to use the select attribute. The symbol is shown. The bold caption isn't visible cause only the first matched sub-rule is considered. The italic caption is displayed as it was selected by the first sub-rule.

<m k="railway" v="halt|tram_stop" zoom-min="15" select="first">
    <m v="tram_stop">
        <symbol src="assets:symbols/transport/tram_stop.svg" />
    </m>
    <m v="tram_stop">
        <caption style="bold" dy="20" fill="#af3a3a" k="name" size="12"/>
    </m>
    <m select="when-matched">
        <caption style="italic" dy="-20" fill="#222222" k="name" size="12"/>
    </m>
</m>

Rendering Instructions

A rendering instruction specifies how a map element is drawn. Each rule element might include any number of rendering instructions. Except for labels and symbols, all rendering instructions are drawn on the map in the order of their definition.

At the moment, the following rendering instructions are available:

  • area
  • caption
  • circle
  • line
  • outline
  • lineSymbol
  • text
  • extrusion
  • symbol

Header Elements

The following header elements can be used:

  • map-background: a color value to set the color of a blank tile. This should not be used to set the color of the sea or land. Default is #FFFFFF.
  • base-stroke-width: set the basic width of strokes. Default is 1.
  • base-text-scale: set the overall text scale. Default is 1.
<?xml version="1.0" encoding="UTF-8"?>
<rendertheme xmlns="http://opensciencemap.org/rendertheme" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://opensciencemap.org/rendertheme https://raw.githubusercontent.com/mapsforge/vtm/master/resources/rendertheme.xsd" version="1" map-background="#FFFCFA">
    …
</rendertheme>

Texts and Captions

The most common attributes for textual styling:

Attribute Valid values Description Default
font-family default, default_bold, monospace, sans_serif, serif, thin, light, medium, black, condensed Set font family default
style bold, bold_italic, italic, normal Set font style normal
size non negative float Set font size 0
fill color Set fill color #000000
stroke color Set stroke color #000000
stroke-width non negative float Set stroke width 0
dy float Offset in vertical direction 0

Styles

There are different possibilities to simplify and accelerate map styling or changing styles.

Style patterns

If you want to use a specific style multiple times you not have to rewrite it for each text, line, area or symbol rule. If you define a style set an id and use it with use in your rendering instructions:

  • style-text
  • style-line
  • style-area
  • style-symbol

This example styles all areas with the_residential_ style, which haven't the highway or building key.

<style-area fade="11" fill="#e8e7e3" id="residential" />

<m closed="yes" e="way" k="highway|building" v="~">
    <m v="residential|commercial|retail|farmyard">
        <area use="residential" />
    </m>
</m>

Stylemenus

The stylemenu allows you to selectively turn rules on and off, in effect defining multiple layers in a map that can be controlled individually.

To make use of style menus, you will first need to group the elements of your map into categories by attaching a cat element to them.

<m cat="areas" e="way" k="landuse" v="landfill|quarry" zoom-min="14">

The same cat tag can be given to as many elements as you like, but each element can only have one cat tag. However, this does not limit your ability to group elements, as in the style definitions, multiple categories can be combined into one layer.

You can think about the cat tag as a switch that switches all elements in the rendertheme below it either on or off. If a category is turned off, all elements below it become invisible. If a category is turned on, all elements below become visible (unless they are themselves controlled via a category which is turned off).

Layers are combinations of categories that can be toggled on and off together and other layers (via overlay) that can be toggled on and off individually. In general, categories are not visible to a map user, but layers are. To make layers more user friendly, they can be named with the name tag in various languages.

<layer id="public_transport" visible="true">
    <name lang="de" value="Öffentlicher Verkehr"/>
    <name lang="en" value="Public Transport"/>
    <name lang="es" value="Transporte público"/>
    <name lang="fr" value="Transport public"/>
    <cat id="public_transport"/>
    <cat id="rail"/>
</layer>

A set of layer definitions makes up a style:

<stylemenu id="r4menu" defaultvalue="terrain" defaultlang="en">
    <layer id="shopping" visible="true">
        <name lang="de" value="Shopping"/>
        <name lang="en" value="Shopping"/>
        <name lang="es" value="Tiendas"/>
        <name lang="fr" value="Shopping"/>
        <cat id="shopping"/>
    </layer>

    <layer id="terrain" visible="true">
        <name lang="de" value="Topographischer Hintergrund"/>
        <name lang="en" value="Topographic Colours"/>
        <name lang="es" value="Colores topográficos"/>
        <name lang="fr" value="Couleurs topographiques"/>
        <cat id="topo"/>
    </layer>
</stylemenu>

The visible attribute is meant to indicate which of the layers are visible in the user interface. Layers where visible is set to false should not be seen by a user, and are thus useful to build base-layers of common categories from which then user-visible layers can be inherited, like this:

<layer id="base">
    <cat id="roads"/>
    <cat id="waterbodies"/>
    <cat id="landuse"/>
    <cat id="places"/>
    <overlay id="emergency"/>
    <overlay id="food"/>
</layer>

<layer id="simple" parent="base" visible="true">
    <name lang="de" value="Auto"/>
    <name lang="en" value="Driving"/>
    <name lang="es" value="Conducción"/>
    <name lang="fr" value="Conduite"/>
    <cat id="transport"/>
    <cat id="barrier"/>
    <cat id="driving"/>
    <overlay id="parking"/>
    <overlay id="shopping"/>
</layer>

<layer id="standard" parent="base" visible="true">
    <name lang="de" value="Stadt"/>
    <name lang="en" value="City"/>
    <name lang="es" value="City"/>
    <name lang="fr" value="Ville"/>
    <cat id="areas"/>
    <overlay id="tourism"/>
    <overlay id="sports"/>
    <overlay id="amenities"/>
    <overlay id="buildings"/>
    <overlay id="public_transport"/>
    <overlay id="accommodation"/>
    <overlay id="shopping"/>
</layer>

To turn layers on by default, add the enabled=true attribute. In this case, buildings should be by default visible, while parking related elements not:

<layer id="parking">
    <name lang="de" value="Parkplätze"/>
    <name lang="en" value="Parking"/>
    <name lang="es" value="Aparcamiento"/>
    <name lang="fr" value="Parking"/>
    <cat id="parking"/>
</layer>

<layer enabled="true" id="buildings">
    <name lang="de" value="Gebäude"/>
    <name lang="en" value="Buildings"/>
    <name lang="es" value="Edificios"/>
    <name lang="fr" value="Bâtiments"/>
    <cat id="buildings"/>
</layer>

Map Integration

The Playground and Android Samples app have a completely worked style menu. When a rendertheme is parsed, the style menu definitons are parsed and a callback is made into the application giving it access to the stylemenu definitions.

On Android, the stylemenus can thus be converted into standard Android settings, providing a seamless integration of the rendertheme definitions that do not require changes every time the rendertheme changes. There is an example on how to do this in the Samples app of Mapsforge, see the Settings.java file in Mapsforge repository.

Priorities

Labels and icons are drawn in order of priority. The default (and highest) priority is 0, so anything with a priority higher than 0 will only be drawn if the space is not yet taken up or has a lower priority value than its colliding elements.

VTM priorities have the opposite meaning to the Mapsforge render-theme priorities.

<m e="node" k="place" v="town" zoom-min="8">
    <caption priority="2" k="name" style="bold" size="14" fill="#333380" stroke="#FFFFFF" stroke-width="2.0"/>
</m>
<m e="node" k="place" v="city" zoom-min="6" zoom-max="6">
    <caption priority="0" k="name" style="bold" size="11" fill="#333380" stroke="#FFFFFF" stroke-width="2.0"/>
</m>

Symbols

Symbols can be either defined in the raster PNG format or as vector graphics in SVG format. VTM uses libraries for Android and Java that support a large subset of the Tiny SVG specification.

SVG Scaling

SVG resources can be automatically scaled to accommodate different device resolutions.

The options available are:

  • If no size is given, a svg is rendered to a 20x20px multiplied by the device scale factor and any user adjustments.
  • symbol-percent: the svg is rendered as a percentage size of its default size. This is the best way to make certain svg smaller or bigger than others.
  • symbol-width and/or symbol-height: additional parameters give the absolute pixel size for the symbol, again adjusted by the scale factors. If only one dimension is set, the other is calculated from aspect ratio.

SVG Icon Design

If you want to know how to design your own icons, you can have a look at Google's Material Design conventions. To keep SVG sizes down, it is advisable to make use of the reuse facilities within SVG files and to remove any unneccessary comments and metadata.