CartoType uses XML style sheets to control the appearance of maps. Features that can be controlled include the following:

  • selection of layers
  • colors
  • transparency
  • size of features
  • SVG icons
  • lettering style and positioning
  • scales at which features appear

Structure of a CartoType style sheet


<?xml version="1.0" encoding="UTF-8"?>
<CartoTypeStyleSheet name="mystylesheet" background="ivory" labelAttrib="name:en">
   <defs> ... </defs>
   <layer name="park"> ... </layer>
   <layer name="river"> ... </layer>
   <layer name="road"> ... </layer>
   <layer name="other-layer"> ... </layer>


Style sheet macros and variables

Style sheets can get very big. Two ways to save space are described here.


Macros are predefined pieces of the style sheet which can be referenced by name. You define macros in the <defs> section like this:

<macro id='minor-road-label'>
 <label font-size='75%,8pt' glow='white' color='black' case='assume-title' maxScale='20000'/>
<macro id='standard-tunnel'>
 <tunnel dashArray='1,1' fade='0.3' mouth='dimgrey' mouthWidth='20%,1' mouthPath='m 0 512 a 512 512 0 1 1 0 -1024'/>


It is often necessary to enable or disable parts of a style sheet, or make them dependent on run-time parameters. While it's possible to solve the problem using several different style sheets, it is much easier to put everything into one style sheet and select different features at run-time using conditional compilation controlled by parameters set by the application.

You can select any part of a style sheet (that is, any balanced XML) using

<if exp="expression"> ... </if>


Here are two maps of the same area drawn using different style sheets.


Above: Poole in southern England using the standard style sheet.


Dimensions are specified using numbers followed by optional units. A number without a unit refers to pixels. Sometimes units are not allowed, as for example in opacity levels, which are dimensionless. Where units are allowed, you can use any of the following:

  • pt: printer's points of exactly 1/72in (sometimes called PostScript points).
  • pc: printer's picas of 12pt.
  • cm: centimeters.
  • mm: millimeters.
  • in: inches.
  • m: map meters; that is, meters at the scale of the map, converted to pixels using the current map projection.
  • %: a percentage of some value depending on context; for example, in the context of a road, percentages refer to the width of the road, allowing you to specify that a road name is 75% of the width of the road.

Dimensions can optionally be followed by limits: minimum and maximum values. For example, it is useful to specify a label size in map meters, but clamp it to a certain range of sizes, avoiding lettering that is too small to read, or so large as to be ugly and obtrusive. For example:


sets a label size to 300 map meters but clamps it to the range 8pt...24pt. It is legal to omit the third (upper) limit, as in:



Colors are RGBA (red, green and blue components plus an 'alpha' or opacity level), and can be specified in these ways:

  • Hexadecimal 24-bit RGB, in the form #RRGGBB, where each group of two hex digits is an 8-bit intensity value. An opacity value of 255 (fully opaque) is used.
  • Hexadecial 24-bit RGB using three digits only: #RGB; the digits are treated as #RRGGBB
  • Hexadecimal 32-bit RGBA, in the form #RRGGBBAA, where the first three groups of two hex digits are the red, green and blue intensity levels and the last (AA) is the alpha or opacity value, where 0 = transparent and 255 = opaque.
  • Hexadecimal 32-bit RGBA using four digits only: #RGBA; the digits are treated as #RRGGBBAA
  • As an SVG color keyword. SVG (the W3 Scalable Vector Graphics standard) defines over a hundred keywords for colors, including all the common names and many unusual ones like 'khaki' and 'teal'.

Fonts are specified using a subset of the CSS font style attributes. For details see Labels.


Labels in style sheets

The <label> section in a <layer> section tells CartoType to draw a label and defines its style, including font attributes.

You can have up to two <label> sections in a <layer>. That enables you to draw both a highway shield with the highway reference, and an ordinary name along the road, for example. Use <labelAttrib> to select the correct name for each label, if using more than one.

The <label> attributes, in alphabetic order, are:


<scale> and <zoom> sections in style sheets

You will nearly always want your maps to look different at different scales. Some objects will not appear at some scales, and other will be drawn very differently. For example, minor roads may not appear at small scales, and city names may be suppressed or drawn as a faint overlay at large scales.

The easiest way to make this happen is to use <scale> sections:

<scale min='m' max='n'>

with any balanced XML you like inside them.


Levels of map objects

Most mapped objects are at ground level, but often it is useful to distinguish between various vertical levels, to allow the map to display objects in layer order.

CartoType uses 16 different levels. Ground level is 0, lower levels range from -8 (lowest) to -1, and higher levels range from 1 to 7 (highest).

Levels of map objects

How levels are stored in map objects

The level is stored as a signed nybble in bits 12..15 (mask = 0x0000F000) of the integer attributes of an object, but only if the road flag mask for that layer selects those bits. The road flags are set in the <layer> element, either by road='true', which sets them to 0xFFFFFFFF (all ones) or by the roadflags attribute: for example, roadflags='#1F001' in the amenity <layer> states that we wish to use the 'bridge' (0x10000), 'level' (0xF000) and 'tunnel' flags (0x1).


You can create CartoType maps (CTM1 files) containing array objects. These are effectively textures in computer graphics terms: that is, they are rectangular bitmaps which can be projected on to the map and rendered in various ways.

The most common standard layers created in CTM1 files by the tool generate_map_data_type1 are called terrain-shadow and terrain-height-feet.

Terrain shading using the terrain-shadow layer

The terrain-shadow layer contains an eight-bit opacity (alpha) value for each sample, representing the light intensity for a simulated sun in the south-west. You draw it like this, giving a color value to be used when drawing the shadow. You can provide an opacity value as well. For example:

<layer name='terrain-shadow'>
 <shape fill='#446' opacity='0.75'/>

gives light greyish-green terrain shading.


The <defs> section

Objects used more than once can be defined in a <defs> section. An objects must be defined before any layers in which it is used. The following types of objects can be defined in the <defs> section: macros, hachures, icons, patterns and strings.


Macros define named sections of a style sheet for re-use multiple times (full description here).



The hachure used in the example to the right is specified like this:

<hachure id="other-area-shading" width="1pt" interval="4pt" color="brown" opacity="0.4"/>


The <layer> section

A layer is a named set of map objects of a common type, like roads, parks, or stations. Layers are drawn in the order in which sections appear in the style sheet. The <layer> attributes are:

  • name: the name of the layer, which must match the name stored in the map data file or database
  • The roadflags attribute is a mask that specifies how a non-road layer uses road attributes for levels, tunnels, bridges and ramps. It overrides the default value, or any global value set in . You can use lroad='true' as a shortcut for roadflags='#FFFFFFFF'.

    The value '#FFFFFFFF' (the # indicates a hexadecimal number) tells CartoType to use the tunnel, bridge, ramp and level attributes for a non-road layer. The value 0 states that none of these attributes are to be used.

    You can control the the level, tunnel, bridge and ramp settings separately. The road level is kept in bits 12-15 (mask = #F000), the tunnel flag is bit 0 (mask = #1), the bridge flag is bit 16 (mask = #10000) and the ramp flag is bit 6 (mask = #40). For more details, see TRoadType in the API documentation.

Displaying highlighted routes, pushpins, user-created data and other auxiliary data

CartoType applications that do navigation or route-finding need to highlight the current route, display points of interest and addresses selected by the user, and draw other temporary, fast-changing or custom data.

You can do this in a completely flexible way using an auxiliary map database supplied to CartoType at map drawing time. For example, to highlight a route, you could create a memory-resident map database (using the class CMemoryMapDataBase), add the layer "route" to it, and arrange for this database to contain one or more line objects representing the current route, if any.

You then add a layer section for the "route" layer to the style sheet, in a convenient place: probably after all other ordinary layers but before <labelLayer/>.

When a map is drawn and an auxiliary database is supplied as well as the main database, for every layer in the style sheet both databases are searched for matching objects. Objects from the main database are drawn first, then objects from the auxiliary database.


The <labelLayer> section: a special layer for icons and labels

All icons and labels are collected and drawn as a separate layer, which is drawn when the <labelLayer> section is interpreted. Icons are drawn immediately before labels. The <labelLayer> tag has no attributes, so you just place


in the style sheet, at the same level as other layers. Normally it is the last item in the style sheet.

You can achieve various special effects by using more than one <labelLayer/> tag. Each label layer draws all the icons and labels that have been stored since the last label layer if any. One application for this feature is to draw icons and labels for routing information independently of all others, and overlapping them.


The <shape> section in a <layer> controls the drawing of polygons. The <shape> attributes are

  • fill: the color used to fill the polygon; omit this if the polygon is not to be filled
  • border: the color used to draw the border; omit this if no border is wanted; if it is specified, but borderWidth is omitted, the border is drawn one pixel wide
  • borderWidth: the width of the border
  • opacity: the opacity of both the fill and border colors. To set the fill and border opacity values separately, use the #RRGGBB or #RRGGBBAA form for specifying the colors
  • dashArray: a dashed border can be drawn by supplying a list of numbers giving the lengths of the filled-in sections and the gaps between them, in units of the width of the border (given by the borderWidth attribute). For example, the value '1,2' specifies dashes one unit long and gaps two units long. The list of numbers can be any length.


<shape fill="lightgray" border="darkgray" borderWidth="10m" opacity="0.5"/>


The <line> section in a <layer> controls the drawing of lines, the most important of which are roads. Some attributes apply only to roads. The <line> attributes are

  • fill: the color used for the interior of the line
  • border: the color of the borders of the line
  • centerLine: (for roads only) the color of the center line of a road; used for major divided highways; center lines are drawn only if the road is marked as divided in the data
  • width: the width of the line
  • borderWidth: the width of the borders; percentage values refer to the width of the line
  • centerLineWidth: (for roads only) the width of the center line; percentage values refer to the width of the road
  • opacity: the opacity of all features - line, border and center line. To set opacity values separately use the #RRGGBB or #RRGGBBAA form for specifying the colors
  • antiAlias: (allowed values: "true" or "false") if true (the default value) use anti-aliasing to draw the line and its border more smoothly.
  • dashArray: a dashed line can be drawn by supplying a list of numbers giving the lengths of the filled-in sections and the gaps between them, in units of the width of the line. For example, the value '1,2' specifies dashes one unit long and gaps two units long. The list of numbers can be any length.

The <icon> section in a <layer> controls the drawing of icons for point objects. Icons are specified using SVG (Scalable Vector Graphics). The <icon> attributes are:

  • canCombine: if the value is "yes" or "true" multiple instances of this icon are combined (at the time of drawing the map) when too close together. By default icons do not combine. Combined icons are given the attribute _combined=N, where N is the number of original icons combined.
  • canOverlap: if the value is "yes" or "true" the icon can overlap other icons. By default icons are not allowed to overlap. Non-overlapping icons are drawn only if they would not overlap other non-overlapping icons. Overlapping icons are always drawn.
  • color: if present, overrides the natural color of the icon as defined by the SVG code; the icon is drawn in monochrome, colorising it using the specified color
  • colorAttrib: the name of a map object attribute giving the color of the icon; the default map object attribute name is _color. Map objects having the specified attribute use it as the icon color.
  • height: height of the icon; when the icon is rendered it is scaled to this height; if width is not set it is calculated automatically, preserving the aspect ratio of the SVG graphics
  • hotSpotX: x coordinate of the icon's hot spot, which is the point on the icon to be positioned at the point of interest on the map; defaults to 50% of the icon's width; percentage values refer to the width of the icon
  • hotSpotY: y coordinate of the icon's hot spot, which is the point on the icon to be positioned at the point of interest on the map; defaults to 50% of the icon's height; percentage values refer to the height of the icon
  • id: the name by which an icon can be referenced elsewhere in the style sheet. Icons can be referenced anywhere after their definition, whether they are defined in a <defs> section or at their point of first use in a layer.
  • labelX, labelY: x and y coordinates of the label position, relative to the hotspot, if a label is to be drawn on top of the icon (as in US Highway shields). The label is centered on this position. Percentage values refer to the width and height of the icon. The default values are both 0, meaning that the label is drawn over the hotspot. Percentage values refer to the height of the icon.
  • priority: the label priority, with the same meaning as it has in <label>; this attribute allows you to set the label priority if a label consists of an icon only. This attribute works only if it is part of the <icon> element in a <layer>, not if it is specified in the <icon> element in the <defs> section.
  • ref: a reference to an icon defined previously in the <defs> section of the style sheet. If a <ref> is present, the <svg> section is taken from the <icon> in the <defs> section.
  • refAttrib: the name of a map object attribute containing the icon reference; if this is specified, for any map objects having the attribute, the value of the attribute is used to select the <icon> from the <defs> section
  • text: the text for an icon made from a character or characters rather than SVG graphics
  • textAttrib: if not empty, the name of a map object attribute giving the icon text, for use with icons consisting of one or more characters. Overrides text.
  • width: width of the icon; when the icon is rendered it is scaled to this width;  if height is not set it is calculated automatically, preserving the aspect ratio of the SVG graphics

Every <icon> section that does not load a predefined icon using the ref attribute must contain an <svg> section defining the icon using a subset of the Scalable Vector Graphics language. CartoType supports the following SVG graphic elements fully: <g>, <rect>, <circle>, <ellipse>, <line>, <polyline>, <polygon>, and <path>, and partially supports <text>.

Here is a sample <icon> section containing some SVG code to draw a large blue letter H to indicate a hospital:

<icon width='70m,16pt,100pt'>
   <svg width='80' height='100'>
      <g stroke='blue' stroke-width='20'>
         <line x1='10' y1='0' x2='10' y2='100'/>
         <line x1='70' y1='0' x2='70' y2='100'/>
         <line x1='10' y1='50' x2='70' y2='50'/>


Graphics can be used to indicate bridges and ramps (roads connecting limited-access roads like motorways to other roads). They consist of an optional shadow under the bridge, and optional lines at the side of the bridge, with user-definable ends.

Bridge graphics are drawn for roads with the bridge attribute, and ramp graphics are drawn for those with the ramp attribute.


The bridge graphics above are drawn using this style:

<bridge width='45m,2pt' border='dimgrey' borderWidth='14%,1' endPath='l 512 512' maxScale='50000'/>

You use the <bridge> or <ramp> tag inside a < layer> tag (or inside a <condition> in a layer). The <bridge> and <ramp> attributes are:

  • border: the border color
  • shadow: the shadow color
  • width: the width of the bridge (distance between bridge borders)
  • borderWidth: the width of the border strokes
  • shadowWidth: the width of the shadow
  • shadowOffsetX: x offset of the shadow, relative to the road
  • shadowOffsetY: y offset of the shadow, relative to the road
  • maxScale: maximum scale (denominator) at which the bridge graphics are drawn
  • endPath: a path, using SVG path syntax, for strokes appended to the ends of the bridge sides. It gives one of the four ends only: that of the top right end, if the bridge is drawn horizontally. The other ends are generated by transforming the path as needed. The path units are 1024ths of the line width unless modified by unitsPerLineWidth.
  • unitsPerLineWidth: the size of the units in endPath, defined as the number of units equal to the line width. The default value is 1024
  • fill: if present, the fill color for the bridge or ramp; if absent, the bridge or ramp inherits the road color.
  • lineBorder: if present, the line border color for the bridge or ramp; if absent, the bridge or ramp inherits the road's border color.
  • lineWidth: if present, the line width for the bridge or ramp; if absent, the bridge or ramp inherits the road's line width.
  • lineBorderWidth: if present, the line border width for the bridge or ramp; if absent, the bridge or ramp inherits the road's border width.

For all the dimensions, percentages are relative to the width of the road.


Tunnels can be shown by fading the road, drawing it as a dashed line, or both. Graphics can be drawn to show the mouths of the tunnel.


The tunnel named IJ-TUNNEL above shows all three of these methods and is drawn using this style:

<tunnel dashArray='1,1' mouth='dimgrey' mouthWidth='20%,1' mouthPath='m 0 512 a 512 512 0 1 1 0 -1024'/>

You use the <tunnel> tag inside a <layer> tag (or inside a <condition> in a layer). The <tunnel> attributes are:

  • fade: a value in the range 0...1: the amount by which the tunnel is faded compared to a surface-level road. 0 is no fading; 1 makes the tunnel disappear.
  • fill: the fill color. If this is not specified, the road's ordinary fill color is used.
  • border: the border color. If this is not specified, the road's ordinary border color is used.
  • dashArray: the dash array if any. If this is not specified the dash array is inherited from the ordinary road style.
  • maxScale: maximum scale (denominator) at which the tunnel style is used
  • mouthWidth: width of the tunnel mouth symbol; if a percentage is used it is relative to the width of the road. If SVG is used (see below) the width is used as the width and height of the SVG image.
  • mouthPaint: paint used for the tunnel mouth symbol
  • mouthPath: a path, using SVG path syntax, for graphics drawn at tunnel mouths. It specifies the right hand end, relative to the end of the tunnel. The other end is generated by reflection. The path units are 1024ths of the line width unless modified by unitsPerLineWidth.
  • unitsPerLineWidth: the size of the units in endPath, defined as the number of units equal to the line width. The default value is 1024

Using SVG for tunnel graphics

You can use SVG for more complex graphics for tunnel mouths. Do this by embedding an <svg> element inside a <tunne>l element. For example:


<tunnel dashArray='1,1' fill='yellow' mouthWidth='150%' maxScale='25000'>
   <svg x='-750' y='-750' width='1500' height='1500'>
   <linearGradient id="tunnel_gradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="-512" y2="0">
      <stop offset="0" style="stop-color:cornflowerblue"/>
      <stop offset="1" style="stop-color:yellow"/>
   <path stroke='none' fill="url(#tunnel_gradient)" d='m 0 -500 a 500 500 0 1 0 0 1000 z'/>
   <path stroke='brown' fill='none' stroke-width='60' d='m 0 -500 a 500 500 0 1 0 0 1000'/>

which gives this:


In this example the SVG view rectangle is 1500 units wide, centered on (0,0). The rectangle has to be big enough for the graphics to be rotated to any angle without being clipped off. The width of the SVG rectangle is scaled to the width given by mouthWidth, so 1500 units are scaled to 150% of the line width - therefore 1000 SVG units correspond to the width of the line. The graphics are drawn relative to the right hand end of the tunnel, with (0,0) at the end itself, and the x axis aligned to the direction of the tunnel.


You can use the <oneWayArrow> section to define an arrow symbol to be drawn to show the direction of one-way streets. The <oneWayArrow> attributes are:

  • fill: the color used to draw the arrow.
  • border: if specified, a border is drawn in this color.
  • borderWidth: the width of the border in user units: by default, 1024 units are equal to the width of the road, but you can set the unit size to whatever you like using the unitsPerLineWidth attribute (see below).
  • gap: the gap between the left edges of successive symbols, in user units, where 1024 units equal the width of the road (unless modified by unitsPerLineWidth); default value = 1024.
  • isLabel: allowed values are 'yes' and 'no'; the default is 'no'. If the value is 'yes', this attribute treats arrows as labels, which means that they are drawn just after the object's label and will not overlap other labels in the same label layer, or other arrows with the 'isLabel' attribute.
  • maxScale: the maximum scale factor at which the symbols are drawn. The default is 10000.
  • opacity: the opacity used for the fill color.
  • path: a path, defined using SVG path data syntax (the 'd' attribute in the element), defining the arrow or other symbol, in a coordinate system where the direction of the road is from left to right and the width of the road is 1024 units, unless modified by unitsPerLineWidth.
  • unitsPerLineWidth: the number of units in the path definition that are equal to the width of the road. The default value is 1024.
  • width: if svg is used to define the graphics (see below), the width of the graphics. The default value is the width of the road, and percentages also refer to the width of the road.
  • height: if svg is used to define the graphics (see below), the height of the graphics. The default value is the width of the road, or (if the width attribute was used) the same value as the width. Percentages refer to the width of the road.

Example: a broad transparent yellow arrow:

<oneWayArrow path="M 0 50 H 300 L 40 300 H 180 L 505 0 L 180 -300 H 40 L 300 -50 H 0 Z" fill="yellow" opacity="0.5"/>

If you use <oneWayArrow> on a layer other than "road" it is treated as meaning <repeatedSymbol> and the symbols are unconditionally drawn along the path in the direction in which it is defined.

Using SVG for arrows

For more complex arrow graphics, where a filled shape with an optional border is not enough, use SVG, You can do it like this:

 <oneWayArrow gap='2500' opacity='1' isLabel='yes'>
   <svg x='-500' y='-500' width='1000' height='1000'>
      <linearGradient id="XXX" gradientUnits="userSpaceOnUse" x1="-500" y1="0" x2="1000" y2="0">
         <stop offset="0" stop-color='pink'/>
         <stop offset="1" stop-color='red'/>
    <path fill='url(#XXX)' d='M -450 -50 V 50 H 250 L -100 400 H 50 L 450 0 L 50 -400 H -100 L 250 -50 H -450 Z' />

which produces arrows that fade from red to pink along their length.


Repeated symbols and start and end symbols on lines

You can draw repeated symbols along any linear feature. For example, national frontiers are sometimes emphasized using small crosses, and cross-ties can be drawn along railway lines. The syntax is exactly the same as for the oneWayArrow attribute on roads, except that you use repeatedSymbol instead of oneWayArrow. You cannot use both oneWayArrow and repeatedSymbol for a road.

This feature can be used to place arrows along route lines overlaid on the map by means of of an auxiliary map database.

Using SVG for repeated symbols

You can use SVG to define repeated symbols in exactly the same way as for one-way arrows.

Start and end symbols

Symbols can also be specified for the starts and ends of lines. The startSymbol and endSymbol elements work in the same way as oneWayArrow and repeatedSymbol and allow you to create graphics that is drawn at the start or end of a line only. This can be used for arrow-heads, transverse ticks, and the like.


Dashed, truncated and extended lines

Dashed lines are specified using a syntax similar to that of SVG. Use the attribute dashArray in the <line> or <shape> tag. The value is a comma-separated list of dash and gap sizes, relative to the line width (e.g., the value 2 means a dash or gap twice as long as the line width).

The railway line below is drawn as a dashed line with a border, using this code in the style sheet:

<layer name='railway'>
<line width='12m,2pt' border='grey' borderWidth='10%,0.7,2' fill='white' dashArray='5,5'/>
<label font-size='75%,8pt' glow='white' color='black' case='assume-title'/>

White dashes are drawn over a grey border; when there are dashes, the border is also the colour between the dashes.

dashed railway

Truncating and extending lines

Sometimes lines need to be truncated at the start or end or both. For example, a line indicating an airway may need to be shortened so that it doesn't interfere with symbols for navigation aids or position fixes. You can use the truncationAtStart and truncationAtEnd attributes inside <line> or <highlight> elements to shorten lines. All the normal map-related or display-related dimensions can be used, and you can also use percentages, which refer to the width of the line.

Negative values have the effect of extending lines. This can be used to join disconnected sections of highlights drawn along lines (for example, to show traffic density on roads).


Map objects in a single layer often have different attributes. For instance, roads have a RoadType attribute giving the importance of the road, whether it is one-way, whether it has a central divider, etc. These attributes affect the way the road is drawn.

You use <condition> sections inside <layer> to treat objects with differing attributes in different ways. Each <condition> section is like an embedded <layer> section for only those objects with the specified attributes.

A <condition> section inherits all attributes defined in the containing <layer>, unless it is nested inside another condition, in which case it inherits from the containing condition. Conditions may be nested up to 15 levels deep.

You set the actual condition using a style sheet expression in the exp attribute. Expressions test integer and string attributes of map objects; if the expression is true, the object is drawn using the styles given inside the condition element

This is hard to understand without an example. Here is the road layer from a style sheet formerly used by the CartoType demo programs:

<layer name="road">
   <line width="30m" fill="orange" border="black" borderWidth="5%"/>
   <label font-size="75%,8pt"/>
   <condition exp="RoadType in [#400,#BFF]">
      <scale max="50000"/>
      <line width="18m" fill="yellow" border="black" borderWidth="5%"/>
      <label font-size="75%,8pt" maxScale="15000"/>
      <oneWayArrow path="M 0 50 H 300 L 40 300 H 180 L 505 0 L 180 -300 H 40 L 300 -50 H 0 Z" fill="teal" opacity="0.5"/>
   <condition exp="(RoadType bitand #FF00)==#300">
      <scale max="100000"/>
      <line width="22m,2pt" fill="orange" border="black" borderWidth="5%" centerLine="white" centerLineWidth="5%"/>
      <label font-size="75%,9pt"/>
      <oneWayArrow path="M 0 50 H 300 L 40 300 H 180 L 505 0 L 180 -300 H 40 L 300 -50 H 0 Z" fill="teal" opacity="0.5"/>
   <condition exp="(RoadType bitand #FF00)==#200">
      <line width="30m,2pt" fill="tomato" border="black" borderWidth="5%" centerLine="pink" centerLineWidth="5%"/>
      <label font-size="75%,10pt"/>
      <oneWayArrow path="M 0 50 H 300 L 40 300 H 180 L 505 0 L 180 -300 H 40 L 300 -50 H 0 Z" fill="yellow" opacity="0.5"/>
   <condition test="(RoadType bitand #FF00)==#100">
      <line width="45m,2pt" fill="mediumturquoise" border="black" borderWidth="5%" centerLine="white" centerLineWidth="5%"/>
      <label font-size="75%,10pt"/>
      <oneWayArrow path="M 0 50 H 300 L 40 300 H 180 L 505 0 L 180 -300 H 40 L 300 -50 H 0 Z" fill="yellow" opacity="0.5"/>

The first condition has the test "RoadType in [#400,#BFF]", meaning that only roads with road types in the range 400 (hex) to BFF (hex) inclusive are drawn by the specifications in this condition. These are minor and unclassified roads, and are drawn by this style sheet in yellow and not drawn at smaller scales than 1:15000.

Here is an example showing the inheritance of attributes from the containing layer:

<layer name='waterway'>
<label font-style='italic' color='blue' case='assume-title' glow='white'/>
   <!-- RIVER -->
   <condition exp='(Type bitand #FFFF0000)=="riv"'>
   <line width='20m,1pt' fill='skyblue'/>
   <label font-size='75%,8pt' maxScale='1000000'/>
   <!-- CANAL -->
   <condition test='(Type bitand #FFFF0000)=="can"'>
   <line width='8m,1pt' fill='skyblue'/>
   <label font-size='75%,8pt' maxScale='1000000'/>
   <!-- STREAM -->
   <condition test='(Type bitand #FFFF0000)=="str"'>
   <line width='8m,1pt' fill='skyblue'/>
   <label font-size='75%,8pt' maxScale='250000'/>
   <!-- DRAIN -->
   <condition test='(Type bitand #FFFF0000)=="dra"'>
   <line width='4m,1pt' fill='skyblue'/>
   <label font-size='75%,8pt' maxScale='25000'/>

And here is an example of a nested condition:

<condition test='(RoadType bitand #F00)==#400'>
<scale max='400000'/>
<line width='25m,0.5pt' fill='ivory' border='black' borderWidth='8%,0.7,2'/>
<label font-size='70%,8pt' glow='white' color='black' case='assume-title' maxScale='20000'/>
<oneWayArrow path='#arrow' gap='2500' fill='teal' opacity='0.5' isLabel='yes'/>
<bridge width='38m,2pt' border='black' borderWidth='14%,1' endPath='l 512 512' maxScale='50000'/>
<tunnel dashArray='1,1' fill='grey' mouth='black' mouthWidth='20%,1' mouthPath='m 0 512 a 512 512 0 1 1 0 -1024'/>
   <!-- TERTIARY -->
   <condition test='(RoadType bitand #F80)==#400'>
   <line fill='khaki'/>

Here, tertiary roads are exactly the same as unclassified roads except for their fill color, so a lot of unnecessary repetition is avoided. But note that all the nested tests must succeed for this to work. In this example, the test '(RoadType bitand #F00)==#400' selects both unclassified and tertiary roads, while '(RoadType bitand #F80)==#400' selects tertiary only. When the map is drawn, objects are matched to the innermost test that succeeds.


Road types are as defined in the enumerated type CartoType::TRoadType:


enum TRoadType
/** The major road type is held in the high 8 bits. */
EMajorRoadTypeMask = 0xFF00,
/** The minor road type flags are held in the low 8 bits. */
EMinorRoadTypeMask = 0x00FF,
/** Roads of unknown type. */
EUnknownMajorRoadType = 0,
/** Primary road with limited access (motorway, freeway, etc.). */
EPrimaryLimitedAccessRoadType = 0x100,
/** Primary road without limited access: UK 'A' road. */
EPrimaryUnlimitedAccessRoadType = 0x200,
/** Secondary road: UK 'B' road. */
ESecondaryRoadType = 0x300,
/** Local road or town or city street. */
EMinorRoadType = 0x400,
/** Byway: road or track passable only by 4WD vehicles. */
EBywayRoadType = 0x500,
/** Access ramp to limited access road. */
EAccessRampType = 0x600,
/** Service road or access road. */
EServiceRoadType = 0x700,
/** Vehicular Ferry route. */
EVehicularFerryRoadType = 0x800,
/** Passenger-only Ferry route. */
EPassengerFerryRoadType = 0x900,
/** Path or walkway for pedestrians. */
EPathRoadType = 0xA00,
/** Stairway or escalator for pedestrians. */
EStairwayRoadType = 0xB00,
/** A bit flag for roads separated by a central divider. */
ESeparatedRoadTypeFlag = 1,
/** A bit flag for roads in a tunnel. */
ETunnelRoadTypeFlag = 2,
/** A bit flag for underpassing roads. */
EUnderpassRoadTypeFlag = 4,
/** A bit flag for roads with a central railway or tramway. */
ECentralRailLineRoadTypeFlag = 8,
/** A bit flag indicating that the road is one-way in the direction in which it is defined. */
EOneWayForwardRoadTypeFlag = 16,
/** A bit flag indicating that the road is one-way in the reverse direction to that in which it is defined. */
EOneWayBackwardRoadTypeFlag = 32,
/** A bit flag to allow access ramps (links) to be marked as sub-types of a major road type. */
ELinkRoadTypeFlag = 64,
A bit flag to allow a distinction to be made between grades of road, within the major road type.
It allows OpenStreetMap data to distinguish trunk roads from primary roads in a backward-compatible way.
ELowerGradeRoadTypeFlag = 128,


CTM1 map files created from US Census Dept. TIGER data use the attribute 'CFCC', which gives the feature type. CFCC stands for Census Feature Class Code.

The original CFCC codes are made from an uppercase letter followed by a two-digit number. The codes used in CartoType's CTM1 data format are entirely numeric. The uppercase letter is replaced by one or two digits, using the range 1...26 for the letters A...Z. Thus A08 (road with rail line in center) becomes 108, and X00 (feature not yet classified) becomes 2400.

For roads, CFCC codes are translated into CartoType road types, which are explained in the previous section.

There is a list of CFCC codes at (in Chapter 3).


CTM1 map files created from OpenStreetMap data (OSM files in XML format) use the attribute Type. This 32-bit value contains a value in its upper 15 bits that encodes a three-letter tag that is a mnemonic for one of the tags used in the OSM file. The encoding is done like this: for the purpose of explanation here is a C macro that takes three lower-case letters:

 #define OsmType(A,B,C) ((((A)-'a') << 27) | (((B)-'a') << 22) | (((C)-'a') << 17)) 

However, you don't have to work with the actual numeric values because you can use the three-letter tag on the right hand side of a test in a condition.

Here are the OpenStreetMap types that are currently defined and used by generate_map_data_type1.

EAbandoned = OsmType('a','b','a'),
EAerodrome = OsmType('a','e','r'),
EAirfield = OsmType('a','i','r'),
EAirportGate = OsmType('a','g','t'),
EAirportHoldingPosition = OsmType('a','h','p'),
EAllotments = OsmType('a','l','l'),
EAlpineHut = OsmType('a','l','p'),
EAmbulanceStation = OsmType('a','m','b'),
EApron = OsmType('a','p','r'),
EAerialWayPylon = OsmType('a','p','y'),
EArtwork = OsmType('a','r','t'),
EAerialWayStation = OsmType('a','s','t'),
EAirTerminal = OsmType('a','t','e'),
EAtm = OsmType('a','t','m'),
EAttraction = OsmType('a','t','t'),
EBabyHatch = OsmType('b','a','b'),
EBarracks = OsmType('b','a','r'),
EBasin = OsmType('b','a','s'),
EBay = OsmType('b','a','y'),
EBeach = OsmType('b','e','a'),
EBeacon = OsmType('b','e','c'),
EBedAndBreakfast = OsmType('b','e','d'),
EBench = OsmType('b','e','n'),
EBank = OsmType('b','n','k'),
EBoatyard = OsmType('b','o','a'),
EBoundary = OsmType('b','o','u'),
EBorough = OsmType('b','o','r'),
EBicycleParking = OsmType('b', 'p', 'k'),
EBicycleRental = OsmType('b', 'r', 'e'),
EBridleway = OsmType('b','r','i'),
EBrownField = OsmType('b','r','o'),
EBusStop = OsmType('b','s','p'),
EBusStation = OsmType('b','s','t'),
EBufferStop = OsmType('b','u','f'),
EBuilding = OsmType('b','u','i'),
EBunker = OsmType('b','u','n'),
ECabin = OsmType('c','a','b'),
ECafe = OsmType('c','a','f'),
ECampSite = OsmType('c','a','m'),
ECanal = OsmType('c','a','n'),
ECaveEntrance = OsmType('c','a','v'),
ECableCar = OsmType('c','c','r'),
ECableDistributionCabinet = OsmType('c','d','c'),
ECemetery = OsmType('c','e','m'),
EChairLift = OsmType('c','h','a'),
ECheckPoint = OsmType('c','h','e'),
EChalet = OsmType('c','h','l'),
ECivilBoundary = OsmType('c','i','b'),
ECinema = OsmType('c','i','n'),
ECity = OsmType('c','i','t'),
ECliff = OsmType('c','l','f'),
EClinic = OsmType('c','l','i'),
ECommercial = OsmType('c','m','r'),
ECoastline = OsmType('c','o','a'),
ECollege = OsmType('c','o','l'),
ECommon = OsmType('c','o','m'),
EConstruction = OsmType('c','n','s'),
EConservation = OsmType('c','n','v'),
EContinent = OsmType('c','o','n'),
ECounty = OsmType('c','o','u'),
ECarPark = OsmType('c','p','k'),
ECarRental = OsmType('c','r','e'),
ECrossing = OsmType('c','r','o'),
ECountry = OsmType('c','r','y'),
ECarSharing = OsmType('c','s','h'),
ECarWash = OsmType('c','w','a'),
ECaravanSite = OsmType('c','v','n'),
ECycleway = OsmType('c','y','c'),
EDam = OsmType('d','a','m'),
EDangerArea = OsmType('d','a','n'),
EDentist = OsmType('d','e','n'),
EDisused = OsmType('d','i','s'),
EDitch = OsmType('d','i','t'),
EDock = OsmType('d','o','c'),
EDrain = OsmType('d','r','a'),
EDragLift = OsmType('d','r','g'),
EDoctors = OsmType('d','r','s'),
EDistrict = OsmType('d','s','t'),
EElectricVehicleCharging = OsmType('e','v','c'),
EFarm = OsmType('f','a','r'),
EFarmYard = OsmType('f','a','y'),
EFell = OsmType('f','e','l'),
EFerryTerminal = OsmType('f','e','t'),
EFastFood = OsmType('f','f','d'),
EFireExtinguisher = OsmType('f','i','e'),
EFireFlapper = OsmType('f','i','f'),
EFireHose = OsmType('f','i','h'),
EFireStation = OsmType('f','i','s'),
EFireHydrant = OsmType('f','i','y'),
EFootpath = OsmType('f','o','o'),
EForestry = OsmType('f','o','r'),
EFuel = OsmType('f','u','e'),
EFunicular = OsmType('f','u','n'),
EGarages = OsmType('g','a','r'),
EGate = OsmType('g','a','t'),
EGarden = OsmType('g','d','n'),
EGenerator = OsmType('g','e','n'),
EGreenHouse = OsmType('g','h','o'),
EGlacier = OsmType('g','l','a'),
EGolfCourse = OsmType('g','o','l'),
EGondola = OsmType('g','o','n'),
EGoodsAerialWay = OsmType('g','o','o'),
EGrass = OsmType('g','r','a'),
EGreenField = OsmType('g','r','e'),
EGritBin = OsmType('g','r','b'),
EGraveYard = OsmType('g','r','y'),
EGuestHouse = OsmType('g','u','e'),
EHalt = OsmType('h','a','l'),
EHamlet = OsmType('h','a','m'),
EHangar = OsmType('h','a','n'),
EHeath = OsmType('h','e','a'),
EHelipad = OsmType('h','e','l'),
ERailwayHalt = OsmType('h','l','t'),
EHospital = OsmType('h','o','s'),
EHotel = OsmType('h','o','t'),
EHostel = OsmType('h','s','t'),
EIndustrial = OsmType('i','n','d'),
EInformation = OsmType('i','n','f'),
EIsland = OsmType('i','s','l'),
EIsolatedDwelling = OsmType('i','s','o'),
EKindergarten = OsmType('k','i','n'),
ELandFill = OsmType('l','a','n'),
ELand = OsmType('l','n','d'),
ELevelCrossing = OsmType('l','e','v'),
ELibrary = OsmType('l','i','b'),
ELightRail = OsmType('l','i','r'),
ELocality = OsmType('l','o','c'),
ELockGate = OsmType('l','o','k'),
EMaritimeBoundary = OsmType('m','a','b'),
EMall = OsmType('m','a','l'),
EMarsh = OsmType('m','a','r'),
EMeadow = OsmType('m','e','a'),
EMilitary = OsmType('m','i','l'),
EMixedAerialWay = OsmType('m','i','x'),
EMonorail = OsmType('m','o','n'),
EMotel = OsmType('m','o','t'),
EMinorPowerLine = OsmType('m','p','l'),
EMiniatureRailway = OsmType('m','r','y'),
EMud = OsmType('m','u','d'),
EMunicipality = OsmType('m','u','n'),
EMuseum = OsmType('m','u','s'),
ENarrowGauge = OsmType('n','a','r'),
ENatureReserve = OsmType('n','a','t'),
ENavalBase = OsmType('n','a','v'),
ENationalParkBoundary = OsmType('n','p','b'),
ENeighborhood = OsmType('n','e','i'),
ENursingHome = OsmType('n','u','r'),
EOrchard = OsmType('o','r','c'),
EPrecisionApproachPathIndicator = OsmType('p','a','p'),
EPark = OsmType('p','a','r'),
EPublicBuilding = OsmType('p','b','u'),
EPostBox = OsmType('p','b','x'),
EPeak = OsmType('p','e','a'),
EPharmacy = OsmType('p','h','a'),
EPhone = OsmType('p','h','o'),
EPicnicSite = OsmType('p','i','c'),
EParkingEntrance = OsmType('p','k','e'),
EParking = OsmType('p','k','g'),
EParkingSpace = OsmType('p','k','s'),
EPlantNursery = OsmType('p','l','a'),
EPlatform = OsmType('p','l','f'),
EPlaceOfWorship = OsmType('p','l','w'),
EPlayground = OsmType('p','l','y'),
EPoliticalBoundary = OsmType('p','o','b'),
EPostOffice = OsmType('p','o','f'),
EPolice = OsmType('p','o','l'),
EProtectedArea = OsmType('p','r','a'),
EPreservedRailway = OsmType('p','r','y'),
EPowerSubStation = OsmType('p','s','s'),
EPub = OsmType('p','u','b'),
EPowerLine = OsmType('p','w','l'),
EPowerStation = OsmType('p','w','s'),
EQuarry = OsmType('q','a','r'),
ERail = OsmType('r','a','i'),
ERange = OsmType('r','a','n'),
ERapids = OsmType('r','a','p'),
ERecycling = OsmType('r','c','y'),
ERecreationGround = OsmType('r','e','c'),
ERegion = OsmType('r','e','g'),
ERetail = OsmType('r','e','t'),
ERiver = OsmType('r','i','v'),
ERailway = OsmType('r','l','y'),
ERoundHouse = OsmType('r','o','u'),
EResidential = OsmType('r','s','d'),
ERestaurant = OsmType('r','s','t'),
EReservoir = OsmType('r','s','v'),
ERunway = OsmType('r','u','n'),
ERiverBank = OsmType('r','v','b'),
ESaltPond = OsmType('s','a','l'),
ESand = OsmType('s','a','n'),
ESchool = OsmType('s','c','h'),
EScree = OsmType('s','c','r'),
EScrub = OsmType('s','c','b'),
ESea = OsmType('s','e','a'),
EStateEmergencyServiceStation = OsmType('s','e','s'),
ESportsCenter = OsmType('s','p','o'),
ESportsPitch = OsmType('s','p','p'),
ESpring = OsmType('s','p','r'),
ESportsTrack = OsmType('s','p','t'),
EState = OsmType('s','t','a'),
ESteps = OsmType('s','t','e'),
EStadium = OsmType('s','t','m'),
ERailwayStation = OsmType('s','t','n'),
EStation = OsmType('s','t','n'), // deliberate duplicate
EStone = OsmType('s','t','o'),
EStopPosition = OsmType('s','t','p'),
EStream = OsmType('s','t','r'),
ESuburb = OsmType('s','u','b'),
ESubwayEntrance = OsmType('s','w','e'),
ESwimmingPool = OsmType('s','w','i'),
ESubway = OsmType('s','w','y'),
ETaxi = OsmType('t','a','x'),
ETheatre = OsmType('t','h','e'),
EThemePark = OsmType('t','h','p'),
EToilet = OsmType('t','o','i'),
ETown = OsmType('t','o','w'),
ETurningCircle = OsmType('t','c','i'),
ETurningPoint = OsmType('t','p','t'),
ETram = OsmType('t','r','a'),
ETree = OsmType('t','r','e'),
ETrafficSignals = OsmType('t','r','f'),
ETramStop = OsmType('t','r','s'),
ETurnTable = OsmType('t','u','r'),
ETower = OsmType('t','w','r'),
ETaxiway = OsmType('t','w','y'),
EUniversity = OsmType('u','n','i'),
EVisualApproachSlopeIndicator = OsmType('v','a','s'),
EVillageGreen = OsmType('v','i','g'),
EVillage = OsmType('v','i','l'),
EVineyard = OsmType('v','i','n'),
EViewPoint = OsmType('v','i','w'),
EVolcano = OsmType('v','o','l'),
EWater = OsmType('w','a','t'),
EWeir = OsmType('w','e','r'),
EWetland = OsmType('w','e','t'),
EWindsock = OsmType('w','i','s'),
EWood = OsmType('w','o','o'),
EZoo = OsmType('z','o','o')