Search for content

Styling the OSM Map

The OSM Vector Maps service provides highly configurable map styles. You have the choice of using one of our predefined styles or build your own style.


The visual appearance of your map is defined by an array of layer definitions in JSON format. Each layer represents what data to draw, its order to draw it in and how to style the data. The array of layers has to be included in your style.json as described below.

We provide a ready to use layer set to start with. You can simply download it from the following URLs and integrate it in your own map project.

The "Standard" layer style

open street map berlin

This is our default style and focused on the road network.

The MapLibre style document (style.json)

The style document contains information on how the map is rendered and from which resources. It is the standard way MapLibre configures the renderer. A very detailed description on how this JSON file works can be found on the MapLibre GL js API documentation page.

A sample style.json looks like this:

 "version": 8,
 "name": "Basic",
 "pitch": 0,
 "sources": {
   "ptv": {
     "type": "vector",
     "tiles": ["{z}/{x}/{y}"],
     "minZoom": 0,
     "maxzoom": 17
 "sprite": "",
 "glyphs": "{fontstack}/{range}.pbf",
  • The tiles property describes the URL of the tile server provided by PTV Developer. 
  • The sprite property defines the address where to fetch the sprite sheet. This sheet defines all kinds of icons like highway shields and so on. 
  • The glyphs entry is the URL to the fonts which are needed for rendering the map labels and street names. 
  • The layers section describes how the map should be rendered. Every map element provided in a vector tile can be customized and styled with a layer definition. 

Layer concept

Each single layer definition carries information of how to render a map element from a vector tile. The layers are rendered in the order as they are defined in your style.json. So you should, for example, first define a layer for a map background and after this a layer for streets.

This is an example for a layer defining how to render a highway:

   "id": "TSP_RoadHighway_Inner",
   "type": "line",
   "source": "ptv-osm",
   "source-layer": "MotorwayLayer",
   "minzoom": 7,
   "filter": [
        ["==", "feature", "highway_motorway"],
        ["==", "feature", "highway_trunk"]
   "layout": {
     "line-cap": "butt",
     "line-join": "round",
     "visibility": "visible"
   "paint": {
     "line-color": { "stops": [[7, "rgba(255, 163, 0, 1)"], [8, "rgba(255, 203, 107, 1)"]] },
     "line-width": { "base": 1.4, "stops": [[6, 1], [8, 2], [10, 3], [12, 5], [14, 10], [21, 60]] },
     "line-opacity": 1


A layer definition generally consists of many parameters, here we show you the most common parameters we use in our examples:

  • id: An unique name for the layer.
  • type: The rendering type of the layer.
  • Common types are
    • "background"
    • "fill" for areas or polygons
    • "line" for stroked lines like streets or country borders
    • "symbol" for text labels or icons
    • "fill-extrusion" for 3d extruded objects like buildings
  • source: The name of the vector tile source. 
    For our PTV OSM vector format, this is always "ptv-osm". You will need to specify a source for all layers that visualize data from vector tiles. Only layer types like "background" or "sky" don't need a source.
  • source-layer: The name of the layer to use from the vector tile source. 
    Please have a look further below for a list of our PTV OSM vector format source layers.
  • minzoom and maxzoom: The optional minimum and maximum zoom levels for which the layer should be visible.
  • filter: An optional expression specifying conditions when to display the layer. 
    Please consult the Mapbox GL JS documentation about filters for detailed information.
  • layout: Optional information about how to lay out the layer dependent on its type. 
    Please consult the Mapbox GL JS documentation about layouts for detailed information.
  • paint: Optional properties on how to paint the layer dependent on its type. 
    Please consult the Mapbox GL JS documentation about paint for detailed information.

Layers in detail


Some of the linear and polygonal layers (currently backgrounds and transport layers) are provided with several steps of generalized geometries. Generalization simplifies geometries for the purpose of reducing data. The benefits are smaller tile sizes and better rendering performance. 
Depending on the zoom level of your map view, you will receive the geometries in full detail (when zoomed in very close) or more and more generalized (when zooming out further and further). You don't have to take care of this, it is an implicit feature of the PTV vector format.

Source layers

The PTV vector format supports 16 different types of source layers. Each source layer type contains geometries (in the form of points, lines or polygons) and various other attributes to further define the purpose of the layer like what kind of data is represented or the name of a data element. These attributes are deduced from the key-value pair attribute format of OSM map elements. Names (with the key name) and values are given in the language used locally at the place of the map element.


The layer type "WaterLayer" contains all kinds of rivers and lake background areas.

The geometries of this layer are of type 'Polygon'. The following key-value pairs are defined:

nameThe name of the given background in the local language of the element.


The layer type "BackgroundLineLayer" contains all kinds of rivers and streams which are displayed as lines.

The geometries of this layer are of type 'Line'.


The layer type "LandscapeLayer" contains several kinds of land backgrounds.

The geometries of this layer are of type 'Polygon'. The following key-value pairs are defined:

landusefell, wasteland, forestry, leisure, garden, highway, range, shrubs, cemetery, industrial, reservoir, spoil_area, winter_sports, orchard, greenfield, industrial;forest, residential, forest, yes, marsh, hill, service, farmland, prairie, administrative, recreation_ground, fixme, pasture, nature reserve, basin, wood, turbuary, surplus, wetland, events, grave_yard, pond, APC Ground, public_beach, shelterbelt, animal_keeping, bare_ground, farmyard, nature_reserve, conservation;meadow, greenhouse_horticulture, conservation, disused:farmyard, farm, allotments, disturbed, special_use, retail, proposed, fallow land, dummy, plantation, danger_area, landfill, field or pasture, mine_spoils, fo\, mine_spoils_recultivated, railway, Urban Open Land, vineyard, peat_cutting, agriculture, common, park, turbary, logging, mata nativa, stripmine, protective_green_area, traffic_island, garages, animal_breeding, water_wellfield, zone_of_alienation, homeless camp, natural reserve, construction, greenland, heath, education, churchyard, decoration, water, forest;natural_reserve, civil, proving_ground, natural_reserve, aquaculture, rough_pasture, flower, recreation, military, land, forest;meadow, forfor, apiary, flowerbed, fieldmargin, brownfield, natural, mountain, depot, abandoned:farmyard, virgin prairie, reservoir_watershed, saltpond, religious, street_green, duck_decoy, trees, Worship, quarry, ruins, plant_nursery, scrub, institutional, commercial, salt_pond, grass, meadow, village_green, peat_bog, nature, planting, grassland, reindeer_lichen, wood_pasture, public_facility
naturalglacier, water;wood, fell, sinkhole, fence, island, bois de Gâs des Osmeaux, heath, stone, islet, forest, Sloth Park, yes, tree, dune, jungle, hill, shrubbery, rock, water, wetland;water, tree_group, woodland, scrubs;sinkhole, peninsula, wood, Birkewsierbësch, managed forest, viischte Mëssel, Steerueder, wetland, Ak, sand, reserve, beach, bare_rock, cliff, bush, reef, coastline, ridge, mountain, wood;scrub, hënneschte Mëssel, scurb, olive grove, her, Maaschleedchen, valley, driveway, Rengelsburen, moor, peak, trees, clearcut, Derrygid Wood, f, shrub, bare_rock;wood;scrub, landform, shingle, Bois sacré, mixed, scrub, scree;heath, Groussheck, no, earth_bank, grass, tree_row, meadow, cape, tree:group, mud, grassland, tundra, scree
nameThe name of the given background in the local language of the element.


The layer type "BuiltupLayer" contains all kinds of builtup backgrounds.

  • The geometries of this layer are of type 'fill'.
  • Valid feature types are:
landusepublic_facility, amenity, agriculture, civic, common, institution, research, park, utility, cemetery, garages, industrial, construction, greenfield, orchard, forest, residential, education, churchyard, yes, farmland, University, research_institute, civil, recreation_ground, aquaculture, fairground, educational, recreation, public_services, school, military, observatory, public, animal_keeping, schoolyard, playground, civic_admin, university, farmyard, brownfield, healthcare, 新区学校, greenhouse_horticulture, conservation, religious, farm, allotments, hospital, plant_nursery, retail, gas, community_services, haelthcare, institutional, commercial, grass, meadow, village_green, government, place_of_worship, landfill
nameThe name of the given background in the local language of the element.


The layer type "OceanLayer" contains all ocean background.

  • The geometries of this layer are of type 'fill'.
  • No features


The layer type "BorderLayer" contains all country borders, no state borders.

  • The geometries of this layer are of type 'Line'.
  • No features


The layer type "HighwayLayer" contains all highways, freeways, turnpikes and so forth.

  • The geometries of this layer are of type 'Line'.

  • Valid feature types are:

    featurehigway_trunk, highway_primary 


The layer type "TransportLayer" contains all transport related elements, which are mainly streets but also foot paths or railways.

  • The geometries of this layer are of type 'Line'.

  • Valid feature types are:

    featureAbout 260 attributes characterizing as highways or railways. Examples are highway_track, highway_residential or railway_monorail. See the external OSM taginfo page for more information. 
    nameThe name of the given line geometry in the local language of the element.
    shield_nameThe name or number on the corresponding road sign of this street.
    shield_idThe type of road sign for this street. See chapter Spritesheets for more information.
    shield_textcolThe color of the road sign text.

{Tunnel, Bridge}Layer

The layer types "TunnelLayer" and "BridgeLayer" contains all tunnels and bridges. In OSM a broad understanding of tunnels and bridges has been evolved. All roads and ways which are covered or roofed fall under this category.

  • The geometries of this layer are of type 'Line'.
  • Valid feature types are:
featureThe name of the corresponding feature in the Transport_Layer or Motorway_Layer
nameThe name of the given line geometry in the local language of the element.

Layers in our examples

If you have a closer look on our predefined layer styles, you will notice that they have a naming scheme for each layer in common.

  • All layers containing background areas or lines start with the prefix "BKG_" followed by the rough name of the background type.
  • All layers containing streets or other public transport routes start with the prefix "TSP_" followed by the rough name of the transport type. Sometimes they are suffixed with "_Inner", "_Outer" or "_Dashed" to emphasize that the layer represents the inner or outer street parts (that have to be drawn separately) or if it has to be painted dashed.
  • All layers containing labels start with the prefix "LBL_" followed by the rough name of the label type.
  • Finally, the building layer is prefixed with "BLD_".


A spritesheet is an image that consists of several smaller images. We use a single spritesheet for all images that we want to display on our map. The images are mainly the colored backgrounds of road signs or road markings like the arrow marking a one way street.

You can find our example spritesheet here:

Additionally, there is a description file in json format, that tells you which images are contained in the spritesheet, along with their sizes and positions. The MapLibre renderer can handle this json file and extract the single images. 
The corresponding json file is here:

Encoding of road sign names

You will find various road sign images in our spritesheet. Their names all start with the prefix "roadsign-", followed by a block of four digits, followed by one last digit.

Syntax: roadsign-XXYZ-L

  • The first two of the four digits (XX) represent the shape of the road sign.
  • The third digit (Y) represents the background color of the road sign.
  • The fourth digit (Z) represents the border color of the road sign.
  • The last separated digit (L) represents the length of the text that should fit into this road sign

Shape encoding

11Hexagon (e.g. German Autobahn)
12Badge (e.g. American Highway)
15Pentagon (e.g. Argentinian Highway)
16Pointed badge
17Rounded badge

Color encoding


Generating your own spritesheet

You can generate your own spritesheet by assembling all your needed images in SVG format in one directory. Then you use the tool spritezero-cli to generate a single spritesheet image and description file of this directory.

Get spritezero-cli via npm:

npm install -g @mapbox/spritezero-cli


Examples for restyling

All of the following examples are based on our default layer style "Standard".

Change width and colors of highways

To change how the renderer should paint a highway, you first have to locate the highway layer in the json style file. A highway is a transport type layer, so the name prefix is "TSP_". If you search through all TSP_* layers, you will stumble over two layers named "TSP_RoadHighway_Outer-color" and "TSP_RoadHighway_Inner".

The "TSP_RoadHighway_Outer-color" layer will be drawn first and is responsible for the outer part of a highway. Colors and widths are defined in the paint properties:

"paint": {
 "line-color": {
   "stops": [[4, "rgba(243, 238, 233, 1)"], [5, "rgba(255, 163, 0, 1)"]]
 "line-width": {
   "base": 1.4,
   "stops": [ [5, 1],[6, 2],[7, 3],[8, 4],[10, 6], [12, 8], [14, 14],[21, 64]]
 "line-opacity": 1


The outer part of the highway is nearly white (rgba(243, 238, 233, 1)) from zoom level 0-4, from zoom level 5 onward it is faded to yellow (rgba(255, 163, 0, 1)). If you like to change its outer color to red, simply replace both colors with a subtle and a strong red:

"line-color": {
 "stops": [[4, "rgba(190, 133, 133, 1)"], [5, "rgba(255, 0, 0, 1)"]]

The "TSP_RoadHighway_Inner" will be drawn after and over the outer layer. You can change its colors accordingly.

To change the thickness of highways, you have to modify the values of the line-width property. The thickness is defined for eight zoom levels in our example. We want to double the widths of the outer part of the highway, so we double each thickness value:

"line-width": {
 "base": 1.4,
 "stops": [ [5, 2],[6, 4],[7, 6],[8, 8],[10, 12], [12, 16], [14, 28],[21, 128]]


Styling with Maputnik

A simple way to style your map is to use the Maputnik Editor:

Simply upload an existing style (that includes your PTV Developer API Key) from your computer. Maputnik allows you to interactively manipulate all layers and their attributes and shows your changes live on a map view.

Add the API Key to the style

To be able to retrieve vector tiles from the PTV Developer service, you have to provide your API Key with the style. Otherwise, Maputnik will not be able to show any map tiles.

Add the API Key as a query parameter to the tiles URL:

"ptv-osm": {
    "type": "vector",
    "tiles": [
    "attribution": "©2023, PTV Group, OpenStreetMap contributors",
    "minZoom": 0,
    "maxzoom": 14,
    "parse_json": true