Build a Park Bench Finder App
Show visitors exactly where they can sit in any park using live OpenStreetMap data. This is the simplest possible MapLark query - a single API call returns all benches in a bounding box as GeoJSON points, ready to place on any map.
What you'll build
A function that queries the MapLark API for benches in a given area and returns their coordinates as an array of [lon, lat] pairs. You can pass these directly to any map library (Leaflet, Mapbox, Google Maps) to render pin markers. The same pattern works for any point-type OSM feature - bins, bike racks, drinking fountains, ATMs - just change the tags parameter.
Prerequisites
Run these commands on a Bash terminal.
pip install osmfeaturesScript
View full source code: test_park_bench_finder.py
"""
App idea: show benches on a park map so visitors know where to rest.
Djurgården is Stockholm's main recreational island; it has many benches.
API call: ``type=node&tags=amenity=bench``
"""
from osmfeatures import OSMFeature, OSMFeatureCollection, OSMFeaturesClient
DJURGARDEN_BBOX = "18.090,59.320,18.170,59.345"
def test_park_bench_finder(client: OSMFeaturesClient):
data = client.query(bbox=DJURGARDEN_BBOX, type="node", tags="amenity=bench", limit=200)
assert isinstance(data, OSMFeatureCollection)
assert len(data["features"]) > 0, "Expected bench nodes in Djurgården"
# All features must be Point nodes with the correct tag
for f in data["features"]:
assert isinstance(f, OSMFeature)
assert f.osm_type == "node"
assert f["geometry"]["type"] == "Point"
assert f.tags.get("amenity") == "bench"
# Nodes are already points - no centroid needed
assert f.centroid is None
# Extract lon/lat to demonstrate placing map markers
bench_coords = [f["geometry"]["coordinates"] for f in data["features"]]
assert all(len(c) == 2 for c in bench_coords)
lons = [c[0] for c in bench_coords]
lats = [c[1] for c in bench_coords]
# Sanity-check all coordinates fall inside Stockholm
assert all(17.5 < lon < 18.5 for lon in lons)
assert all(59.0 < lat < 60.0 for lat in lats)
print(f"\n[bench finder] {len(bench_coords)} benches found in Djurgården")
How it works
The query uses three parameters to narrow results to exactly the features you need. All three are passed as URL query parameters to GET /v2/osm_features.
| Parameter | Value | What it does |
|---|---|---|
bbox | min_lon,min_lat,max_lon,max_lat | Spatial anchor - restricts results to a rectangular area. Required when using tag filters. |
type | node | Returns only point-type OSM features. Benches are always nodes, so this keeps the response lean. |
tags | amenity=bench | Exact tag match using OSM's native key=value schema. Only features with this exact tag are returned. |
limit | 200 | Maximum features to return per page. Use X-Has-More and X-Next-Cursor (or SDK meta) to paginate. |
centroid in their properties - the geometry.coordinates is already the pin location. The centroid field only appears on non-point features (ways, polygons, relations) as a convenience for placing map markers without computing a centroid yourself. Adapt it
The same one-liner pattern works for any OSM amenity node. Swap the tags value to find other point features in any area:
| Tags value | What you get |
|---|---|
amenity=waste_basket | Public bins / litter baskets |
amenity=bicycle_parking | Bike parking spots |
amenity=drinking_water | Public drinking fountains |
amenity=atm | ATM machines |
tourism=viewpoint | Scenic viewpoints |
natural=tree | Individual mapped trees |
More examples
Restaurant Guide
Fetch restaurants with names, cuisine types, and map pins - handling both point and polygon geometries.
Cycling Trail Finder
Use OR-combined tag filters to find bike-permitted paths and forestry tracks.
Walking Route Planner
Build Dijkstra-based walking directions on a real OSM footway network.
API Playground
Explore the OSM dataset with preset tag filters and test all API parameters.