Overpass API/Language Guide

From OpenStreetMap Wiki
Jump to: navigation, search

Overpass turboOverpass APILanguage referenceQuery examplesLanguage GuideAdvanced examplesSparse EditingFAQMapCSS — More: Overpass turbo, Overpass API

Available languages — Overpass API/Language Guide
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 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 português do Brasil 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 беларуская български қазақша македонски монгол русский тоҷикӣ українська Ελληνικά Հայերեն ქართული नेपाली मराठी हिन्दी অসমীয়া বাংলা ਪੰਜਾਬੀ ગુજરાતી ଓଡ଼ିଆ தமிழ் తెలుగు ಕನ್ನಡ മലയാളം සිංහල ไทย မြန်မာဘာသာ ລາວ ភាសាខ្មែរ ⵜⴰⵎⴰⵣⵉⵖⵜ አማርኛ 한국어 日本語 中文(简体)‎ 吴语 粵語 中文(繁體)‎ ייִדיש עברית اردو العربية پښتو سنڌي فارسی ދިވެހިބަސް

This guide shows you a lot of examples for queries with Overpass API. You are invited to adapt the queries to your particular need. You may also want to consult Overpass QL.



Contents

Background and concepts

Overpass API allows to query for OSM data by your own search criteria. For this purpose, it has a specifically crafted query language.

The basic semantics of Overpass API is that flows of OSM data (nodes, ways...) are generated and modified by statements, which are executed one after another. The following simple query can for instance generate a flow of data containing all the nodes in a given bounding box, and print it:

node(50.745,7.17,50.75,7.18);
out;

You can then filter further the resulting flow, looking only for the bus stops:

node(50.745,7.17,50.75,7.18)[highway=bus_stop];
out;

Or you could also extend the result to include the ways which are referencing using the selected nodes. In this case, you may also want to extend the result with all nodes referenced by these ways:

node(50.745,7.17,50.75,7.18);way(bn);
( ._; >; );
out;

These statements and their syntax are described in more details below.

The Overpass API languages

Overpass API now offers its full expressive power within a single HTTP GET request. For this purpose, the new query language Overpass QL is introduced in parallel to the established XML query language. You can always convert between the two: just paste one of the examples below into http://overpass-api.de/convert_form.html. You can choose there to get the output in:

  • XML query format: this matches the XML form below in all the examples.
  • to pretty Overpass QL: this matches the Overpass QL form below.
  • to concise Overpass QL: this yields a one-line HTTP GET request for the same expression.

To execute the query, use instead http://overpass-api.de/query_form.html.

Overpass QL Basics

Examples of the QL syntax are provided below. The QL syntax is more concise, and is to some extend similar to C-like programming languages. A statement always ends with a semicolon ";". Furthermore, a statement is either:

  • a query statement, starting with "node", "way", "relation", "rel" (short for "relation"), or one of the special statements ">", ">>", "<", or "<<", or
  • an output statement, starting with "out".

Query statements consist of the type of object to be retrieved

 node
 way
 rel

and of at least one clause that described the object to be retrieved, e.g.

 ["name"="Berlin"]

to give e.g. this query

 node["name"="Berlin"];

which retrieves all nodes named Berlin.

Overpass QL clauses

There are different types of clauses that you can use to select nodes, ways, and relations.

Tag request clauses (or "tag filters")

All variants of tag requests; e.g.,

  ["key"="value"]
  ["key"]
  ["key"~"value"]
  ["key"!="value"]
  ["key"!~"value"]

Bounding box clauses ("bbox query", "bounding box filter")

Or bounding box clauses

  (51.0,7.0,52.0,8.0)

Bounding box clauses always start with the lower latitude followed by lower longitude, then upper latitude then upper longitude. Note that this is different from the ordering in the XAPI syntax. The XML syntax is safeguarded by using named parameters.

Recursion clauses ("recursion filters")

Or recursion forward or backward about membership links

  (r)
  (w)
  (n)
  (br)
  (bw)
  (bn)
  (>)
  (>>)
  (<)
  (<<)

Special clauses ("special filters")

Or special clauses of the form "(type:value)", e.g. the "(around:value)" clause.

More details are provided in the respective parts of the Usage Examples.

About the links

Most examples are illustrated with showing links to a map. This is still a very experimental solution. The bounding box is fixed to show always the German town Bonn. And some queries take quite a lot of time, maybe over a minute if none of the needed data is in the cache on the server. The symbols are ugly, but this could also be changed for a mashup layer aiming at end users. They should be primarily easy to find.

Usage examples: All data in a bounding box

Let's start looking at some examples for queries by looking at querying by bounding box.

The bounding box

The bbox-query lets you download all nodes, ways or relations from the given bounding box. Specify with:

  • s the southern limit in decimal degrees (lowest latitude, measured along a meridian from the nearest point on the Equator, negative in the Southern Hemisphere)
  • w the western limit in decimal degrees (lowest longitude, measured along a parallel from the nearest point on the Greenwich meridian, negative in the Western Hemisphere)
  • n the northern limit in decimal degrees (highest latitude, measured along a meridian from the nearest point on the Equator, positive in the Northern Hemisphere)
  • e the eastern limit in decimal degrees (highest longitude, measured along a parallel from the nearest point on the Greenwich meridian, positive in the Eastern Hemisphere))

These coordinates are specified in the OSM database and in the OverPass API by vertically projecting the real points to nodes on the WGS84 ellipsoid.

Please note also that the Overpass QL form has the implicit order (s, w, n, e). This is more concise than the explicit XML syntax, but of course requires some care to get the order right. The western limit is higher than the eastern limit if and only if your query surpasses the longitude ±180.0 degrees with a bounding box passing through the Antimeridian (in that case the query is equivalent to the union of two bounding boxes on each side the Antemeridian.

For areas that aren't boxes, see the Poly command.

Retrieving all nodes within a bounding box

All nodes in a small sample bounding box:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <bbox-query e="7.157" n="50.748" s="50.746" w="7.154"/>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node(50.746,7.154,50.748,7.157);
out body;

Display result: OpenLayers map, JSON, XML.

Ways

In a similar fashion, you can get all ways of the bounding box. A way is found not only if it has a node inside the bounding box but also if it just crosses somewhere the bounding box.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="way">
    <bbox-query e="7.157" n="50.748" s="50.746" w="7.154"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
way(50.746,7.154,50.748,7.157);
out body;

Display result: OpenLayers map, JSON, XML.

Relations

A relation is found in a bounding box if it has a member of type node or way within the bounding box.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="relation">
    <bbox-query e="7.157" n="50.748" s="50.746" w="7.154"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
relation(50.746,7.154,50.748,7.157);
out body;

Display result: OpenLayers map, JSON, XML.

Usage examples: Simple queries for tags and bounding boxes

Wherever you see the this symbol: overpass turbo icon, you can click it to use overpass turbo for inspecting the query and its results.

Finding something in the OpenStreetMap data always means to search for a location or for the values of certain tags. You can choose any key for the tag in the following examples. In a first step, we find objects by their names, thus we search for certain values of the key "name".

By exact name

In our first example, we search for a node by the value of its name tag:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node["name"="Gielgen"];
out body;

Display result: OpenLayers map, JSON, XML.

By exact name and rough location

If this isn't exact enough, you could also specify a bounding box to get results from only within a certain bounding box. The coordinate order is (lower lat., lower lon., upper lat., upper lon.). If you don't have a bounding box, the following example may fit better to you:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"="Gielgen"]
  (50.7,7.1,50.8,7.2);
out body;

Display result: OpenLayers map, JSON, XML.


Non-exact names

But even when you don't know the exact name, you can find the object. For that purpose, Overpass API supports (POSIX extended) regular expressions. We give a couple of examples for useful regular expressions.

The first example searches for any node that contains the substring "holtorf" in its name:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" regv="holtorf"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"~"holtorf"]
  (50.7,7.1,50.8,7.25);
out body;

Display result: OpenLayers map, JSON, XML.

The second example searches for any node that has the substring "Holtorf" as the beginning of the name:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" regv="^Holtorf"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"~"^Holtorf"]
  (50.7,7.1,50.8,7.25);
out body;

Display result: OpenLayers map, JSON, XML.

The third example searches for any node that has the substring "holtorf" as the end of the name:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" regv="Holtorf$"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"~"holtorf$"]
  (50.7,7.1,50.8,7.25);
out body;

Display result: OpenLayers map, JSON, XML.

Of course you could also search for "^Holtorf$", but this is the same as a simple search for equal value.

And you can search case insensitive with regular expressions by enclosing both variants in brackets:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" regv="[hH]oltorf"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"~"[hH]oltorf"]
  (50.7,7.1,50.8,7.25);
out body;

Display result: OpenLayers map, JSON, XML.

Accents and decorated characters

A lot of European languages have modified variants of the well known Latin characters, not only "e" but also "é" or "ê". You can obtain them with a regular expression:

By list listing candidates:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" regv="H[oôóòö]ltorf" />
    <bbox-query s="50.7" w="7.1" n="50.8" e="7.25" />
  </query>
  <print />
</osm-script>
try it yourself in overpass-turbo
node
  ["name"~"H[oôóòö]ltorf"]
  (50.7,7.1,50.8,7.25);

out body;

Or by leaving a dot wildcard:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" regv="H.ltorf" />
    <bbox-query s="50.7" w="7.1" n="50.8" e="7.25" />
  </query>
  <print />
</osm-script>
try it yourself in overpass-turbo
node
  ["name"~"H.ltorf"]
  (50.7,7.1,50.8,7.25);

out body;

Please note:

  • A single wildcard dot replaces a single UTF-8 encoded code point, not necessarily only a single byte in that encoding (only the characters in the 7-bit US-ASCII subset are encoded in UTF-8 on one byte). So a single dot matches "e" as well as "é" or "ê" (but also any other letter, including non-Latin; "-" or a space), but not "ø̄" which is not encodable as a single codepoint, but as the precombined letter barred o followed by the combining macron, or as the precombined letter o with macron followed by the combiningbar overlay, or as the base letter o followed in any order by the combining macron and the combining bar overlay).
  • Letters with combining diacritics should be stored in the database in Unicode “Normalized Form Composed”, or NFC. Most letters with diacritics used in modern European languages are composable in NFC, but not every pair consisting in a base letter with by a single combining diacritic are composable into a single code point, and some letters with two combining diacritics are still encodable in NFC with a single codepoint, such as "ế" used in Vietnam and will be matched by a single wildcard dot), instead of the canonically equivalent encoding as the base letter "e" followed by the two distinct combining diacritics in either order (one of this order is the “Normalized Form Decomposed” (NFD) used by some OSes like MacOS (which prefers storing filenames encoded as NFD in its filesystem), or by some keyboard drivers or text editors.
  • For this reason it is not easy to match all possible encoding forms of the same base letter e (including lettercase variants) with or without one or more combining diacritics: the Overpass API still does not support matching regular expressions based on collation (whose rules depend on the language and script used, and on the collator used for that language and script, and on the collation strength parameters (such as letter case sensitivity). Instead you can enumerate expected the letter variants in [square] brackets, or use unions of queries for each orthography or encoding of the letter you're looking for.

One or another name

If you want to allow two alternative values, you can use a pipe for that.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" regv="holtorf|Gielgen"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"~"holtorf|Gielgen"]
  (50.7,7.1,50.8,7.25);
out body;

Display result: OpenLayers map, JSON, XML.

More information about (POSIX extended) regular expressions can be found on the console or by your favourite search engine with "man 7 regex".

Negation

Regular expressions don't allow negation on their own. For that reason, there is an explicit negation operator in Overpass QL.

For example, the following query yields all ways that do not have a highway key value:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="way">
    <has-kv k="highway" modv="not" regv="."/>
    <bbox-query e="7.18" n="50.75" s="50.74" w="7.17"/>
  </query>
  <print limit="" mode="body" order="id"/>
</osm-script>
try it yourself in overpass-turbo
way
  ["highway"!~"."]
  (50.74,7.17,50.75,7.18);
out body;

Display result: OpenLayers map, JSON, XML.

As a second example, you can restrict a query for bus stops to those that have a shelter. Technically, we search for nodes with "highway"="bus_stop" and tag "shelter" present, but not set to "no".

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="highway" v="bus_stop"/>
    <has-kv k="shelter"/>
    <has-kv k="shelter" modv="not" v="no"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["highway"="bus_stop"]
  ["shelter"]
  ["shelter"!="no"]
  (50.7,7.1,50.8,7.25);
out body;

Display result: OpenLayers map, JSON, XML.

The same thing with regular expressions:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="highway" v="bus_stop"/>
    <has-kv k="shelter"/>
    <has-kv k="shelter" modv="not" regv="no"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["highway"="bus_stop"]
  ["shelter"]
  ["shelter"!~"no"]
  (50.7,7.1,50.8,7.25);
out body;

Display result: OpenLayers map, JSON, XML.

Multiple tags

Of course you can search also for nodes that have a tag "highway" to value "bus_stop" and a tag "shelter" to value "yes":

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="highway" v="bus_stop"/>
    <has-kv k="shelter" v="yes"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["highway"="bus_stop"]
  ["shelter"="yes"]
  (50.7,7.1,50.8,7.25);
out body;

Display result: OpenLayers map, JSON, XML.

Streets and other ways

Every of the above queries also works for ways or relations. We search for the street "Gielgenstraße" within the now well-known bounding box:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="way">
    <has-kv k="name" v="Gielgenstraße"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
way
  ["name"="Gielgenstraße"]
  (50.7,7.1,50.8,7.25);
out;

Display result: OpenLayers map, JSON, XML.

Please note that you need to also request the nodes of the way if you want to display the way in map (or need the coordinates for another reason. This is done with an extra-recurse down statement. To get also the way, we put both in an union statement. All these statements are explained further down.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="way">
    <has-kv k="name" v="Gielgenstraße"/>
    <bbox-query e="7.25" n="50.8" s="50.7" w="7.1"/>
  </query>
  <union>
    <item />
    <recurse type="way-node"/>
  </union>
  <print/>
</osm-script>
try it yourself in overpass-turbo
(
  way
    ["name"="Gielgenstraße"]
    (50.7,7.1,50.8,7.25);
  >;
);
out;

Relations

And now we search for the relation of "network"="VRS" and "ref"="636". This is a local bus service. As the network shortcut is unique, we don't need a bounding box or any other similar aid.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="relation">
    <has-kv k="network" v="VRS"/>
    <has-kv k="ref" v="636"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
relation
  ["network"="VRS"]
  ["ref"="636"];
out body;

Display result: OpenLayers map, JSON, XML.

Query by element id

If you want a specific id from the database, you can query for it. We give

  • an example for a node:
Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <id-query ref="507464799" type="node"/>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node(507464799);
out;

Display result: OpenLayers map, JSON, XML.

  • an example for a way:
Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <id-query ref="24777894" type="way"/>
  <print/>
</osm-script>
try it yourself in overpass-turbo
way(24777894);
out;

Display result: OpenLayers map, JSON, XML.

  • an example for a relation:
Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <id-query ref="1745069" type="relation"/>
  <print/>
</osm-script>
try it yourself in overpass-turbo
relation(1745069);
out;

Display result: OpenLayers map, JSON, XML.

The union operator: combining results and forming sets

Combining results with the union operator

And, finally, we search for all kind of objects with a certain tag within a bounding box. You need to repeat the tag for every type and to use the union operator. To allow us displaying everything on a map, we also ask for the nodes and ways that are referred by the relations and ways in the result:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <union>
    <query type="node">
      <has-kv k="amenity" v="fire_station"/>
      <bbox-query e="7.3" n="50.8" s="50.6" w="7.0"/>
    </query>
    <query type="way">
      <has-kv k="amenity" modv="" v="fire_station"/>
      <bbox-query e="7.3" n="50.8" s="50.6" w="7.0"/>
    </query>
    <query type="relation">
      <has-kv k="amenity" modv="" v="fire_station"/>
      <bbox-query e="7.3" n="50.8" s="50.6" w="7.0"/>
    </query>
  </union>
  <union>
    <item/>
    <recurse type="down"/>
  </union>
  <print/>
</osm-script>
try it yourself in overpass-turbo
(
  node
    ["amenity"="fire_station"]
    (50.6,7.0,50.8,7.3);
  way
    ["amenity"="fire_station"]
    (50.6,7.0,50.8,7.3);
  rel
    ["amenity"="fire_station"]
    (50.6,7.0,50.8,7.3);
);
(._;>;);
out;

Display result: OpenLayers map JSON, XML.

The default set "_" and recalling the default set "._"

Similar to a default variable in the programming language PERL, Overpass QL has a default set, called "_". Let's look at the last query again:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <union>
    <query type="node">
      <has-kv k="amenity" v="fire_station"/>
      <bbox-query e="7.3" n="50.8" s="50.6" w="7.0"/>
    </query>
    <query type="way">
      <has-kv k="amenity" modv="" v="fire_station"/>
      <bbox-query e="7.3" n="50.8" s="50.6" w="7.0"/>
    </query>
    <query type="relation">
      <has-kv k="amenity" modv="" v="fire_station"/>
      <bbox-query e="7.3" n="50.8" s="50.6" w="7.0"/>
    </query>
  </union>
  <union>
    <item/>
    <recurse type="down"/>
  </union>
  <print/>
</osm-script>
try it yourself in overpass-turbo
(
  node
    ["amenity"="fire_station"]
    (50.6,7.0,50.8,7.3);
  way
    ["amenity"="fire_station"]
    (50.6,7.0,50.8,7.3);
  rel
    ["amenity"="fire_station"]
    (50.6,7.0,50.8,7.3);
);
(
    ._;
    >;
);
out;

Display result: OpenLayers map JSON, XML.

The query consists of

  • A first union (nodes, ways, relations), indicated by the "union" statement or first set of brackets "(...);" in QL. The output of that union is placed in "_".
  • A second union "(._;>;);" in QL, consisting of
    • recalling the default set ("item" or "._;" in QL)
    • recurse down, (">;" in QL)

The output of that second union is again placed in "_", which is then printed.

The prInt command prints the content of the container "_" at execution time. This comes very close to "the last set defined".


Other named sets

The item standalone query consists only of an input set prefix. It takes the input set specified by its prefix. This is in particular useful for union statements: it reproduces its input set as (part of the) result of the union statement. The most common usage is the usage with the default input set:

  ._;

In the context of a union statement, the following will return all items in the default input set along with the recurse down result.

  (._; >;);

But of course other sets are possible too:

  .a;

In the context of a union statement:

  (.a; .a >;);

Note: Subsequent statements in a union statement are not impacted by the item statement. In particular `.a;` does not add the contents of the input set to the default item set "_".

The item statement can also be used as filter.

Union and assigning sets: .->a

Overpass has an imperative execution model. In particular, the statements are executed one after another, and each statement is terminated by a semicolon. Each statement puts its results into a container in its memory named by default "_". If a statement needs input, it reads its input from "_". For example, the print statement reads from "_". Sometimes it is useful to use more than one container during a more complex query. In this case, the output can be redirected to another container, e.g. with name "x". This is what the above syntax controls.

The union block statement is written as a pair of parentheses. Inside the union, any sequence of statements can be placed, including nested union and foreach statements.

  (statement_1; statement_2; )[->.result_set];

It takes no input set. It produces a result set. Its result set is the union of the result sets of all sub-statements, regardless of whether a sub-statement has a redirected result set or not.

Example:

  (node[name="Foo"];way[name="Foo"];);

This collects in the first statement all nodes that have a name tag "Foo" and in the second statement all ways that have a name tag "Foo". After the union statement, the result set is the union of the result sets of both statements.

The result set of the union statement can be redirected with the usual postfix notation.

Example:

  (node[name="Foo"];way[name="Foo"];)->.a;

Same as the preceding example, but the result is written into the variable a.

Limitation : Note foreach and print statements cannot be sub-element of element union.

Recursion: ">", "<", etc

Recursion clauses

We already met the recursion clauses:

  (r)
  (w)
  (n)
  (br)
  (bw)
  (bn)
  (>)
  (>>)
  (<)
  (<<)

We'll now have a look at some of these.

Why we need recursion

In general, you will be rather interested in complete data than just elements of a single type. First, there are several valid definitions of what "complete map data" means. The first unclear topic is what to do with nodes outside the bounding box which are members of ways that lie partly inside the bounding box.

The same question repeats for relations. If you wait for a turn restriction, you may prefer to get all elements of the relation included. If your bounding box hits for example the border of Russia, you likely don't want to download ten thousands kilometers of boundary around half the world.

A second question for relations is whether relations on relations should be included.

For that reason, we subsequently give examples for several variants of map calls. It is a discipline where the query paradigm shows its strength: you can construct a query of any flavor you want. Just choose from the examples below or modify them to your needs.

The particular statements of the calls are explained in the more advanced sections further below.

Recursing down: ">" and ">>"


Recursing up: "<" and "<<"

This call includes all nodes in the bounding box, all ways that have such a node as member, and all relations that have such a node or such a way as members. Please observe that not all returned ways or relations are displayed in OpenLayers because Open Layers requires all nodes of a way or members of a relation to be present.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <union into="_">
    <bbox-query e="7.157" n="50.748" s="50.746" w="7.154"/>
    <recurse type="up"/>
  </union>
  <print mode="meta"/>
</osm-script>
try it yourself in overpass-turbo
(
  node(50.746,7.154,50.748,7.157);
  <;
);
out meta;

More about this query below.

Recursing up and down: Completed ways and relations

This call includes all nodes in the bounding box, all ways referring to any of these nodes, all member nodes of these ways whether these are inside the bounding box or not, all relations that have such a node or such a way as a member, and their node and way member, and even the nodes of these ways. Note that due to the involved relations, objects from quite far outside the bounding box are included.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <union into="_">
    <bbox-query e="7.157" n="50.748" s="50.746" w="7.154"/>
    <recurse type="up"/>
    <recurse type="down"/>
  </union>
  <print limit="" mode="meta" order="id"/>
</osm-script>
try it yourself in overpass-turbo
(
  node(50.746,7.154,50.748,7.157);
  <;
  >;
);
out meta;

More about this query below.

More complex recursion

See Overpass API/Advanced examples.

Special clauses: around and poly

"around" - finding something near something else

A less technical way to get one of multiple results can be to find something by providing a nearby location. For example, you can search for a location called "Gielgen" in a 1000 meter radius of a location called "Bonn".

(Be aware that the computations are made with a non-spheroid formula (see more here), that may cause some approximations)

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Bonn"/>
  </query>
  <query type="node">
    <around radius="1000"/>
    <has-kv k="name" v="Gielgen"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node["name"="Bonn"];
node
  (around:1000)
  ["name"="Gielgen"];
out body;

Display result: OpenLayers map, JSON, XML.

Select region by polygon

In addition to bounding boxes, now also polygons can be used to cut out a region for download. A simple example is a part of my home town in Germany:

try it yourself in overpass-turbo
(
  node(poly:"50.7 7.1 50.7 7.12 50.71 7.11");
  <;
);
out meta;

Display result: XML, JSON

More general, the examples from above can be adapted to the polygon variant: Just replace the bbox condition by the polygon condition. The only restriction is that polygons can only be used as borders for nodes. Please use one of the various recurse statements to get ways and relations from it.

If you want to use a polygon like the output of rel2poly.pl as a boundary, you can convert it with the following bash script poly2request.sh:

#!/usr/bin/env bash

echo -n '(node(poly:"'
awk '{ if ($1 != "1" && $1 != "polygon" && $1 != "END") printf $2" "$1" "; }'
echo '");<;);out;'

Now you can get your download with e.g.

./poly2request.sh <polygon.txt >request.txt
wget --post-file=request.txt http://overpass-api.de/api/interpreter

Control output format (print, out)

Print does what its name lets you expect: it prints the contents queried so far as returned data. Thus, almost every query ends with a print statement. For the sake of brevity, print has been renamed to out; in Overpass QL.

Degree of verbosity

Print exists in four different degrees of verbosity, which are specified by the mode attribute: body (default), skeleton, ids_only, and meta. Those are explained by the following examples, giving the relevant parts of the query and the result. The more concise the output is, the faster the query runs. For that reason, skeleton is used in this guide for the OpenLayers layers. meta is likely to be the best choice if you want to edit the data. If you are unsure what you need, try body first.

XML QL Description
<print/> out;
or
out body;
The normal print mode.
<print mode="skeleton"> out skel; The skeleton print mode is somewhat shorter than the usual print mode: No tags are printed in this mode, only ids, child elements, and coordinates of nodes.
<print mode="ids_only"> out ids; ids_only is the shortest print mode; only ids are printed. ids_only is shortened to ids in Overpass QL. Note that this doesn't work with OpenLayers because no coordinates are returned.
<print mode="meta"> out meta; meta is the most complete mode. Beside child elements and tags, also the meta data (timestamp, version, changeset, user name and id) is printed.


Normal (body)

body is the default mode: ids, child elements, and tags are printed. If you want the mode body, you can omit the mode attribute.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
    <has-kv k="place" v="suburb"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"="Gielgen"]
  ["place"="suburb"];
out;

Display result: OpenLayers map, JSON, XML.

Concise (skeleton, skel)

The skeleton print mode is somewhat shorter: No tags are printed in this mode, only ids, child elements, and coordinates of nodes:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
    <has-kv k="place" v="suburb"/>
  </query>
  <print mode="skeleton"/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"="Gielgen"]
  ["place"="suburb"];
out skel;

Display result: OpenLayers map, JSON, XML.

Brief (ids_only, ids)

ids_only is the shortest print mode; only ids are printed. ids_only is shortened to ids in Overpass QL. Note that this doesn't work with OpenLayers because no coordinates are returned.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
    <has-kv k="place" v="suburb"/>
  </query>
  <print mode="ids_only"/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"="Gielgen"]
  ["place"="suburb"];
out ids;

Display result: OpenLayers map, JSON, XML.

Verbose (meta, meta)

meta is the most complete mode. Beside child elements and tags, also the meta data (timestamp, version, changeset, user name and id) is printed:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
    <has-kv k="place" v="suburb"/>
  </query>
  <print mode="meta"/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"="Gielgen"]
  ["place"="suburb"];
out meta;

Display result: OpenLayers map, JSON, XML.

This meta data is, in particular, necessary in order to handle the result in JOSM.

Order attribute for faster results (quadtile, qt)

You can also change the order of the elements. By default, elements are ordered by their id (i.e., order="id"). You get faster results if you allow elements to be ordered by their location (i.e., order="quadtile", or qt in Overpass QL).

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
    <has-kv k="place" v="suburb"/>
  </query>
  <print order="quadtile"/>
</osm-script>
try it yourself in overpass-turbo
node
  ["name"="Gielgen"]
  ["place"="suburb"];
out qt;

Display result: OpenLayers map, JSON, XML.

Limit attribute to limit elements (limit, n)

It is also possible to limit the number of printed elements:

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
  </query>
  <print limit="2"/>
</osm-script>
try it yourself in overpass-turbo
node["name"="Gielgen"];
out 2;

Display result: OpenLayers map, JSON, XML.

This limits the output to at most two nodes.

Geometry attribute (center, center)

Add the center of the object's boundingbox to the output, not guaranteed to be on the object's area.

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script>
  <query type="relation">
    <has-kv k="boundary" v="postal_code"/>
    <has-kv k="postal_code" v="65343"/>
  </query>
  <print geometry="center"/>
</osm-script>
try it yourself in overpass-turbo
rel["boundary"="postal_code"][postal_code=65343];
out center;

OSM Scrip options

Choose file format (ouput=json, [out:json])

You can get the result as JSON or as XML. By default, you get the data as XML. To get the result as JSON, just add a JSON request to the query header (before the first statement):

Overpass XML Overpass QL
link=http://overpass-turbo.eu/?Q=%3Cosm-script%20output%3D%22json%22%3E%0A%20%20%3Cquery%20type%3D%22node%22%3E%0A%20%20%20%20%3Chas-kv%20k%3D%22name%22%20v%3D%22Gielgen%22%2F%3E%0A%20%20%3C%has-kv k="name" v="Gielgen"/>     2Fquery%3E%0A%20%20%3Cprint%2F%3E%0A%3C%2Fosm-script%3E&C=50.73515;7.20519;14&R
<osm-script output="json">
  <query type="node">
    <has-kv k="name" v="Gielgen"/>
  </query>
  <print/>
</osm-script>
try it yourself in overpass-turbo
[out:json];
node["name"="Gielgen"];
out body;

CSV (Comma Separated Values) format: see Overpass QL wiki page.

Display result: OpenLayers map, JSON, XML.

Resource management options (osm-script)

The osm-script is silently added if you don't specify it explicitly when using the XML syntax. The reason to specify one explicitly is to tweak the resource management options by setting optional XML attributes (equivalent bracketted options may also be specified in an empty statement at start of your query when using the QL syntax).

Overpass XML Overpass QL
try it yourself in overpass-turbo
<osm-script timeout="900" element-limit="1073741824">
  <bbox-query s="51.15" w="7.0" n="51.35" e="7.3"/>
  <print/>
</osm-script>
try it yourself in overpass-turbo
[timeout:900][maxsize:1073741824];
node(51.15,7.0,51.35,7.3);
out;

This query extends the timeout from 3 minutes to 15 minutes (written as 900 seconds). Additionally, the soft quota for memory usage is set to 1 GiB (equals 1073741824 byte).

Warning: when running this example, more than 100 MiB of data will be retrieved (even if it does not recurse up to give all details like in the first example, here it will only retrieve a flat list of nodes with their tags). Overpass will alert you if you run it directly in your browser to render the data on the map, the browser tab may crash if you continue loading it. The results of such large requests should be downloaded for processing by other tools.

These resource limits cannot be set to arbitrary high values: each Overpass API instance may refuse to extend them above some threshold (depending on server capabilities or current server load), or the query may just fail with an error message (and non-OK HTTP server error status).

Further pages and resources on the openstreetmap wiki