Custom map styles
Our built-in styles (infrastructure, speed, electrification, signalling, gauge, load,
source) colour the network one way each. To change colours, hide or reorder layers, add labels
or put the tracks on a basemap, save a custom style in the dashboard. It is served at
https://tiles.routing.gleisklar.de/styles/u/{id}.json?key=rr_pk_…with the current tile URLs and your key filled in, so a map needs nothing else.
Create a style
Section titled “Create a style”- In the dashboard open styles and pick the built-in style to start from.
- The editor shows the style’s layers, top layer first, next to a live preview:
- switch layers on and off, move them up and down, remove them;
- change every colour of a layer: the colours in a style’s expressions are listed one by one, named after the legend (“15 kV 16.7 Hz”, “main line”, …);
- change line widths, circle sizes, text sizes and opacity where they are plain numbers;
- add labels: line numbers, track names or maximum speeds along the tracks, signal names, platform numbers. Label layers use our fonts (Noto Sans);
- basemap under the tracks: our own basemap in one of five flavours, or none (see below).
- The JSON tab has the whole document for anything the panel doesn’t cover (filters, expressions, zoom ranges, a third-party basemap). apply checks it.
- save. Maps that load the style URL get the change within a minute.
Styles belong to your account; up to 50 per account.
Load it in MapLibre
Section titled “Load it in MapLibre”The style URL works directly with a publishable key (rr_pk_…):
const map = new maplibregl.Map({ container: "map", style: "https://tiles.routing.gleisklar.de/styles/u/k3xq….json?key=rr_pk_…",});or with the SDK (npm i @quebi/rail-api), which also works with a secret key on a server:
import { railHostedStyle } from "@quebi/rail-api/maplibre";
const hosted = await railHostedStyle("k3xq…", { key: "rr_pk_…" });new maplibregl.Map({ container: "map", style: hosted.style, transformRequest: hosted.transformRequest, // sends a secret key as a header, never in URLs attributionControl: hosted.attributionControl, // keeps the ODbL credit visible});The key must
- belong to the account that saved the style (any other key gets 404, as for a style that doesn’t exist),
- have the tiles scope,
- for a publishable key, list the page’s origin, as for tiles.
Each load of the style counts as one request (endpoint styles, product tiles); the tiles count
as usual. Responses carry an ETag and Cache-Control: private, max-age=60. Tile URLs contain
the data version, which changes with the nightly build: when tiles answer 404, load the style
again.
Edit in Maputnik
Section titled “Edit in Maputnik”Maputnik edits any part of a style visually.
- Add
https://maplibre.orgto the allowed origins of one of your publishable keys (dashboard, api keys): Maputnik runs there and loads the style and the tiles with the key. - In Maputnik choose Open → Load from URL and paste the style URL (with
?key=). - Edit, then Save → Download.
- In the dashboard open the style, choose import JSON, check the preview and save (or import it as a new style on the styles page).
On import the tile URLs of our API (with your key and the data version in them) are turned back into our source, and the URLs of our basemap, its fonts and sprites into their placeholders, so neither is stored. You can also download the JSON from the editor, edit it in any text editor and import it again.
What a style may contain
Section titled “What a style may contain”A style is a MapLibre style (version 8). On saving it is checked against the style spec and these rules; the editor lists every problem with its place in the document:
- Our data is the source
{ "type": "vector", "url": "railroute://tiles" }; the server puts in the tile URLs. Its tile layers:tracks,signals,switches,level_crossings,platforms. A style has to use it. - Our basemap is the source
{ "type": "vector", "url": "railroute://basemap" }, with"glyphs": "railroute://fonts/{fontstack}/{range}.pbf"and"sprite": "railroute://sprites/<flavor>"(light,dark,white,grayscale,black; also as theurlof an entry in a sprite list). The server puts in the API’s URLs. - Other sources,
glyphsandspritemust behttps://URLs on an allowed host:tiles.openfreemap.org,api.maptiler.com,api.protomaps.com,protomaps.github.io,tiles.stadiamaps.com,demotiles.maplibre.org. That covers the common hosted basemaps and their fonts; keys for them (e.g. a MapTiler key) are yours, in their URLs. - GeoJSON may be inline; GeoJSON, raster, image and video sources by URL only from allowed hosts.
data:URLs only for image sources and GeoJSON, up to 8 KB.- Size: at most 512 KB.
The server checks the source rules again whenever it serves a style. Our source always carries the OpenStreetMap (ODbL) and RINF attribution; keep MapLibre’s attribution control visible.
A basemap under the tracks
Section titled “A basemap under the tracks”Our API serves a basemap of its own: land, water, roads, places and their labels from
OpenStreetMap, with the fonts and icons it needs, so a map loads nothing from a third party. In
the editor pick a flavour under basemap under the tracks (light, dark, white,
grayscale, black, the Protomaps styles); its layers
go below all others and the list hides them unless you ask for them. Picking another flavour
replaces them, none takes them out again. In the document that is
"sources": { "basemap": { "type": "vector", "url": "railroute://basemap" }, "railroute": { "type": "vector", "url": "railroute://tiles" }},"glyphs": "railroute://fonts/{fontstack}/{range}.pbf","sprite": "railroute://sprites/grayscale"then the Protomaps layers with "source": "basemap" (tile layers earth, water, landuse,
landcover, roads, transit, buildings, boundaries, places, pois) before the rail-…
layers. Basemap tiles count as endpoint basemap; fonts and sprites are free. With the SDK,
railBaseStyle("speed", { basemap: "light" }) gives such a document to start from.
A third-party basemap works too: its source, fonts and sprite from one of the allowed hosts
above (e.g. OpenFreeMap’s https://tiles.openfreemap.org/planet), its layers below ours. Check
its terms of use; tile.openstreetmap.org is not allowed.