Overpass QL Intro

Basics of OSM

Before jumping into Overpass QL, I need to explain at least a little bit of how OSM works.

  • nodes
  • ways
  • relations
OSM right click menu.
OSM tags after clicking Query features
OSM tags after clicking Query features.
Tags associated with an OSM object
Tags associated with an OSM object.

Basics of Overpass QL

At this point you are familiar with OSM, so why not move on to the query language Overpass offers.

Overpass Turbo site.
node[amenity=atm]({{bbox}});
out;
ATMs returned by our first query.
Searching for tags in a OSM database
Searching for tags in a OSM database.
  • search in the OSM database and find out what tags exist for what you want to search
  • try to find the tag value on the wiki page
  • build your query
  • I go to the database site and search for “school”, I get these results:
Search results for “school”.
  • I search for school on the Wiki page and find out that there are again a bunch of options, e.g. school as a building, driving school, music school, etc.
  • Now I build my query. It might look something like this:
(
node[amenity=school]({{bbox}});
node[building=school]({{bbox}});
node[amenity=music_school]({{bbox}});
);
out;
node[amenity=school]({{bbox}});
node[building=school]({{bbox}});
node[amenity=music_school]({{bbox}});
out;
(
node[amenity=school]({{bbox}})->._;
node[building=school]({{bbox}})->._;
node[amenity=music_school]({{bbox}})->._;
)->._;
out;
node[highway=bus_stop][shelter=yes]({{bbox}});
out;
node[highway=bus_stop][name="Nazionale/Quattro Fontane"]({{bbox}});
out;
node[highway=bus_stop][name~"Fontane$"]({{bbox}});
out;
node[highway=bus_stop][name~"Fontane$", i]({{bbox}});
out;
node[!highway]({{bbox}});
out;
Go to results button
Go to results button.
[timeout:120];area["name:en"=Prague]->.a;
node(area.a)[amenity=atm];
out;
[timeout:120][out:json];area["name:en"=Prague]->.a;
node(area.a)[amenity=atm];
out;
Buttons for switching between raw data and interactive map.

Areas

In all of the previous examples, I used {{bbox}} bounding box. But that’s not ideal because:

  • It’s available only in the web app.
  • It doesn’t apply well if I want to query an area that does not fit well into the rectangle map in the web app.
area["name:en"=Prague]->.a;
node(area.a)[amenity=atm];
out;
  • I used name:en tag key because I suspect that name key would contain the value Praha, not the English name.
  • I assigned the result or the area query to a named set; I recommend using named sets, the code becomes a bit more clear.
rel["name:en"=Prague][boundary=administrative]->.prague_rel;
.prague_rel map_to_area->.prague;
node(area.prague)[amenity=atm];
out;

Examples

It’s time for some examples :)

area["name:en"="Czechia"]->.cze;
way(area.cze)[power=line][voltage=400000];
(._;>;);
out;
  • I’m looking for power lines which will be represented as ways in OSM.
  • This strange looking (._;>;); statement exists because I need to find nodes for the ways that the previous statement assigned into the default set. This is what the recurse down query does. ._ means take what’s in the default set. And the outcome will again be assigned to the default set.
400 kV power lines in the Czech Republic.
area["name:en"="Prague"]->.prague;
(
rel(area.prague)[route=tram][ref=3];
rel(area.prague)[route=tram][ref=9];
);
(._;>>;);
out;
Tram routes 3 and 9 in Prague.

Around filter

Let’s consider the following situation: I want to find tram stops that are close to train stops. Typing such queries is possible with the aroundquery filter:

area["name:en"="Prague"]->.prague;
node(area.prague)[railway=tram_stop]->.trams;
(
node(around.trams:500)[railway=stop][!subway];
node(around.trams:500)[railway=station][!subway];
);
out;
Train stops in Prague that are within 500 meters from a tram stop.

nw, nr, wr, nwr

Let’s see another example. I’ll find all things related to nuclear power in the Czech Republic:

area["name:en"="Czechia"]->.a;(
nwr(area.a)["plant:source"=nuclear];
nwr(area.a)["landfill:waste"=nuclear];
nwr(area.a)["generator:source"=nuclear];
nwr(area.a)["hazard"=nuclear];
nwr(area.a)["disused:generator:source"=nuclear];
nwr(area.a)["military"="nuclear_explosion_site"];
);
(._;>>;);
out meta;
nwr["plant:source"=nuclear];
(
node["plant:source"=nuclear];
way["plant:source"=nuclear];
relation["plant:source"=nuclear];
);
  • nw stands for node and way
  • nr stands for node and relation
  • wr stands for way and relation
  • nwr stands for node, way, and relation

How is all this useful?

I’ll finish my Overpass QL intro here but let’s answer one more question. All this is nice but how exactly is all this useful?

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store