Shortbread Schema Extensions
Status Experimental | Last updated 2026-06-19
Introduction
VersaTiles generates its OpenStreetMap vector tiles with Planetiler using the Shortbread schema.
That profile can emit a handful of features that are not part of the official Shortbread 1.0/1.1 schema. We call them experiments: they make richer maps possible (3D buildings, localized labels, …), but they may change, be renamed, or be removed, and some are being proposed upstream. They are kept deliberately separate so the default output stays spec-conformant.
Two principles hold for every experiment:
- Opt-in. Nothing beyond the spec is emitted unless explicitly enabled. A bare build is strict Shortbread.
- Additive. Experiments only add attributes or features to existing layers — layer names, geometry types and zoom ranges are unchanged, and the
buildingslayer still carries the spec'sdummy=1. A consumer that only understands base Shortbread can ignore the extras safely.
This page documents the schema contract (what extra attributes/features exist and how to use them in a style). It is not the build manual — see the profile README for how tiles are generated.
Enabling experiments
Experiments are switched on at tile-generation time with the --shortbread_experiments argument — a comma-separated list of all, none, or specific tokens:
# strict spec (default — nothing beyond Shortbread)
java -jar planetiler.jar shortbread --area=monaco
# everything on
java -jar planetiler.jar shortbread --area=monaco --shortbread_experiments=all
# a specific subset
java -jar planetiler.jar shortbread --area=monaco \
--shortbread_experiments=building_heights,building_parts,locale_namesThe default is none. The token registry is defined in Experiment.java and is the source of truth.
For map authors: experiments are chosen by whoever builds the tiles (versatiles-generator), not by the map client. The published VersaTiles tiles ship a fixed set — check the generator configuration to see which. There is currently no per-tile metadata flag indicating which experiments were enabled (see Future).
Experiments
| Token | Layer(s) | Adds |
|---|---|---|
building_heights | buildings | height, min_height |
building_parts | buildings | building:part polygons + hide_3d (implies building_heights) |
locale_names | all label layers | geofenced name_<lang> fallback |
island_labels | place_labels | labels for islands mapped as polygons |
address_details | addresses | unit, block |
bridge_names | bridges | name (and name_<lang>) |
building_heights
Adds two integer-metre attributes to buildings for 3D extrusion, derived like OpenMapTiles:
height— fromheight/building:height, elsebuilding:levels(orlevels) × 3.66 m, else a 5 m default.min_height— frommin_height/building:min_height, elsebuilding:min_level× 3.66 m. Emitted only when greater than 0.- Implausible values (≥ 3660 m, almost always tagging errors) are dropped.
The spec dummy=1 is still present. Upstream discussion: shortbread-docs #77.
Style usage (MapLibre fill-extrusion):
{
"type": "fill-extrusion",
"source-layer": "buildings",
"paint": {
"fill-extrusion-height": ["get", "height"],
"fill-extrusion-base": ["coalesce", ["get", "min_height"], 0]
}
}building_parts
Implements OSM Simple 3D Buildings so multi-part buildings extrude correctly. It is meaningless without heights, so it implies building_heights.
- Emits
building:partpolygons into thebuildingslayer — but only those carrying height information (a bare part with no height would just add overlapping 2D footprints). - The footprint of a building that has parts must not be extruded under them. The
outline-role member of atype=buildingrelation is taggedhide_3d=true.
Style usage: extrude every buildings feature except hide_3d:
"filter": ["!=", ["get", "hide_3d"], true]Known gap (as in OpenMapTiles): parts that merely overlap a footprint with no
type=buildingrelation cannot be detected cheaply, so those footprints do not gethide_3d.
locale_names
Refines name localisation. Base Shortbread emits name and name:<code> from their own OSM tags only. With locale_names, a feature tagged with just name, located inside a country whose default language is <lang>, also receives name_<lang> (e.g. name_de inside Germany).
- Backed by a country → language lookup built from the Natural Earth
ne_10m_admin_0_countriesdataset (downloaded at build time when the experiment is on). Only clearly monolingual countries are mapped; multilingual ones (CH, BE, LU, CA, …) are intentionally omitted to avoid mislabelling. - It is the geofenced version of the Tilemaker reference's global
name_<lang> = namecopy — so it does not mislabel a French town's name as German. - Requested languages follow
--name_languages(defaulten,de).
This makes three frontend label modes possible:
| Mode | Expression |
|---|---|
| Local name | ["get", "name"] |
| Prefer language X | ["coalesce", ["get","name_X"], ["get","name"]] |
| Only language X | ["get", "name_X"] (blank elsewhere) |
The "only language X" mode is the one that needs this experiment: without it, a German town tagged only name would have no name_de.
island_labels
Base Shortbread only labels island nodes. This adds area-ranked label points for islands mapped as polygons (the common case), so larger islands appear at lower zoom. Output is the normal place_labels kind=island.
address_details
Adds unit (from addr:unit) and block (from addr:block) to the addresses layer, beyond the spec's housename / housenumber.
bridge_names
Adds name (and, with locale_names, name_<lang>) to man_made=bridge polygons in the bridges layer. Base Shortbread defines no name for bridges. Upstream discussion: shortbread-docs #141.
Spec vs. experiment, by layer
Attributes a style can always rely on, versus those that only appear when an experiment is enabled:
| Layer | Spec attributes (always) | Experiment attributes / features |
|---|---|---|
buildings | dummy | height, min_height, hide_3d; extra building:part polygons |
addresses | housename, housenumber | unit, block |
bridges | kind | name, name_<lang> |
place_labels | kind, population, name… | extra island-polygon label points |
| name layers | name, name:<code>-derived | geofenced name_<lang> fallback |
Deviations from the reference (always on)
Separate from the opt-in experiments above, the profile intentionally differs from the Geofabrik Tilemaker reference in a few places to fix clear bugs or improve quality. These ship always (no flag) and stay spec-conformant:
boundariesadmin_levelclamped to{2, 4}(the schema enum); level 3/5+ are dropped.aerialwayskind— OSMrope_tow(absent from the schema enum) is mapped to the genericdrag_lift.- Multi-value names — OSM uses
;to join several names in one tag (e.g.name=A;B); only the first value is kept for a clean label. - Low-zoom label thinning —
water_polygons_labelsandplace_labelsare thinned per grid cell at low/mid zoom (keeping the largest / most populous) to bound tile size. ocean— non-polygonal slivers (thin polygons that collapse to lines at low zoom) are dropped so the layer stays polygon-only.way_areais reported in Web-Mercator m² (matching the spec's projection note), not geodesic.
These (and smaller ones) are marked with // DEVIATION: in the code and listed in the profile README.
Compatibility & stability
- Additive guarantee. Strict Shortbread consumers are unaffected — extensions never remove or retype spec data.
- Experimental. These attributes/features may change, be renamed, or be removed without a schema-version bump. Do not treat them as a stable contract; track the linked upstream issues.
- Tile size.
building_heightsand especiallybuilding_partsenlarge dense-city tiles (more attributes and features). Consider this when enabling them for a planet build.
Future
mountain_peaks— a planned new layer (natural=peak/volcano, elevation), off by default until proposed upstream (shortbread-docs #137).- Discoverability — stamping the enabled experiments into the archive metadata so a client can detect them.
References
- VersaTiles profile:
planetiler-shortbread· README ·Experiment.java - Shortbread schema: shortbread-tiles.org · shortbread-docs (issues #77, #137, #141)
- VersaTiles ecosystem: versatiles-generator (build) · versatiles-style (consumer)
- OSM: Simple 3D Buildings ·
building:height·addr:*· semicolon value separator - Rendering: MapLibre
fill-extrusion· data source Natural Earth admin 0