Quick Start
nodes, ways, and relations limit what can match.limitLocal keeps matching in the current map view, limitLocal(auto) reruns when the view changes, and limitLocal(...) can resolve GPS, bbox, places, streets, or addresses.coords returns geometry so the result can be rendered on the map.count(key) counts distinct values instead of returning full geometry.ways
limitLocal
coords
highway=*
limitLocal("Zoo Leipzig")
building=*
coords
# are comments and ignored by the parser.Core Directives
nodes,ways,relations: choose feature typescoords: include geometrylimitLocal: restrict to the current map viewlimitLocal(gps, 2km): restrict to a radius around the current GPS positionlimitLocal(bbox, west, south, east, north): use an explicit bounding boxlimitLocal(auto): keep using the current map view and rerun automatically after significant map moveslimitLocal("Zoo Leipzig"): resolve a free-text local area first, then search inside itlimitLocal("Eldenaer Straße", 1km): resolve a free-text local area, add a radius, then search inside itgeocodeOnly("Trischenstraße, Wedel"): Webclient action for pure find/locate requests; it runs the geocoder and positions the map without executing a PBFX searchrouteOnly("Danziger Straße 73", from="Alexa", profile=bike): Webclient action for pure route requests; it resolves GPS or a named start plus destination geocode, then runs the normal routing endpointcoverage: return a raster coverage/heatmap layer instead of normal geometry resultscoverage(log, blur=5): use logarithmic scaling and five blur passes for smoother density mapsshow(condition): explicitly select the visible/returned feature setvectorTiles(polygonUnion, polygonClose=2px, polygonMinArea=1.17px2, labelLanguages=name|name:en|name:de),leanResults, anddebugVectorTiles(query,timing,mvt,client,prio): render map-like results as HTTP MapLibre MVT tiles, optionally union/close polygons, set their minimum area in square screen pixels, include selectable label-language variants, strip bulky result metadata, and show selected tile diagnosticsprojection(globe)orprojection(mercator): select the client-side MapLibre projection without changing the vector-tile data hashexternal(water_polygons)orexternal(water_polygons, osm_country_land): include prepared external data sources from~/temp/external. When bothosm_country_landand the legacycountry_boundariessource are listed, the detailed OSM source wins.deltaordelta(add, modify, delete): preview an experimentaldataset.pbfdoverlayresults 100000: override the result cap (default: 100,000; vector tiles: 1,000,000)numTags 5: include more tag information in result itemszoom 10 16: only activate following lines in that zoom rangeroutingorrouting(highway=*|route=ferry): build a route graph, optionally restricted to matching ways (intersectionsis still accepted as an alias)routeCost(highway=primary):1.8,routeCost(highway=traffic_signals):+25m,routeCost(oneway=yes):forward,routeCost(access=private):blocked,routeCost(highway=residential):defer(10km), orrouteCost(refMaxspeed):20km/h: weight, penalize, set direction, exclude routing graph segments, defer low-priority road classes far away from start and target, or set the ETA reference speeddebugPagesanddebugTagSets: print debug information to the server log
ways
coords
limitLocal
results 200000
limitLocal(gps, 2km)
amenity=pharmacy
coords
Delta Preview (Experimental)
delta shows changed OSM features from dataset.pbfd. Additions are green, modifications orange, and deletions red. Restrict the states with delta(add), delta(modify), delta(delete), or a comma-separated combination.
delta(add, delete)
limitLocal(auto)
limitLocal(auto). Your explicit view, GPS, bbox, or place limit is kept. Untagged nodes needed by changed ways are stored in the delta but not drawn as standalone features. PBFD is still a validation and visualization format, not yet a production replacement for a full PBFX rebuild.Filters
Use show(...) to choose the returned feature set. Older bare filter lines still work, but show(...) keeps result selection separate from styling, labels, and overlays.
show(highway=*|building=*|natural=water)
Filters are mostly exact. The most common forms are:
key=valuekey=**=valueto match a value across any keykey=a|b|cfor several values of the same key!key=valueto exclude matches(a=b)|(c=d)for explicit OR across different conditions
highway=primary|secondary|trunk
building=*
*=Eldenaer Straße|Hübnerstraße
!highway=street_lamp|traffic_signals|crossing
(railway=station)|(highway=bus_stop)
*=value means: match if any tag value equals that value. This is useful when the same name or identifier may appear under different keys.Named Selections & Spatial Queries
$name is a textual filter macro; @name is a materialized feature selection. Spatial operations work on named selections and return matching features from the left-hand selection only.
Keeps pharmacies no more than 500 metres from a station. It does not add the stations.
set @stations = nodes(railway=station|railway=halt)
set @pharmacies = nodes(amenity=pharmacy) | ways(amenity=pharmacy)
set @nearStations = near(500m, @pharmacies, @stations)
color(@nearStations):#d43f8d; for=nodes|ways
set @parks = ways(leisure=park) | relations(leisure=park)
set @paths = ways(highway=path|footway)
set @inside = inside(@paths, @parks)
set @crossing = intersects(@paths, @parks)
set @parksWithPaths = contains(@parks, @paths)
inside(A, B), intersects(A, B), and contains(A, B) are directed: only matching features from A are returned. inside requires B to contain polygons; contains requires polygons in A. near accepts m and km.@a & @b compares OSM identity. Use intersects(@a, @b) to compare geometry. The former top-level near(...)/inside(...) syntax is no longer supported.Materialize primitive features, follow relation membership in either direction, and combine sets with |, &, or -.
set @routes = relations(type=route&route=bus)
set @stops = members(@routes, role=stop)
show(@stops)
color(@stops):#00aa66; for=nodes
label(@stops):name; prefer=name,ref; size=12
role describes one relation membership rather than a normal feature tag. For example, members(@routes, !role=platform) excludes platform memberships from route geometry; a separate members(@routes, role=platform) set can be styled and labeled differently.
Reverse traversal uses parents(...), for example set @routes = parents(nodes(public_transport=platform), type=route).
Count and Coverage
Use count(key) to count distinct values instead of returning full geometry.
ways
limitLocal
count(surface)
Use coverage when you want a density/coverage raster layer instead of normal geometry results.
nodes
limitLocal
coverage(log, blur=5)
amenity=pharmacy
coverage supports linear, sqrt, and log scaling. The explicit form is coverage(scale=log, blur=5, resolution=256); only resolution=256 is currently supported.Styles and Labels
Current base style forms:
color(condition):#rrggbb; width=1.5; opacity=0.8style(condition):#rrggbb; width=1.5; opacity=0.8as a legacy aliasoverlay(condition):#rrggbb; width=1.5; opacity=0.8for an additional top layer
color(highway=primary):#ed8f54; opacity=0.98; width=3.6
color(building=*):#99948f; opacity=0.42; fill
overlay(surface=cobblestone|sett):#9073dd; opacity=0.35; width=4; line=dash
color() and style() are normal render styles and also act as style filters. overlay() duplicates already visible features as an extra marking and does not replace the base style.
Style options can limit geometry types, choose line patterns, disable picking, or add an outline/casing:
color(highway=primary):#e0613d; opacity=0.98; width=3.8; for=ways; casing=2
color(building=*):#85807a; opacity=0.30; fill; for=ways|relations; casing=1; hit=no
color(railway=rail):#2e2e33c7; width=1.8; for=ways; line=dashdot
Common style options: for=nodes|ways|relations, width=..., opacity=..., fill, line=solid|dash|dot|dashdot, casing=..., fadeIn=0..1, hit=yes|no, and overlay=yes. The legacy r,g,b,a,width tuple is still accepted.
fadeIn is a presentation-only duration in zoom levels. For example, a rule with zoom 7 12 and fadeIn=0.5 becomes fully opaque at zoom 7.5 without changing its MVT data or cache key.
Line width and casing use pixels by default. Append m for meters or px explicitly:
color(highway=primary):#e0613d; opacity=0.98; width=6m; minWidth=0.8px; maxWidth=7px; casing=25%
For metric widths, minWidth and maxWidth clamp the resulting on-screen width in pixels. A percentage casing is calculated per side from that clamped base width; absolute pixel and meter casings remain supported.
Casing appearance can be customized without changing feature geometry:
color(highway=primary):#e0613d; width=6m; casing=20%; casingColor=#70452f; casingOpacity=0.7; casingLine=solid
Polygon fills support the built-in patterns hatch, crosshatch, dots, and stripes:
color(boundary=protected_area):#b7ddb0; fill; fillPattern=hatch; patternColor=#43835a; patternOpacity=0.35
The map view background can be set with a hex or RGBA color. A color background hides the raster base map for the query:
background:#14171a
The raster base map can also be controlled by the query. Opacity is optional and only applies when the base map is shown:
background:base; opacity=0.55
background:none
When DEM tiles are available, the background can also be drawn from elevation data. Missing tiles are requested in the background and appear after rerunning the query:
background:hillshade; opacity=0.45; azimuth=315; altitude=45; exaggeration=1.4; resolution=384; smooth=3
background:relief; opacity=0.55; exaggeration=1.2
Routing overlays can be styled client-side when routing is active:
color(route):#0059ff; opacity=0.9; width=6; line=dash
color(route:start):#00b340; width=7
color(route:end):#e61a1a; width=7
Routing costs are independent from visual style. Factors multiply weighted meters. A factor of 1 is neutral, lower values are preferred, higher values are avoided. Multiple matching factors multiply. Additive +Xm values add meter-equivalent penalties, blocked removes a segment or node from the route graph, and defer(Xm|Xkm) postpones matching segments while both start and target are farther away than that distance:
routeCost(highway=cycleway):0.65
routeCost(highway=secondary):1.8
routeCost(highway=traffic_signals):+25m
routeCost(barrier=bollard):+12m
routeCost(access=private):blocked
routeCost(highway=residential):defer(10km)
routeCost(refMaxspeed):20km/h
routeCost(elevationProfile):1
Spatial route costs can prefer or avoid routing ways inside matching polygon targets or near matching geometry:
$green = leisure=park|natural=wood|landuse=forest
routeCost(inside($green)):0.5
routeCost(near(20m, highway=primary|highway=secondary)):2.0
Routing direction is another independent routeCost dimension. Later direction rules override earlier ones, without changing the numeric cost:
routeCost(oneway=yes):forward
routeCost(oneway=-1):backward
routeCost(oneway:bicycle=no):both
routeCost(cycleway=opposite):both
When routing is active, start/end placement snaps to the nearest segment. The route overlay reports length, average route cost, type shares, and counted traffic-signal nodes. Server routing applies node-via turn restrictions for car-like profiles and discourages U-turns with an additional turn penalty.
Global output keys use ->name or ->name|ref|maxspeed.
Conditional labels use label(condition):keys with optional label options:
label(place=city):name; prefer=name:de,int_name,name:en,ref; priority=320
label(place=town):name; priority=240
label(highway=primary|secondary):name; priority=120; size=11
label(highway=primary|trunk|motorway):ref; priority=180; shield=road; size=11
label(place=city):name; icon=city; iconSize=14; color=#333333; halo=#ffffffcc; priority=320
label(amenity=restaurant):name; icon=restaurant; iconSize=15; priority=120
prefer=key1,key2 tries preferred label keys first, then falls back to the keys after :.
Common label options: priority=..., size=..., color=#rrggbb, halo=#rrggbbaa, haloWidth=..., placement=point|line|polygon, anchor=..., offset=x,y, icon=..., iconSize=..., shield=road, and fadeIn=0..1. Legacy r,g,b,a label colors are still accepted.
icon=name shows a local Maki SVG icon with the label; common names include city, town, village, suburb, capital, restaurant, cafe, pharmacy, hospital, lodging, parking, fuel, bicycle, rail, airport, and museum.
shield=road renders a road ref label horizontally as a shield-style point label on the selected road geometry. Labels do not select features by themselves; keep a matching show(...) or selected filter for the roads.
Image overlays can load Commons thumbnails via Wikidata entity tags:
limitLocal
coords
tourism=museum
->name
->image(64):wikidata
->image(size):wikidata requests the wikidata output key automatically and shows up to a small number of image markers on the map when matching results contain a Wikidata Q-id with a Commons image.Macros
Macros start with $ and are expanded before normal parsing.
$roads = highway=*
$major = highway=primary|secondary|trunk|motorway
show($roads)
style($major):#ed8f54; opacity=0.98; width=3.6
Function-like macros are also supported:
$road($type,$width)=style(highway=$type):#f2b87a; opacity=0.95; width=$width
$road(primary,3.6)
$road(secondary,2.8)
Examples
ways
limitLocal
coords
show(highway=*)
color(highway=*):#ffffff; width=2; for=ways; casing=0.8
ways
relations
limitLocal("Zoo Leipzig")
coords
show(building=*)
color(building=*):#bdbdbd; opacity=0.8; fill; for=ways|relations
nodes
limitLocal
coords
show(place=city|town|village)
color(place=city|town|village):#333333; width=3; for=nodes; hit=no
label(place=city|town|village):name; priority=260
nodes
ways
limitLocal
coords
show(addr:housenumber=*)
!addr:street=*
!addr:place=*
!addr:city=*
color(addr:housenumber=*):#ff0000; width=4; for=nodes|ways
->addr:housenumber|addr:city|addr:place|addr:street
set @pharmacies = nodes(amenity=pharmacy)
set @stations = nodes(railway=station|railway=halt)
set @nearStations = near(500m, @pharmacies, @stations)
color(@nearStations):#ff0000; width=3
limitLocal
Not Supported Yet
- numeric comparisons such as
maxspeed >= 50 - regex matching
- full boolean expression precedence
- set negation and mixed set/tag expressions inside
show(...) - spatial operations on external features without stable OSM identities