Overpass API/Overpass API by Example

From OpenStreetMap Wiki
Jump to: navigation, search
Available languages — Overpass API/Overpass API by Example
· Afrikaans · Alemannisch · aragonés · asturianu · azərbaycanca · Bahasa Indonesia · Bahasa Melayu · Bân-lâm-gú · Basa Jawa · Baso Minangkabau · bosanski · brezhoneg · català · čeština · corsu · dansk · Deutsch · eesti · English · español · Esperanto · estremeñu · euskara · français · Frysk · Gaeilge · Gàidhlig · galego · Hausa · hrvatski · Igbo · interlingua · Interlingue · isiXhosa · isiZulu · íslenska · italiano · Kiswahili · Kreyòl ayisyen · kréyòl gwadloupéyen · Kurdî · latviešu · Lëtzebuergesch · lietuvių · magyar · Malagasy · Malti · Nederlands · Nedersaksies · norsk bokmål · norsk nynorsk · occitan · Oromoo · oʻzbekcha/ўзбекча · Plattdüütsch · polski · português · română · shqip · slovenčina · slovenščina · Soomaaliga · suomi · svenska · Tiếng Việt · Türkçe · Vahcuengh · vèneto · Wolof · Yorùbá · Zazaki · српски / srpski · беларуская · български · қазақша · македонски · монгол · русский · тоҷикӣ · українська · Ελληνικά · Հայերեն · ქართული · नेपाली · मराठी · हिन्दी · অসমীয়া · বাংলা · ਪੰਜਾਬੀ · ગુજરાતી · ଓଡ଼ିଆ · தமிழ் · తెలుగు · ಕನ್ನಡ · മലയാളം · සිංහල · ไทย · မြန်မာဘာသာ · ລາວ · ភាសាខ្មែរ · ⵜⴰⵎⴰⵣⵉⵖⵜ · አማርኛ · 한국어 · 日本語 · 中文(简体)‎ · 吴语 · 粵語 · 中文(繁體)‎ · ייִדיש · עברית · اردو · العربية · پښتو · سنڌي · فارسی · ދިވެހިބަސް
Overpass turbo · Overpass API · Language reference · Query examples · Language Guide · Advanced examples · Sparse Editing · FAQ · MapCSS · more: Overpass turbo · Overpass API

The Overpass API offers a variety of search possibilities. This is also known as querying. The results of those searches or queries can be displayed directly on a map, but it is also possible to retrieve only the data. On this page we will focus on examples that have to be displayed on a map. This means that all queries can be inserted in the code editor of Overpass turbo . From there the query can be executed and the result will be shown on a map.


Simple examples

Query for rare or unique tag values

The following query will search for nodes with the name name=Gielgen, we expect that there are not many nodes with such a tag.

  out skel;

UI description is out-of-date

Please, when you try this query in the UI, choose the to OpenLayers auto-centered overlay radio button and run the query with Convert on. This will center the map automatically around the result, i.e. around the node that represents the village Gielgen.

When the first line of the result reads Searching ..., then you know that the server has not returned any data yet. When the line reads No results found., you know that the result did not contain any nodes (and without nodes, nothing can be drawn by OpenLayers). Found ... features, means of course that the result contains so many Nodes and Ways.

Since OpenLayers requires Nodes in order to display data on the map, we need to retrieve the Nodes of the Ways in order to display Ways. This is done with the operator ">":

  out skel;

The same holds for Relations:

  (rel["ref"="A 555"];>;);
  out skel;

One has to be aware, that numbers of found objects includes the ways within the relations.

Query frequently occurring tags

When the tag does not identify a unique object, but instead describes a category of objects such as mailboxes, then it is still possible to show them all as a layer on a map:

  out skel;

UI description out-of-date

Please select to OpenLayers slippy overlay in the radio buttons and start the qeury with Convert. After such a query, the map will always be centered on Central Europa and the objects will only be loaded when you zoom in.

The status text indicates whether one zoomed in far enough: Please zoom in to view data. means that no data was loaded at the current zoom level, but data that was already loaded will not be removed. Loading... appears, as soon as the browser will start loading objects when one zooms in one level more. Displaying ... features indicated how many objects were loaded

The zoom level works together with the time out parameter [timeout:5]: The Slippy Map waits maximum 5 seconds to obtain data from the Overpass API. When one increases this value, the system becomes less responsive, and requires more memory on the client side. However, one can see the features even when one is zoomed out to a higher level. On the other hand, decreasing the value makes the system more responsive, but requires to zoom in.

As an example for ways, ski slopes:

  out skel;

and as example for relations, retrieve all highway routes belonging to the network BAB:

  out skel;

Query frequently occurring tags in a bounding box

In case one knows the bounding box in which one wants to search for a tag, one can simply add this box to the query. The following query

  out skel;

finds all mailboxes in Bonn (latitude between 50.6 and 50.8, longitude between 7.0 and 7.3) and shows then on the map.

A slight more complex query is needed for schools, as they can be mapped as both Nodes and Ways:

  out skel;

The query consists of 3 subqueries, whose results are joined 1. all Ways, which have the tag amenity=school 2. all Nodes references by the above ways 3. alle Nodes, which have the tag amenity=school.

Overpass Turbo combines the results of 1 and 2, such that the ways are displayed on the map.

The same principle works for relations

  out skel;

returns the bus route 16 that goes through Bonn. Please note that the complete route is shown, while part of it lies outside Bonn (or the bounding box). The reason is that the query starts with looking for the relations within the bounding box and from there continues to look for all elements in the relation.

The query

  out skel;

will also limit the ways to the bounding box. This is done by querying the nodes and ways that are part of the relation and fall within the bounding box.

Search objects with a certain tag A but without a tag B

Example: find all Nodes, Ways and Areas which are tagged with addr:city, but do not have addr:postcode: try it yourself in overpass-turbo

) ;out skel;

OSM-data at a certain date

The following query retrieves the data in the visible area of Overpass Turbo on May 6, 2014 at 00:00

( node({{bbox}}); <; >; );
out meta;

Link to Overpass Turbo, Overpass XML Variant

List of streets

The following query allows you to compile a complete list of all street names in a town. The example is made for Troisdorf:


This gives all the Ways inside this town, including ways that cross the town boundary. It cannot be avoided, but luckily it does not occur that often. The Nodes of the ways are not returned. With a small shell script such as

  grep '<tag k="name"' <troisdorf.osm | sort | uniq | awk '{ s=substr($0,22); print substr(s,1,index(s,"\"")-1); }' >streetnames.txt

one can extract the list of street names.

In many cases, the boundary of a town has a different name than the city itself. This leads to empty results.E.g. Eckernförde requires the suffix "Landmasse" . The problem can be solved in general by using a regular expression


the processing afterwards can be simplified when one uses CSV as output


One only has to remove duplicates from this list, this can easily be done with

sort liste.csv | uniq

Looking for a boundary relation with boundary=administrative and admin_level=9 and de:amtlicher_gemeindeschluessel=XXXXXXXX

... because the combination of admin_level=9 with AGS is incorrect. Boundary relation for villages with their own "Gemeindeschlüssel" should have at least admim_level=8 or higher.

The first query also leaves out "boundary=administrative" , because it is equally possible that one has set the wrong level or did not mention the level at all



Non-matching addr:postcode=XXXXX tags inside a boundary relation with postal code ≠ XXXXX

... what is the query for all Nodes and Ways with a different addr:postcode than the surrounding boundary relation?

Query for a specific postal code, e.g. "42103":

Since release 0.7.54, it's also possible to check several postal codes in one query:

area[postal_code](if:number(t[postal_code])>="42103" &&

foreach.pc -> .a(
  .a out;
   node(area.a)["addr:postcode"]["addr:postcode"](if: t["addr:postcode"] != a.u(t["postal_code"]));
   way(area.a)["addr:postcode"]["addr:postcode"](if: t["addr:postcode"] != a.u(t["postal_code"]) );
  out geom;

Previously, this required a bash-script for postal codes 42103 - 42119

  i=42103; while [[ $i -le 42119 ]]; do { wget -O false_$i.osm "http://overpass-api.de/api/interpreter?data=area[postal_code=\"$i\"]->.a;(node(area.a)[\"addr:postcode\"][\"addr:postcode\"!=\"$i\"];way(area.a)[\"addr:postcode\"][\"addr:postcode\"!=\"$i\"];>;);out;"; i=$(($i + 1)); }; done

When one replaces "out;" with "out meta;", than it becomes possible to read the data in the file "false_XXXXX.osm" into JOSM for editing.

The query becomes noticeable faster faster with a proper Bounding Box:

  i=42103; while [[ $i -le 42119 ]]; do { wget -O false_$i.osm "http://overpass-api.de/api/interpreter?data=area[postal_code=\"$i\"]->.a;(node(51,7,51.5,7.5)(area.a)[\"addr:postcode\"][\"addr:postcode\"!=\"$i\"];way(51,7,51.5,7.5)(area.a)[\"addr:postcode\"][\"addr:postcode\"!=\"$i\"];>;);out meta;"; i=$(($i + 1)); }; done

Buildings crossed by roads that are not tagged as tunnel or covered

Gebäude ragt auf Straße

Query for buildings crossed by roads (Ways) that do not have a tunnel or covered tag. Since query uses the "around" operator, which searches in the environment of an item, it is possible that false positives are returned, e.g. when a street (Way) is directly connected to the building

Please note that this is a very slow query, that can better be run with a specified bounding box.

Please note that the following query is written with Overpass Turbo in mind

  ( {{bbox}} );
out meta;

Find all bus stops which are not included in a relation

This query returns all bus stop nodes, which are not part of a relation. try it yourself in overpass-turbo

 1 // Select city of Bonn as area
 2 area[name="Bonn"];
 4 // Collect all bus stops in Bonn and store the result in a variable .all
 5 node(area)[highway=bus_stop]->.all;
 7 // Select all relations, where one of the nodes in variable .all is a member
 8 rel(bn.all);
 9 // ...and for those relations find all related node members
10 node(r);
12 // Calculate the set difference (._ contains all nodes which are member of a relation)
13 ( .all; - ._; );
15 // return the result including meta data
16 out meta;
18 // Variant for line 9 / 10:
20 // Return only relations with a specific tagging:
21 // rel[route=bus](bn.all);

(via talk-de, Thanks to Roland)

Bus relations, which are not part of a master relation

Q: I need to find out, which bus relations (route=bus) are not part of a master relation (route_master=bus) in a given area.

1 rel({{bbox}})[route=bus]->.all;
2 rel[route_master=bus](br.all);
3 rel[route=bus](r);
4 ( .all; - ._; );
5 out;

Step-by-step explanation:

  1. Determine all relations in the current bbox with type route=bus. Save the result in variable .all
  2. Determine all parent relations of our relations in .all. Those relations need to be of type route_master=bus.
  3. Based on the list of route_master relations, we determine all child relations of type route=bus. Those relations are all part of a master relation.
  4. Create the set difference of the relations in variable .all and the result from the previous step 3. This way, all relations, which are not part of a master relation, are returned.


« n » adjacent ways

The following example illustrates how to determine five adjacent ways for OSM way 111435507. The around statement with radius 0, which is used in this query not only filters directly connected ways, but also returns intersecting ways (without a common node). Possibly those intersecting ways need to be filtered out in a post-processing step. try it yourself in overpass-turbo


To limit the overall data volume only ways with a highway tag (excluding path, track, cycleway and footpath) are considered. In addition, the global search space is limited via [bbox:...] to a certain bounding box.

How to modify a selected category of data

This guide is now covered in its own page for Sparse Editing.

Find nodes/ways with a given role in a relation

Find all nodes with role "label" or "admin_centre" in current bounding box:


(  node(r.relations:"label");

Find all "inner" ways, e.g. relation member ways with role 'inner':


Find all nodes and ways with role "via":




Adding geocoding details to POIs

Original question on help.openstreetmap.org:

I have a Overpass API query which returns lot of nodes. I would like to know whether there is a way to add reverse geocoding information to the resulting data set. Details of my case are not that important, but just for completeness:

In fact I do not need full reverse geocoding info for nodes, I only need relation of certain administrative level, so if this is possible to add into the result set, it would be great.

 1 area[name="Česko"];
 2 node[information="guidepost"][ele~"^2..$"](area)->.posts;
 3     // You can remove "ele".
 4     // It has been added to experiment with a fewer number of results
 5 foreach.posts(
 6   out;
 7   is_in;
 8   area._[admin_level~"[46]"];
 9       // The choice of "[46]" is arbitrary and could be anything else.
10       // In this case, admin_level=4 are counties and admin_level=6 are cities,
11       // which might be handy.
12   out ids;
13 );
15 // collect area details in 2nd step
16 .posts is_in;
17 area._[admin_level~"[46]"];
18 out;

To avoid repeating full area details for each information=guidepost, the query uses the following alternative approach: for each guidepost, we will only print the osm id for the area, but nothing else. Only towards the end of the query, the full details for all relevant areas are returned.

Here's a brief example on how the format looks like: a POI (node 691566183) is followed by two area ids (3600435511 and 3600442466), which are followed by another POI and its respective area ids. To find out the details for area id 3600435511, simply consult the full area details towards the end of the response.

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API">
  <node id="691566183" lat="49.7982193" lon="13.4686623">
    <tag k="ele" v="295"/>
    <tag k="information" v="guidepost"/>
    <tag k="name" v="Dolanský most (pravý břeh)"/>
    <tag k="tourism" v="information"/>
  <area id="3600435511"/>
  <area id="3600442466"/>
  <node id="691566191" lat="49.8003120" lon="13.4679726">
    <tag k="ele" v="295"/>
    <tag k="information" v="guidepost"/>
    <tag k="name" v="Dolanský most (levý břeh)"/>
    <tag k="tourism" v="information"/>
  <area id="3600435511"/>
  <area id="3600442466"/>
  <area id="3600435511">
    <tag k="admin_level" v="4"/>
    <tag k="boundary" v="administrative"/>
    <tag k="name" v="Jihozápad"/>
    <tag k="name:cs" v="Jihozápad"/>
    <tag k="name:de" v="Südwesten"/>
    <tag k="population" v="1209298"/>
    <tag k="ref" v="CZ03"/>
    <tag k="ref:NUTS" v="CZ03"/>
    <tag k="source" v="cuzk:ruian"/>
    <tag k="source:population" v="csu:uir-zsj"/>
    <tag k="type" v="boundary"/>
    <tag k="wikipedia" v="cs:NUTS Jihozápad"/>
  <area id="3600442466">
    <tag k="ISO3166-2" v="CZ-PL"/>
    <tag k="admin_level" v="6"/>
    <tag k="boundary" v="administrative"/>
    <tag k="name" v="Plzeňský kraj"/>
    <tag k="name:cs" v="Plzeňský kraj"/>
    <tag k="name:de" v="Region Pilsen"/>
    <tag k="name:ru" v="Пльзенский край"/>
    <tag k="population" v="572687"/>
    <tag k="ref" v="PL"/>
    <tag k="ref:NUTS" v="CZ032"/>
    <tag k="source" v="cuzk:ruian"/>
    <tag k="source:population" v="csu:uir-zsj"/>
    <tag k="type" v="boundary"/>
    <tag k="wikipedia" v="cs:Plzeňský kraj"/>

Quelle, Dank an Roland

POIs with websites but with incorrect opening hours

The following query returns institutions and shops, for which a website is tagged, but the opening hours are incorrect (i.e. the syntax is wrong). One should first try the first query, because it more likely to return results for which the opening hours can be found on the website. When the result of the first query is empty, one could try the second one.

First Query:

out meta;

Second Query:

out meta;


Counties without fire station

The following query retrieves all counties (German Kreise) in the state Schleswig-Holstein, in which no fire station is mapped. See the German Forum Thread for details.

It applied a crude workaround for the "area in area" problem (see Github Issue #45): It starts by retrieving all Nodes in the area defined by boundary of Schleswig-Holstein, that have at least 1 tag and that are not part of a Way. For those nodes all "areas" with admin_level = 8 are retrieved. On the other side, we also retrieve all amenity=fire_station for areas with admin_level = 8. The difference between those 2 collections of areas, are all areas in which there is no fire_station mapped. To present the result, all found areas are extended with the necessary ways and nodes

 1 [timeout:3600];
 2 // just working on level 4
 3 area[admin_level=4]["name"="Schleswig-Holstein"]->.boundaryarea;
 5 // get all fire_stations
 6 ( node(area.boundaryarea)["amenity"="fire_station"];
 7   way(area.boundaryarea)["amenity"="fire_station"];>;) ->.a;
10 // >>> Also show existing fire stations? uncomment the following line! <<<
11 //.a out;
12 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
14 // get all areas that contain fire_stations and 
15 // select only areas with admin_level=8
16 .a is_in -> .b; 
17 area.b[admin_level=8] -> .bf; 
19 // get all areas with admin_level=8, 
20 // assuming there's at least one node with any tags
21 node(area.boundaryarea)[~"."~"."] ->.all;
22 // now find out all nodes with any tags that are not part of any way
23 way(bn.all);node(w)[~"."~"."]->.partofway;
24 (.all - .partofway) -> .single_nodes;
26 .single_nodes is_in -> .bll; 
27 area.bll[admin_level=8] -> .bllf;
29 // calculate difference
30 (.bllf - .bf ) ; 
32 // show areas as relation on map
33 rel(pivot); (._;>;); out;

Thank you fx99

Overpass Turbo Link


The following alternative gives all counties (Kreise) in Schleswig-Holstein without amenity=fire_station. Please be aware that the conversion from relations into areas (and thus areas into areas) still experimental in Overpass API 0.7.51 This means that bugs are still possible and that changes in the API are still possible. The result is in CSV format and contains the OSM ID of the relation, the "amtlichen Gemeindeschlüssel" and the name of the relation.

 1 // Ausgabe im CSV Format
 2 [out:csv(::id, "de:amtlicher_gemeindeschluessel", name)];
 4 area[admin_level=4]["name"="Schleswig-Holstein"][boundary=administrative]->.boundaryarea;
 6 // Alle bounding areas with level 8 in Schleswig-Holstein
 7 rel(area.boundaryarea)[admin_level=8];
 8 // make relations out of the areasn (still experimental in 0.7.51)
 9 map_to_area -> .all_level_8_areas;
11 // Search All amenity=fire_station in Schleswig-Holstein
12 ( node(area.boundaryarea)["amenity"="fire_station"];
13   way(area.boundaryarea)["amenity"="fire_station"];>;);
15 // in which boundary areas with level 8 do they appear?
16 is_in;
17 area._[admin_level=8] -> .level_8_areas_with_firestation; 
19 // All level 8 bounding areas without those 
20 // areas with fire station
21 (.all_level_8_areas - .level_8_areas_with_firestation ) ; 
23 // Calculate and output relation
24 rel(pivot);
25 out geom;

Overpass Turbo Link

Search for nodes which belong to two different ways

How to find nodes, which belong to two different ways with certain tags?



returns nodes which are part of a building:


returns nodes of tertiary highways.

How can I combine those two queries so that both conditions are met?

node.b.t;            // calculates set intersection of both variables .b and .t

Overpass Turbo Link


If ways cannot be split into two distinct groups (e.g. building ways vs. highway=tertiary ways), it is necessary to iterate over each single way and determine the intersecting nodes with all other ways in a bbox:

foreach .allways -> .currentway(
  (.allways - .currentway)->.allotherways;
  (._ ; .result;) -> .result;
.result out meta;

Search for nodes which belong to an exact number of ways

To find out all nodes, which belong to an exact number of ways (rather than just more than one way as in the previous example), the following approach can be used:

Find out all nodes, which belong to exactly 3 distinct ways:

foreach .a -> .b(
  (.a - .b)->.c;
  foreach .f1 -> .g(
    way._(if:count(ways) == 3);
    (._ ; .result;) -> .result;
.result out meta;

Caveat: Unfortunately, this query is extremely slow.

Search for street intersections

The following query returns the street intersection of 6th Avenue and West 23rd Street (e.g. in New York):

way[highway][name="6th Avenue"];node(w)->.n1;
way[highway][name="West 23rd Street"];node(w)->.n2;
out meta;

Assumption: both streets need to be connected via a common node.

Overpass Turbo Link Source

Find intersections of major and minor roads:


way[highway~"^(motorway|trunk|primary|secondary|tertiary|(motorway|trunk|primary|secondary)_link)$"];node(w) -> .major;
way[highway~"^(unclassified|residential|living_street|service)$"];node(w) -> .minor;

Count Pharmacies per Country

(Assuming Country is the proper translation for the German "Kreis") The following example returns the number of pharmacies per area with regional key 057* aus. The output is in CSV-Format.

CSV-Format: in Overpass Turbo under Export -> Open Raw Data directly from Overpass API: then load data in  in LibreOffice, The fields are tab-separated

// CSV-Output: see http://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL#Output_Format_.28out.29

[out:csv(::type, "de:regionalschluessel", name,
         ::count, ::"count:nodes", ::"count:ways", ::"count:relations")];

//All areas with regional key (German: "Regionalschlüssel") starting with 057

// Count the pharmacies in each area
  // display details for the current area
  .regio out;
  // Collect all Nodes, Ways and Relations wth amenity=pharmacy in the current area
  ( node(area.regio)[amenity=pharmacy];
// Count the elements in the current area Area, is experimental in  in 0.7.51!  
  out count; 

Overpass Turbo Link

Find duplicate nodes

See https://help.openstreetmap.org/questions/39745/show-duplicated-nodes-via-overpass

Since release 0.7.54, the following approach is also possible: we iterate over all nodes in the current bounding box one by one, and find out the list of all nodes with the same lat/lon value. Assuming there's more than one node at the same lat/lon, those two nodes will have different node ids. That's also the condition we use to filter out those duplicate nodes. The output will only return the duplicate node for each location having the lowest node id.

    node.b(if:id() == b.min(id()) && b.min(id()) != b.max(id()));
    out ;

Unfortunately, this is very slow.

Find multipolygons with more than one outer way member

foreach -> .a (
  way._(if:count(ways) > 1);

Sum of a few defined OSM areas

This query is easily modified to get a sum of any OSM defined areas (geocodeArea) and extract any data for this sum of areas. See comments for details. The example just shows the chosen areas.

// get a few areas into .myArea
// you can add or remove an area by simply adding or removing
// one line here. 


{{geocodeArea:"Grodzisk Mazowiecki County"}}; // "name:en" may be used as well as "name"
{{geocodeArea:"powiat pruszkowski"}};
{{geocodeArea:"powiat żyrardowski"}};
{{geocodeArea:"powiat warszawski zachodni"}}; 
{{geocodeArea:"powiat sochaczewski"}}; 
{{geocodeArea:"powiat nowodworski"}};
{{geocodeArea:"powiat legionowski"}};
{{geocodeArea:"powiat wołomiński"}};
{{geocodeArea:"powiat miński"}};
{{geocodeArea:"powiat otwocki"}};
{{geocodeArea:"powiat piaseczyński"}}; 

// display .myArea This can be replaced by any query
// on the objects in .myArea


// print results
out geom;


Overpass Turbo Link: http://overpass-turbo.eu/s/deu

By tag count

Search for untagged ways

OSM Inspector zeigt auf dem Tagging Layer u.a. Wege ohne Tags.

Diese Analyse lässt sich auch mit Overpass Turbo durchführen und die Ergebnisse gleich in JOSM weiterverarbeiten:

(way({{bbox}}); - way({{bbox}})[~"."~"."];)->.w1;
(.w1; - .w2;);
(._; >;);
out meta;

Overpass Turbo Link


Since 0.7.54 you can also write:

way({{bbox}})(if:count_tags() == 0);
out geom;

Nodes with at least 1 tag

The following query returns all nodes in the current bbox having at least one tag:

[bbox:{{bbox}}];node[~"."~"."];out meta;



Since 0.7.54 you can also write:

way({{bbox}})(if:count_tags() > 0);
out geom;

Nodes with exactly one specific tag

The aim of the following query is to find out all nodes with one specific tag only.

Since 0.7.54 you can use a filter expression:

way({{bbox}})[building](if:count_tags() == 1);
out geom;

For previous versions:

For this purpose, we combine the difference operator ("-") with a regular expressions for keys. Unfortunately, Overpass API doesn't support Perl-compatible regular expressions (PCRE) yet, which would come in handy for an easy solution to this kind of task. The following example is based on a simplified approach: starting with all buildings in the current bbox, we exclude all objects with a tag starting with a letter other than b.

To get some basic idea how to construct a suitable regular expression for a proper but more evolving solution, the following post on stackoverflow should be consulted.

// Query all buildings
// and remove ...
// all buildings with a tag that doesn't start with letter 'b'
); >; );



QA on streets, addresses and house numbers

Find useless associatedStreet-relations

JOSM-plugin "terracer" can be used to split buildings in several parts. Unfortunately, this plugin used to create an associatedStreet relation by default. Those relations are totally useless. Also, street names on the selected buildings are ignored, and only the names filled in the dialog are taken and put on the relation. Also the required "street"s for this type of relation are missing. The result is an associatedStreet-relation with a few members with the role "house".

It would be good to identify those relations and delete them:
— brogo, im dt. OSM Forum

Default settings were changed in the meantime. However, there are still many useless aS relations around.


 1 /* Enter your city/region/etc. here */
 2 {{nominatimArea:Berlin}}
 3 (._; )->.area;
 5 /* Find all associatedStreet relations in your area */
 6 rel[type=associatedStreet]
 7   [!name]
 8   [!"addr:street"]
 9   (area.area)->.allASRelations;
11 /* Find associatedStreet relations with member ways having role "street" */
12 way(r.allASRelations:"street");
13 rel(bw:"street")[type=associatedStreet]->.relationsWithRoleStreet;
15 /* Find all aS relations with empty role-way members */
16 way(r.allASRelations:"");
17 rel(bw:"")[type=associatedStreet]->.relationsWithEmptyRole;
19 /* Find all relations with node members */
20 node(r.allASRelations);
21 rel(bn)[type=associatedStreet]->.relationsWithNode;
23 /* Check if there are member ways with role 'house' not having a building tag */
24 way(r.allASRelations:"house")[!building];
25 rel(bn)[type=associatedStreet]->.relationsWoHouseBuilding;
27 /* Take all aS relations and remove all relations we want to exclude */
28 ( ( ( (.allASRelations; - .relationsWithRoleStreet;); 
29   - .relationsWithEmptyRole; ); 
30  - .relationsWithNode; );
31  - .relationsWoHouseBuilding);
33 /* add ways and nodes for output*/
34 (._;  );
35 out meta;

Find house numbers without street

The following Overpass API query retrieves all Nodes, Ways and Relations that have a addr:housenumber-tag and no addr:street nor addr:place tag. For this collection, we remove all Nodes/Ways/Relations that take part in an associatedStreet-Relation with a role "house".


  • The query assumes that the associatedStreet-relation is conform with the wiki and that it contains at least one member with the role "street", such that the street can be deduced. This is not verified by the query!
  • associatedStreet-Relations without street-roles can be found with the query= "unnütze associatedStreet-Relationen ermitteln" . This problem has to be resolved first, as it would prevent the correct retrieval of house numbers.
  • The name-tag on the relation is ignored. Warning: in the solution of User:Gehrke for #osmwa3334 requires a name tag on the associatedStreet-Relation, but ignores the members with the role "street"[1]

The search area can be adapted in the first line, more details in Forum Thread.

 1 area[type=boundary]["de:amtlicher_gemeindeschluessel"="08115003"]->.boundaryarea;
 2 rel(area.boundaryarea)[type=associatedStreet]->.associatedStreet;
 4 way(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesWay;
 5 way(r.associatedStreet:"house")->.asHouseWay;
 6 ((.allHousesWay; - .asHouseWay); >; );out meta;
 8 node(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesNode;
 9 node(r.associatedStreet:"house")->.asHouseNode;
10 ((.allHousesNode; - .asHouseNode););out meta;
12 rel(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesRel;
13 rel(r.associatedStreet:"house")->.asHouseRel;
14 ((.allHousesRel; - .asHouseRel); >>; );out meta;

Alternatively, one could do a search via Nominatim:

 1 {{nominatimArea:"Regionalverband Saarbrücken"}}
 2 (._; )->.boundaryarea;
 4 /* Shows the boundary area as extra check - one is free to activate this step */
 5 /* rel(pivot.boundaryarea);(way(r);>;);out; */
 7 rel(area.boundaryarea)[type=associatedStreet]->.associatedStreet;
 9 way(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesWay;
10 way(r.associatedStreet:"house")->.asHouseWay;
11 ((.allHousesWay; - .asHouseWay); >; );out meta;
13 node(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesNode;
14 node(r.associatedStreet:"house")->.asHouseNode;
15 ((.allHousesNode; - .asHouseNode););out meta;
17 rel(area.boundaryarea)["addr:housenumber"][!"addr:street"][!"addr:place"]->.allHousesRel;
18 rel(r.associatedStreet:"house")->.asHouseRel;
19 ((.allHousesRel; - .asHouseRel); >>; );out meta;

Nehme entweder "addr:street", "addr:place" oder "name" von associatedStreet. Trifft nichts zu, ist die Straße "null". Ich zähle nun alle Fälle (nur nodes und ways), wo es zwar eine Hausnummer gibt, aber die Straße "null"

Count number of addr:housenumber in an area

The following query counts the number of addr:housenumber=* nodes/ways/relations in an area. Duplicate addresses (i.e. multiple occurrences of the same address) are not filtered out. The query result is in csv format starting with the total number of addresses, followed by the number of nodes, ways and finally relations.

[out:csv(::count, ::"count:nodes", ::"count:ways", ::"count:relations")][timeout:25];
out count;

Overpass Turbo Link

Ways that are part of a "Bundesstraßenrelation"", but do not have a ref-tag

Normally, one would expect that the properties of a relation are also applied to the member ways, so that it is not needed to set those tags explicitly on the ways. However, it turns out that the common practice is to set this ref also on each way. This query shows all ways that do not have the ref-tag.

out meta;

It is also possible to have a ref tag, but that the way does not belong to a relation.

     way(area.a)[highway][ref~"^B.*"]; - 

For a selected area (in the example Saarland), the query retrieves all Ways whose ref-tag starts with a "B". From this collection, we remove all Ways that are part of a relation with type=route, route=road and that have a ref that starts with "B". The remaining federal streets, which are not part of a relation, are returned together with their nodes, in order to show them on a map.

Media:Example.ogg== Examples for Styles in overpass turbo (MapCSS) ==

Hiking routes

The following query for Overpass Turbo shows all hiking-relations in the current bounding box (route=hiking and network=?wn), such as in the Lonvia-style. The color for the ways is taken from the relation.


{ color:green; fill-color:green; }

relation[network=lwn] way
{ color:blue; fill-color:cyan; }

relation[network=iwn] way
{ color:red; fill-color:red; }

relation[network=nwn] way
{ color:green; fill-color:green; }

relation[network=rwn] way
{ color:yellow; fill-color:yellow; }


It is possible that this is not 100% correct, please test and adapt when needed. (received via osm-dev, MapCSS was corrected, Query simplified)


This thema can be analysed with the queries below

Mailboxes, coloured depending on availability of the collection time tag


{ color:red; fill-color: red;}

{ color:green; fill-color:green; }


Overpass Turbo Link

Alternative that also checks the syntax of the collection time

Overpass Turbo Link - valid for 2017


 <osm-script output="json">
    <query type="node">
      <has-kv k="{{key1}}" v="{{value1}}"/>
      <bbox-query {{bbox}}/>
  <print mode="body"/>
  <recurse type="down"/>
  <print mode="skeleton"/>

    color: #ffffff;
    fill-color: #ff0000;
    fill-opacity: 0.8;
    color: #0000ff;
    fill-color: #ff0000;
    fill-opacity: 0.8;
    color: #ffff00;
    fill-color: #ffff00;
    fill-opacity: 0.8;
  node[lastcheck][operator] {
    color: #0000ff;
    fill-color: #ffff00;
    fill-opacity: 0.8;
    color: #ffff00;
    fill-color: #00ff00;
    fill-opacity: 0.8;
    color: #0000ff;
    fill-color: #00ff00;
    fill-opacity: 0.8;
    color: #ffff00;
    fill-color: #55aa00;
    fill-opacity: 0.8;
  node[collection_times:lastcheck=~/2016-*.  /][operator],
    color: #0000ff;
    fill-color: #55aa00;
    fill-opacity: 0.8;
    color: #ffff00;
    fill-color: #aa5500;
    fill-opacity: 0.8;
    color: #0000ff;
    fill-color: #aa5500;
    fill-opacity: 0.8;