On this page
Points and labels
A point is a location with a marker and an optional label. Up to 50 per map. In GET, repeat poi= once per point; in POST, use the pois array.
Coordinates or place names#
Give lat,lon when you know where it is, or place:Name to look it up.
/v1/map.pngGET /v1/map.png?area=Zlínský+kraj&poi=49.13,17.33|label:Chřiby&w=400&h=300
/v1/map.pngGET /v1/map.png?area=Zlínský+kraj&poi=place:Zlín&poi=place:Kroměříž&poi=place:Uherské+Hradiště&w=400&h=300
Place lookups cover cities, peaks, mountain ranges and similar names, and prefer a match inside the framed area. The label defaults to the place name; set label: to override it. Coordinates are used exactly as given, with no lookup. Find place names with GET /v1/places/search?q=….
Names are looked up in the server's imported OpenStreetMap places first. A server can also configure a geocoder (Nominatim or Photon) for names its data does not have, such as places outside the imported region. When the server has none, an unknown name returns 404 not-found with close matches in suggestions. If the geocoder itself fails, the response is 502 upstream-failed or 504 upstream-timeout, so retry those rather than treating them as "no such place". Self-hosters: see Geocoder fallback.
After the location, a point takes |key:value options. All of them are in the poi reference. In JSON the same options are fields of each pois entry:
/v1/map{
"area": "Zlínský kraj",
"pois": [
{ "lat": 49.13, "lon": 17.33, "label": "Chřiby", "marker": { "shape": "triangle", "color": "#e02020" } },
{ "place": "Zlín", "marker": { "shape": "circle", "color": "#222222", "size": 9 } }
],
"width": 400,
"height": 300
}
Markers#
A plain point is a pin. Pick another preset with marker:, and tune color:, size: and stroke:/strokewidth:.
/v1/map.pngGET /v1/map.png?area=Zlínský+kraj&w=480&h=320&poi=49.40,17.60|marker:star|color:%23e0a000|label:star&poi=49.40,17.95|marker:diamond|color:%231565c0|label:diamond&poi=49.20,17.45|marker:square|color:%232e7d32|label:square&poi=49.20,17.80|marker:circle|color:%23222222|label:circle&poi=49.05,17.30|marker:triangle|label:triangle&poi=49.05,17.70|marker:dot|label:dot
Which presets exist, their default sizes and which one a point, a route start or a route finish gets by default is in the markers reference. The role matters: a plain point is a pin, a route start a ring, a route finish a flag (see Routes). Setting marker: replaces the role default.
Custom icons#
Use icon instead of a preset marker for logos or your own pins. It takes an SVG or PNG as a data: URI, or an https URL on a host the server operator allows. anchor:bottom puts the bottom edge of the icon on the location, which is what pin-shaped icons need; the default is the center.
/v1/map{
"area": "Zlínský kraj",
"pois": [
{
"lat": 49.2266,
"lon": 17.6667,
"label": "Zlín",
"marker": {
"icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSI0MCIgdmlld0JveD0iMCAwIDMyIDQwIj48cGF0aCBkPSJNMTYgMEM3IDAgMCA3IDAgMTZjMCAxMiAxNiAyNCAxNiAyNHMxNi0xMiAxNi0yNEMzMiA3IDI1IDAgMTYgMHoiIGZpbGw9IiMxNTY1YzAiLz48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSI2IiBmaWxsPSIjZmZmIi8+PC9zdmc+",
"anchor": "bottom",
"size": 30
}
}
],
"width": 400,
"height": 300
}
size is the icon height in CSS pixels. In a GET URL the icon must be URL-encoded (base64 contains +, / and =), so POST is the practical way to send one.
Security notes for icons#
Fetching a user-supplied URL is how servers get attacked, so the rules are strict. They are the server's, not yours, but they decide what works:
- Remote icons are off unless the operator lists hosts in
WHEREBOX_ICON_HOSTS. Until then onlydata:URIs work. See the configuration reference. - Remote icons must be
https, are never fetched through redirects, and are capped in size and time. - The type must really be an image (PNG signature check); SVGs containing a DOCTYPE or entities, external references, or scripts are rejected.
- A rejected icon is an error, not a silent fallback: you get
400 bad-request(see Errors and limits).
If you embed untrusted SVG from your own users, sanitize it before it reaches the API as well; the server's checks are a safety net, not a content policy.
Labels#
Set the text with label:. A \n starts a new line. Labels avoid each other, the markers, the route lines and the image edge.
/v1/map.pngGET /v1/map.png?area=Moravskoslezský+kraj&w=420&h=300&poi=49.5465,18.4472|label:Lysá hora\n1323 m|weight:700|marker:triangle|color:%23202020
In GET, | cannot appear inside a label; send a POST if you need one. In JSON write a real newline: "label": "Lysá hora\n1323 m".
Position, size, weight and color#
pos: puts the label next to the marker (right, left, top, bottom, the four corners, or auto, the default). labelsize:, weight: and labelcolor: style it. weight: overrides the map-wide fontweight for this label only; see Typography.
/v1/map.pngGET /v1/map.png?area=Zlínský+kraj&w=420&h=300&poi=place:Zlín|pos:bottom|labelsize:18|weight:700&poi=place:Kroměříž|pos:left|labelcolor:%231565c0
Crowded points and leader lines#
With pos:auto, a label first tries the spots next to its marker. If they are all taken, the label moves further out and a thin leader line connects it back. That keeps nearby points readable without you placing anything.
/v1/map.pngGET /v1/map.png?bounds=17.636,49.212,17.698,49.241&w=480&h=340&poi=49.2266,17.6693|label:Náměstí+Míru&poi=49.2277,17.6685|label:Zámek&poi=49.2282,17.6667|label:Divadlo&poi=49.2277,17.6649|label:Nádraží&poi=49.2266,17.6641|label:Radnice&poi=49.2255,17.6649|label:Muzeum&poi=49.2250,17.6667|label:Park&poi=49.2255,17.6685|label:Škola
Turn this off per point with leader:false; the label then sits at the nearest position even if it overlaps something:
/v1/map.pngGET /v1/map.png?bounds=17.636,49.212,17.698,49.241&w=480&h=340&poi=49.2266,17.6693|label:Náměstí+Míru|leader:false&poi=49.2277,17.6685|label:Zámek|leader:false&poi=49.2282,17.6667|label:Divadlo|leader:false&poi=49.2277,17.6649|label:Nádraží|leader:false&poi=49.2266,17.6641|label:Radnice|leader:false&poi=49.2255,17.6649|label:Muzeum|leader:false&poi=49.2250,17.6667|label:Park|leader:false&poi=49.2255,17.6685|label:Škola|leader:false
Options: poi (pos, labelsize, weight, labelcolor, leader).