Overview

Overpass is a query API for OpenStreetMap. Instead of downloading a whole country extract and sorting the mess out later, you can request a narrow slice of data: schools inside a district, clinics within a buffer, bridges along a corridor, or all waterways crossing a project area.

That makes it useful for early-stage screening, rapid map assembly, and situations where you need transparency on exactly which tags were asked for.

Why it matters

When to use

Use Overpass when:

Avoid using it as your only acquisition path when:

Inputs

Typical inputs are:

Workflow and method

  1. Define the spatial frame.
  2. Define the tag families that represent the feature class.
  3. Run a narrow query first and inspect returned tags.
  4. Expand tag coverage only after reviewing what the first result actually contains.
  5. Export to GeoJSON or JSON and normalize field names in the next pipeline stage.

Live extraction sketch

const temaneAmenities = await FileAttachment("../../data/examples/temane-amenities.geojson").json();
const temaneRoads = await FileAttachment("../../data/examples/temane-roads.geojson").json();
const temanePower = await FileAttachment("../../data/examples/temane-power.geojson").json();

({
  amenities: temaneAmenities.features.length,
  roads: temaneRoads.features.length,
  power: temanePower.features.length
})
const overpassSampleQuery = buildOverpassQuery({
  bbox: [-22.25, 34.95, -21.5, 35.35],
  filters: ['["amenity"="place_of_worship"]', '["power"="substation"]'],
  timeout: 90
});

overpassSampleQuery

Run it locally

The repo now contains an actual Overpass query file and a fetch script:

./scripts/overpass/fetch_osm_overpass.sh \
  queries/temane_amenities_power.overpassql \
  data/osm/temane_amenities_power_raw.json

After that raw fetch, the next local step is to normalize or export the JSON into GeoJSON for the pages and downstream scripts.

Run it in the browser

Inside Observable Framework, the browser-side version is simply a JavaScript cell that constructs the query text, lets you inspect it, and can be paired with a fetch if you want an in-browser demo:

const browserQuery = buildOverpassQuery({
  bbox: [-22.25, 34.95, -21.5, 35.35],
  filters: ['["amenity"="place_of_worship"]', '["power"="substation"]'],
  geometryTypes: ["node", "way", "relation"],
  out: "center tags"
});

browserQuery
renderCountBars([
  {label: "Amenity points", value: temaneAmenities.features.length},
  {label: "Road segments", value: temaneRoads.features.length},
  {label: "Power features", value: temanePower.features.length}
], {title: "Sample extraction counts from the Temane source layers"})
renderGeojsonMap({
  title: "Temane extraction preview",
  subtitle: "Roads, power, and amenity points from the local example dataset.",
  layers: [
    {data: temaneRoads, stroke: "#d7b97a", strokeWidth: 1.2, opacity: 0.8},
    {
      data: temanePower,
      stroke: (feature) => feature.geometry.type === "LineString" ? "#8db49a" : "#f1d391",
      fill: (feature) => feature.geometry.type === "Point" ? "#f1d391" : "none",
      pointRadius: 3.4,
      strokeWidth: 1.1,
      opacity: 0.95
    },
    {data: temaneAmenities, fill: "#e08bb6", stroke: "#ffffff", pointRadius: 4.5, strokeWidth: 0.8}
  ]
})
renderFeatureTable(temaneAmenities.features, [
  {label: "OSM id", value: (feature) => feature.properties?.["@id"]},
  {label: "Amenity", value: (feature) => feature.properties?.amenity},
  {label: "Name", value: (feature) => feature.properties?.name ?? feature.properties?.religion}
], {title: "Sample returned features", limit: 6})

Bounding box versus area

Both approaches work, but they behave differently.

Approach Good for Strengths Weaknesses
Bounding box Fast exploratory pulls and corridor windows Simple, explicit, easy to automate Returns features outside the true study boundary if the bbox is loose
Area / relation Named admin units or well-known regions Better semantic tie to a place Depends on OSM relation quality and can be slower or inconsistent

Bounding box pattern

Use a bbox when the study area is defined by a project extent, a buffer, or a provisional review window.

Area pattern

Use an area query when the unit matters semantically, such as a district or municipality you will reference in reporting.

Tag strategy

A good tag strategy is broader than one tag but narrower than a kitchen sink query.

For example, a school search may need to consider:

Not every one of these belongs in every analysis. The point is to review what is locally used in OSM and then decide which tags should count as a receptor, which should be flagged as possible matches, and which should be excluded.

Query design patterns

Pattern 1: multiple tags for the same concept

Pattern 2: paired feature and transport context

Use this when you want both a receptor and the network that serves it.

Pattern 3: candidate settlements

Tools, code, and export use

Common working flow:

  1. Draft and test the query in Overpass Turbo.
  2. Review tags and geometry types in the JSON response.
  3. Export as GeoJSON for immediate inspection.
  4. Rename the file with an area, theme, and date stamp.
  5. Normalize schema in your pipeline so later stages do not depend on raw OSM field variability.

Recommended file pattern:

moz_temane_osm_school-clinic_raw_2026-03-19.geojson
moz_temane_osm_school-clinic_clean_2026-03-19.geojson

Outputs

Expected outputs from an Overpass pull include:

Common pitfalls

Limitations

Overpass is only as good as the underlying mapping. Some places have rich feature coverage and weak attributes; others have settlement names but almost no public-service tags. It also does not solve conflation, deduplication, or project-specific classification on its own.