Overpass API/Overpass QL

From OpenStreetMap Wiki
Jump to: navigation, search
Available languages — Overpass API/Overpass QL
· Afrikaans · Alemannisch · aragonés · asturianu · azərbaycanca · Bahasa Indonesia · Bahasa Melayu · Bân-lâm-gú · Basa Jawa · Basa Sunda · 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 · Tagalog · Tiếng Việt · Türkçe · Vahcuengh · vèneto · Wolof · Yorùbá · Zazaki · српски / srpski · беларуская · български · қазақша · македонски · монгол · русский · тоҷикӣ · українська · Ελληνικά · Հայերեն · ქართული · नेपाली · मराठी · हिन्दी · भोजपुरी · অসমীয়া · বাংলা · ਪੰਜਾਬੀ · ગુજરાતી · ଓଡ଼ିଆ · தமிழ் · తెలుగు · ಕನ್ನಡ · മലയാളം · සිංහල · བོད་ཡིག · ไทย · မြန်မာဘာသာ · ລາວ · ភាសាខ្មែរ · ⵜⴰⵎⴰⵣⵉⵖⵜ ⵜⴰⵏⴰⵡⴰⵢⵜ‎ · አማርኛ · 한국어 · 日本語 · 中文(简体)‎ · 中文(繁體)‎ · 吴语 · 粵語 · ייִדיש · עברית · اردو · العربية · پښتو · سنڌي · فارسی · ދިވެހިބަސް
Overpass API logo.svg
±
Overpass API · Language reference · Language guide · Technical terms · Areas · Query examples · Advanced examples · Sparse Editing · Permanent ID · FAQ · more · Web site
Servers status · Versions · Development · Technical design · Installation · XAPI compatibility layer · Public transport sketch lines · Applications · Source code and issues
Overpass turbo · Wizard · Overpass turbo shortcuts · MapCSS stylesheets · Export to GeoJSON · more · Source code and issues · Web site

Contents

Overview

Overpass QL is the second query language for the Overpass API and was designed as an alternative to Overpass XML. It has a C style syntax: the whole query source code is divided in statements, and every statement ends with a semicolon. It has imperative semantics: the statements are processed one after another and change the execution state according to their semantics.

The execution state consists of the default set, potentially other named sets, and for block statements a stack. A set can contain nodes, ways, relations and areas, also of mixed type and of any number. Sets are created as result sets of statements and are read by subsequent statements as input. Unless you specify a named set as input or result, all input is implicitly read from and all results are written to the default variable named "_" (a single underscore). Names for sets may consist of letters, digits and the underscore but must not start with a digit. Once a new result is (implicitly or explicitly) assigned to an existing set, its previous contents will be replaced and are no longer available. Sets always have global visibility.

There are several different types of statement. You almost always need the print statement, which is called an action, because it has an effect outside the execution state (the output). The other statements are grouped into

  • Standalone queries: These are complete statements on their own.
  • Filters: They are always part of a query statement and contain the interesting selectors and filters.
  • Block statements: They group statements and enable disjunctions as well as loops.
  • Settings: Things like output format that can be set once at the beginning.

Sets

Overpass QL can work with sets. By default, everything is read from and sent to the default set "_".

For example

  node[name="Foo"];

sends the output of that query to _. Output can be sent to a specific set using using the "->" syntax, while the set is prefixed with ".". The last query is thus equivalent to

  node[name="Foo"]->._;

Similarly, this query:

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

combines the output of the two queries, and send the output to _. It is equivalent to

 (
  node[name="Foo"];
  node[name="Bar"];
 )->._;

To send something to a different set, again use the "->" syntax, followed by the set. For example

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

will store all nodes with name=Foo in set "a".

To select something from a set, append the command with ".a".

  node.a[amenity=foo];

will return all nodes in the set "a" that have the tag amenity=foo.

Block statements

Union

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. Note that the square brackets [ ... ] shown below indicate an optional part of the syntax and are not to be typed literally.

  (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.

Difference

The difference block statement is written as a pair of parentheses. Inside the difference statement, exactly two statements must be placed, and between them a minus sign. Note that the square brackets [ ... ] shown below indicate an optional part of the syntax and are not to be typed literally.

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

It takes no input set. It produces a result set. Its result set contains all elements that are result of the first sub-statement and not contained in the result of the second sub-statement.

Example:

  (node[name="Foo"]; - node(50.0,7.0,51.0,8.0););

This collects all nodes that have a name tag "Foo" but are not inside the given bounding box.

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

Example:

  (node[name="Foo"]; - node(50.0,7.0,51.0,8.0);)->.a;

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

Intersection

It is also possible to produce a set of elements that appear in both of two input sets, i.e. elements that are part of both sets. This is described below in By input set (.setname):

  node.a.b;

This is not a block statement, but listed here for its close relation to the difference statement described above.

Collection-controlled loops

For-each loop (foreach)

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

It takes an input set. It produces no result set. The foreach statement loops over the content of the input set, once for every element in the input set.

Example:

  way[name="Foo"];
  foreach(
    (
      ._;
      >;
    );
    out;
  );

For each way that has a name tag with value "Foo", this prints the nodes that belong to this way immediately followed by the way itself. In detail, the result set of way[name="Foo"] is taken as input set. Then, for each element in this input set the loop body is executed once. Inside the loop body the union of the element and its nodes is taken. Then this union is printed. Note that during execution, each printed subset in an iteration is independant of subsets printed in other iterations, possibly resulting in duplicate objects in the global output (no union is computed by the out statement within the loop).

The input set of the foreach statement can be taken from a variable with the usual postfix notation:

Example:

  foreach.a(...);

This loops over the content of set a instead of the default set "_".

The name of the variable to put the loop element into can also be chosen by adding a postfix immediately before the opening parenthese.

Example:

  foreach->.b(...);

This puts the element to loop over into the variable b. Without it, the foreach statement does not puts the elements into any set. Example for both input and loop set changed:

  foreach.a->.b(...);

note: the input set can't be altered by the loop. Any updates to the set will be saved for further usage, but it will not alter the number of iterations.

Standalone queries

Item

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.

Recurse up (<)

The recurse up standalone query is written as a single less than.

It takes an input set. It produces a result set. Its result set is composed of:

  • all ways that have a node which appears in the input set; plus
  • all relations that have a node or way which appears in the input set; plus
  • all relations that have a way which appears in the result set

Example:

  <;

The input set of the recurse up statement can be chosen with the usual prefix notation:

  .a <;

The result set of the recurse up statement can be redirected with the usual postfix notation:

  < ->.b;

Of course, you can also change both:

  .a < ->.b;

Recurse up relations (<<)

The recurse up relations standalone query has a similar syntax to the recurse up query and differs only in two aspects:

  • It is written as a double less than.
  • It also recursively returns all relations that have a member relation appearing in the input set.

In particular, you can change the input and/or result set with the same notation as for the recurse up standalone query.

Precisely, the recurse up relations standalone query returns the transitive and reflexive closure of membership backwards.

Example:

  <<;

Recurse down (>)

The recurse down standalone query is written as a single greater than.

It takes an input set. It produces a result set. Its result set is composed of:

  • all nodes that are part of a way which appears in the input set; plus
  • all nodes and ways that are members of a relation which appears in the input set; plus
  • all nodes that are part of a way which appears in the result set

In particular, you can change the input and/or result set with the same notation as for the recurse up standalone query.

Example:

  >;

Recurse down relations (>>)

The recurse down relations standalone query has a similar syntax to the recurse down query and differs only in two aspects:

  • It is written as a double greater than.
  • It also recursively returns all relations that are members of a relation appearing in the input set.

In particular, you can change the input and/or result set with the same notation as for the recurse down standalone query.

Precisely, the recurse down relations standalone query returns the transitive and reflexive closure of membership.

Example:

  >>;

Query for areas (is_in)

The standalone query is_in returns the areas that cover

  • the given coordinates (when specified) or
  • one or more nodes from the input set (when no coordinates are specified).

It takes either an input set or a coordinate and produces a result set. The results are all areas which contain at least one of node from the input set or the specified coordinates.

is_in cannot be directly used with any of the Overpass QL filters. For filtering the is_in result, a further query is needed (see below): the [square brackets] shown below, indicate optional parts and are not part of the syntax to type.

  [.input_set] is_in         [-> .result_set];
  is_in(latitude, longitude) [-> .result_set];

In its shortest form, it takes its input set as the coordinates to search for. Example:

  is_in;

The input set can be chosen with the usual prefix notation:

  .a is_in;

The result set can be redirected with the usual postfix notation:

  is_in->.b;

Of course, you can also change both:

  .a is_in->.b;

Instead of taking existing nodes you can also specify coordinates with two floating point numbers, divided by a comma. They are interpreted as latitude, longitude. In this case, the input set is ignored. Example:

  is_in(50.7,7.2);

Also in this variant, the result set can be redirected with the usual postfix notation:

  is_in(50.7,7.2)->.b;

Area creation depends on some specific extraction rules, there's no area counterpart for each and every OSM way or relation! For more details see areas.osm3s and the Areas Wiki page.

To filter the result returned by is_in by additional filter criteria, an additional query is needed:

  is_in(48.856089,2.29789);
  area._[admin_level="2"];     // ._ represents the default inputset, which contains all areas returned by ''is_in''

Filters

The most important statement is the query statement. This is not a single statement but rather consists of one of the type specifiers node, way, relation (or shorthand rel) or area, followed by one or more filters. The result set is the set of all elements that match the conditions of all the filters.

Example:

// one filter
  node[name="Foo"];
  way[name="Foo"];
  rel[name="Foo"];
  area[name="Foo"];

// many filters
  node[name="Foo"][type="Bar"];

Here, node, way, rel and area are the type specifier, [name="Foo"] is the filter and the semicolon ends the statement.

The query statement has a result set that can be changed with the usual postfix notation.

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

The individual filters may have in addition input sets that can be changed in the individual filters. Please see for this at the respective filter.

By tag (has-kv)

The has-kv filter selects all elements that have or have not a tag with a certain value. It supports the basic OSM types node, way, and relation as well as the extended type area.

It has no input set. As for all filters, the result set is specified by the whole statement, not the individual filter.

All variants consist of an opening bracket, then a string literal in single or double quotes. Then the variants differ. All variants end with a closing bracket. If the string literal consists only of letters, the quotes can be omitted.

Equals (=, !=)

The most common variant selects all elements where the tag with the given key has a specific value. This variant contains after the key literal an equal sign and a further literal containing the value. Examples, all equivalent:

  node["name"="Foo"];
  node[name=Foo];
  node['name'="Foo"];
  node[name="Foo"];
  node["name"='Foo'];

If you have a digit, whitespace or whatever in the value, you do need single or double quotes:

  node["name"="Foo Street"];
  node["name"='Foo Street'];
  node[name="Foo Street"];

Querying for empty values is not possible using the equals value operator. This can only be achieved by using a regular expression:

node[power=""];          // not supported
node[power~"^$"];        // use regular expression instead

Likewise, querying empty key values is also not possible using this kind of key-value query and needs to be expressed via regular expressions.

node[~"^$"~"."];         // find nodes with empty key ("") and any value

NB: Overpass Turbo Wizard already has some logic in place to automatically convert ""="" accordingly.

Exists

The second variant selects all elements that have a tag with a certain key and an arbitrary value. It contains nothing between the key literal and the closing bracket:

  node["name"];
  node['name'];
  node[name];

Not exists

since v0.7.53

This variant selects all element, that don't have a tag with a certain key and an arbitrary value.

  node[!"name"];
  node[!'name'];
  node[!name];

In previous versions, 'not exists' had to be written as node["name"!~".*"];.

Value matches regular expression (~, !~)

The third variant selects all elements that have a tag with a certain key and a value that matches some regular expression. It contains after the key literal a tilde, then a second literal for the regular expression to search for:

  node["name"~"^Foo$"];    /* finds exactly "Foo" */
  node["name"~"^Foo"];     /* finds anything that starts with "Foo" */
  node["name"~"Foo$"];     /* finds anything that ends with "Foo" */
  node["name"~"Foo"];      /* finds anything that contains the substring "Foo" */
  node["name"~".*"];        /* finds anything, equal to ["name"] */
  node["name"!~".*"];       /* finds nodes without "name" tag; does not have key name */

Please note that in QL you need to escape backslashes: ["name"~"^St\."] results in the regular expression ^St. (which finds every name starting with "St"), while ["name"~"^St\\."] produces the most likely meant regular expression St\. (which finds every name starting with "St."). This is due to the C escaping rules and doesn't apply to the XML syntax.

Case insensitively

You can also search case insensitively

  node["name"~"^Foo$",i];    /* finds "foo", "FOO", "fOo", "Foo" etc. */

Both the key and value variants with and without regular expressions can be negated. They then select exactly the elements which have a tag with the given key, but no matching value and the elements that don't have a tag with the given key:

  node["name"!="Foo"];
  node["name"!~"Foo"];
  node["name"!~"Foo",i];

Key/value matches regular expression (~"key regex"~"value regex")

The fourth variant selects all elements where both key and value match a regular expression. After an initial tilde (~) the regular expression for the key needs to be provided, followed by another tilde character and eventually the regular expression for the value.

  node[~"^addr:.*$"~"^Foo$"];    /* finds addr:* tags with value exactly "Foo" */
  node[~"^addr:.*$"~"^Foo"];     /* finds addr:* tags with value starting with "Foo" */
  node[~"^addr:.*$"~"Foo$"];     /* finds addr:* tags with value ending with "Foo" */
  node[~"^addr:.*$"~"Foo"];      /* finds addr:* tags with value containing the substring "Foo" */
  node[~"^addr:.*$"~"."];        /* finds addr:* tags with any value */
  node[~"^name(:.*)?$"~"."];     /* finds anything with a name or name:lang tag, and with any value */
  node[~"^name(:ar|:he)?$"~"."]; /* finds anything with name, name:ar, or name:he tag, and with any value*/

This format also supports case-insensitive searches: node[~"^addr:.*$"~"^Foo$",i];. Case-insensitivity applies to both tag key and value searches in this case.

Bounding box

The bbox-query filter selects all elements within a certain bounding box.

It has no input set. As for all filters, the result set is specified by the whole statement, not the individual filter.

  (south,west,north,east)

It consists of an opening parenthesis. Then follow four floating point numbers, separated by commas. The filter ends with a closing parenthesis.

The floating point numbers give the limits of the bounding box: The first is the southern limit or minimum latitude. The second is the western limit, usually the minimum longitude. The third is the northern limit or maximum latitude. The last is the eastern limit, usually the maximum longitude. If the second argument is bigger than the fourth argument, the bounding box crosses the longitude of 180 degrees.

Example:

  node(50.6,7.0,50.8,7.3);

Recurse (n, w, r, bn, bw, br)

The recurse filter selects all elements that are members of an element from the input set or have an element of the input set as member, depending on the given parameter.

The input set can be changed with an adapted prefix notation. As for all filters, the result set is specified by the whole statement, not the individual filter.

It consists of an opening parenthesis. Then follows one of the symbols: w (forward from ways), r (forward from relations), bn (backward from nodes), bw (backward from ways), or br (backward from relations). Then follows an optional input set declaration. The filter ends with a closing parenthesis.

Examples with default input set:

  node(w);            // select child nodes from ways in the input set
  node(r);            // select node members of relations in the input set
  way(bn);            // select parent ways for nodes in the input set
  way(r);             // select way members of relations in the input set
  rel(bn);            // select relations that have node members in the input set
  rel(bw);            // select relations that have way members in the input set
  rel(r);             // select relation members of relations in the input set
  rel(br);            // select parent relations from relations in the input set

Example with modified input set:

  node(w.foo);        // select child nodes from ways in the "foo" input set

You can also restrict the recurse to a specific role. Just add a colon and then the name of the role before the closing parenthesis.

Examples with default input set:

  node(r:"role");     // select node members of relations in the input set
  way(r:"role");      // select way members of relations in the input set
  rel(bn:"role");     // select relations that have node members in the input set
  rel(bw:"role");     // select relations that have way members in the input set
  rel(r:"role");      // select relation members of relations in the input set
  rel(br:"role");     // select parent relations from relations in the input set

Example with modified input set:

  node(r.foo:"role"); // select node members with role "role" of relations in the "foo" input set

And you can also search explicitly for empty roles:

  node(r:"");         // select node members with empty role of relations in the input set
  node(r.foo:"");     // select node members with empty role of relations in the "foo" input set

By input set (.setname)

The "item" filter selects all elements from its input set.

As for all filters, the result set is specified by the whole statement, not the individual filter.

It consists of a dot, followed by the name of the input set.

Examples: The default set:

  node._;

and a named set:

  node.a;

It is also possible to specify several input sets (set intersection). For example:

  node.a.b;
This statement returns all nodes which are both in input set .a and input set .b.

By element id

The id-query filter selects the element of given type with given id. It supports beside the OSM datatypes node, way, and relation also the type area.

It has no input set. As for all filters, the result set is specified by the whole statement, not the individual filter.

It consists of an opening parenthesis. Then follows a positive integer. The filter is ends with a closing parenthesis.

Examples:

  node(1);
  way(1);
  rel(1);
  area(1);

Note that area ids need to be derived from an existing OSM way by adding 2400000000 to its OSM id or in case of a relation by adding 3600000000 respectively. Note that area creation is subject to some extraction rules, i.e. not all ways/relations have an area counterpart. See areas.osm3s for details.

Since version 0.7.54, the id-query filter also supports multiple values. To avoid conflicts with the bounding box filter, a new mandatory id: prefix has to be used in this case.

   node(id:1000,1001,1002,1003,1004,1005);
   way(id:3998029,3998240,4065354,4065364,4065392,4065421);
   rel(id:10815,10816);
   area(id:1234);

Performance hint: Try to bundle multiple id queries into one statement, i.e. instead of writing (way(3998029);way(3998240);way(4065354);); use way(id:3998029,3998240,4065354);

Relative to other elements (around)

The around filter selects all elements within a certain radius around the elements in the input set. If you provide coordinates, then these coordinates are used instead of the input set. The input set can be changed with an adapted prefix notation. As for all filters, the result set is specified by the whole statement, not the individual filter.

A radius of 0 can be used for a way intersection test on outer/inner points.

Syntax: It consists of an opening parenthesis. Then follows the keyword around. Then follows optionally an input set declaration. Then follows a single floating point number that denotes the radius in meters. The filter either ends with a closing parenthesis or is followed by two comma separated floating point numbers indicating latitude and longitude and then finally a closing parenthesis.

Performance hint: Consider using a bounding box instead of (around:radius,latitude,longitude), as it will be always faster.

  (around[.input_set]:radius)
  (around:radius,latitude,longitude)

Examples:

  node(around:100.0);
  way(around:100.0);
  rel(around:100.0);

Example with modified input set:

  node(around.a:100.0);

Examples with coordinates:

  node(around:100.0,50.7,7.1);
  way(around:100.0,50.7,7.1);
  rel(around:100.0,50.7,7.1);

Example: Find all cinema nodes in Bonn which are at most 100m away from bus stops

  area[name="Bonn"];
  node(area)[highway=bus_stop];
  node(around:100)[amenity=cinema];
  out;

Find both cinema nodes and ways in Bonn, which are at most 100m away from bus stop nodes:

  area[name="Bonn"];
  node(area)[highway=bus_stop]->.bus_stops;
  ( 
    way(around.bus_stops:100)[amenity=cinema];
    node(around.bus_stops:100)[amenity=cinema];
  );
  (._;>;);
  out meta;

By polygon (poly)

The polygon filter selects all elements of the chosen type inside the given polygon.

It has no input set. As for all filters, the result set is specified by the whole statement, not the individual filter.

It consists of an opening parenthesis. Then follows the keyword poly. Then follows a string containing an even number of floating point numbers, divided only by whitespace. Each pair of floating point numbers represents a coordinate, in order latitude, then longitude. The filter ends with a closing parenthesis:

  (poly:"latitude_1 longitude_1 latitude_2 longitude_2 latitude_3 longitude_3 …");

An example (a triangle near Bonn, Germany):

  node(poly:"50.7 7.1 50.7 7.2 50.75 7.15");
  way(poly:"50.7 7.1 50.7 7.2 50.75 7.15");
  rel(poly:"50.7 7.1 50.7 7.2 50.75 7.15");

Performance hint: A large number of lat/lon pairs slows down the (poly: ) filter, hence simplifying the polyline geometry before using it in a poly filter is recommended.

newer

The newer filter selects all elements that have been changed since the given date. As opposed to other filters, this filter cannot be used alone. If the underlying database instance supports attic data, then "changed" is probably a better choice than "newer".

It has no input set. As for all filters, the result set is specified by the whole statement, not the individual filter.

It consists of an opening parenthesis. Then follows a date specification. Please note that this date specification cannot be abbreviated and has to be put in single or double quotes. The filter ends with a closing parenthesis.

Example:

  node._(newer:"2012-09-14T07:00:00Z");
This finds all nodes that have changed since 14 Sep 2012, 7 h UTC, in the given input set.

By date of change (changed)

The changed filter selects all elements that have been changed between the two given dates. If only one date is given, then the second is assumed to be the front date of the database. If only one date is given and it is run with the current timestamp, then it behaves exactly like "newer" with two exceptions: first, it is faster (see note), second, it can also stand as the only filter.

Note: As of June 2017, a known bug can cause "changed" to be much slower than "newer" in some cases. Consider using "newer" until it is resolved, or consider testing which one runs faster for you. See the following Github issues: #278, #322, #346. See this discussion too.

It has no input set. As for all filters, the result set is specified by the whole statement, not the individual filter.

It consists of an opening parenthesis. Then follows a date specification. Please note that this date specification cannot be abbreviated and has to be put in single or double quotes. Then can follow a comma and a second date specification. The filter ends with a closing parenthesis.

Example: All changes since the given date and now

  node._(changed:"2012-09-14T07:00:00Z");

Example: All changes between the two given dates

  node._(changed:"2012-09-14T07:00:00Z","2012-09-14T07:01:00Z");

By user (user, uid)

The user filter selects all elements that have been last touched by the specified user.

It has no input set. As for all filters, the result set is specified by the whole statement, not the individual filter.

It consists of an opening parenthesis. Then follows either the keyword user, a colon and a string literal denoting the user name to search for. Or the keyword uid followed by the user id of the user to search for. The filter ends with a closing parenthesis.

Example:

  node(user:"Steve");
  node(uid:1);

Since release 0.7.53 it is also possible to specify multiple user names:

  node(user:"Mapper1","Mapper2","Mapper 3");
  node(uid:1,2,4,8,16);

By area (area)

The area filter selects all elements of the chosen type that are inside the given area. Please note with regard to attic data that areas always represent current data.

The input set can be changed with an adapted prefix notation. As for all filters, the result set is specified by the whole statement, not the individual filter.

Syntax: It consists of an opening parenthesis. Then follows the keyword area. Then can follow a colon and a non-negative integer. The filter ends with a closing parenthesis.

Nodes are found if they are properly inside or on the border of the area. Ways are found if at least one point (also points on the segment) is properly inside the area. A way ending on the border and not otherwise crossing the area is not found. Relations are found if one of its members is properly inside the area.

If the area statement is provided without integer, the areas from the input set are used. An example:

  node(area);
  way(area);
  rel(area);

The example with modified input set:

  node(area.a);
  way(area.a);
  rel(area.a);

If an integer is added, the input set is ignored and instead the area that has the given integer as id is taken. For example:

  node(area:2400000001);
  way(area:2400000001);
  rel(area:2400000001);

Caveat: area(area); is currently not supported. In this case, the (area) filter will be silently ignored, leading to unexpected results.

Because areas in OSM are not native elements but are only inferred from the OSM database using its closed ways or relations; this facility allows grouping their various representation in a coherent set which can store their geometry, independently of their complexity and representation in the OSM database, as if they were a single distinctive element, without using complex filtering rules in your query. However associating these objects with an OSM id attribute requires some adjustment because the same id value could be used for unrelated elements with different type (way or relation). For this reason, areas returned by the Overpass API only have a "virtual" id specific to the Overpass API, but not found directly in the OSM database.

By convention the area id can be calculated from an existing OSM way by adding 2400000000 to its OSM id, or in case of a relation by adding 3600000000 respectively. Note that area creation is subject to some extraction rules, i.e. not all ways/relations have an area counterpart (notably those that are tagged with area=no, and most multipolygons and that don't have a defined name=* will not be part of areas).

Areas are created by a regular job on the Overpass API server and usually have a lag of several hours compared to the OSM main database. The exact timestamp can be determined by checking the `timestamp_areas_base` value in the Overpass json or xml result.

If you want more immediate results (not depending on the delayed batch processing), you can also write your own filters without using this facility in your Overpass query: use standard OSM element types and ids and filter them by specific tags of your choice.

See areas.osm3s for details of the filters (written using the XML variant of the Overpass query language) currently by Overpass used to generate the areas that can be queried with this facility. Those areas are defined using the "pivot" query feature (see below).

Area pivot (pivot)

The pivot filter selects the element of the chosen type that defines the outline of the given area.

The input set can be changed with an adapted prefix notation. As for all filters, the result set is specified by the whole statement, not the individual filter.

It consists of an opening parenthesis. Then follows the keyword pivot. The filter ends with a closing parenthesis.

The statement finds for each area in the input set the respective element that the area has been generated from. Which is either a multipolygon relation or a way.

Examples:

  way(pivot);
  rel(pivot);

The example with modified input set:

  way(pivot.a);
  rel(pivot.a);

The following example initially determines the area(s) for the county of Greater London first and stores the result in resultset .londonarea. In the next line the areas contained in resultset .londonarea are converted back into their corresponding OSM relations using the pivot filter. Eventually out geom; outputs the relations (including ways and nodes).

  area[name="London"][admin_level=6][boundary=administrative]->.londonarea;
  rel(pivot.londonarea);
  out geom;

Conditional query filter (if:)

since v0.7.54

The query filter can be added as condition to a query statement. It has an evaluator as argument and it lets pass only those elements for which the expression returns boolean true.

At the moment, the query filter cannot be the only condition in a query. This is due to implementation reasons and will change in future versions.

It is technically possible to have multiple query filters in a single query. But it does not make sense:

  • Their evaluators can be combined with a conjunction in a single query filter.
  • This has the same semantics and is faster.

Its syntax is:

 (if: <Evaluator>)

The whitespace is optional.

Many filters above can be generalized using conditional query filter, if one needs more specific conditions for filter the objects in the query input set. For example, the query:

  node[name=foo];

is equivalent to the following one using a conditional query filter (but for simplicity the former syntax using simpler a filter by tag value is still recommended, as it may have better performance on the Overpass server, and because the new syntax for evaluators may still not be supported in the current implementation of Overpass servers and client libraries before version 0.7.54 of the API):

  node(if: t["name"] == "foo");

Actions

There is currently only one action. This action prints out the content of its input set.

Print (out)

The out action can be configured with an arbitrary number of parameters that are appended, separated by whitespace, between the word out and the semicolon.

The out action takes an input set. It doesn't return a result set. The input set can be changed by prepending the variable name.

Allowed values, in any order, are:

  • One of the following the degree of verbosity; default is body:
    • ids: Print only the ids of the elements.
    • skel: Print also the minimum information necessary for geometry. These are also coordinates for nodes and way and relation member ids for ways and relations.
    • body: Print all information necessary to use the data. These are also tags for all elements and the roles for relation members.
    • tags: Print only ids and tags for each element and not coordinates or members (this is the only information available from derived elements generated by make or convert statements, as the geometry attributes for nodes, and content members for ways and relations are missing).
    • meta: Print everything known about the elements. This includes additionally to body for all elements the version, changeset id, timestamp and the user data of the user that last touched the object (note that these metadata attributes are also missing for derived elements generated by special make or convert statements).
    • count: Print only the total counts of elements in the input set.
  • One of the following modificators for geolocated information (note that this info is missing for derived elements created by special make or convert statements); default is geom:
    • geom: Add the full geometry to each object. This adds coordinates to each node, to each node member of a way or relation, and it adds a sequence of "nd" members with coordinates to all relations.
    • bb: Adds only the bounding box of each element to the element. For nodes this is equivalent to "geom". For ways it is the enclosing bounding box of all nodes. For relations it is the enclosing bounding box of all node and way members, relations as members have no effect.
    • center: This adds only the center of the above mentioned bounding box to ways and relations. Note: The center point is not guaranteed to lie inside the polygon (example).
  • A bounding box in the format "(south,west,north,east)" (normally used with the geom verbosity type). In this case, only elements whose coordinates are inside this bounding box are produced. For way segments, the first or last coordinates outside this bounding box are also produced to allow for properly formed segments (this restriction has no effect on derived elements without any geometry).
  • One of the following for the sort order can be added. Default is asc:
    • asc: Sort by object id.
    • qt: Sort by quadtile index; this is roughly geographical and significantly faster than order by ids (derived elements generated by make or convert statements without any geometry will be grouped separately, only sorted by id).
  • A non-negative integer for the maximum number of elements to print; default is no limit.
Example out statement
Print the elements without meta information out;
Print the elements with meta information out meta;
Print at most 99 elements out 99;
Print up to 1,000,000 elements, ordered by location, with meta data out meta qt 1000000;
Reads from variable a the data to output .a out;

Counting of elements (out count)

In addition the the existing output modes, out count; provides a way to return the total number of elements in a given inputset without transferring individual OSM objects. Is it supported in XML, JSON and CSV mode.

  out count;
XML output mode
  <count total="923" nodes="923" ways="0" relations="0"/>
JSON output mode
{
  "count": {
    "total": 923,
    "nodes": 923,
    "ways": 0,
    "relations": 0,
    "areas": 0
  }
}


Statements producing derived elements

since v0.7.54

TODO: Enhance definition of what 'derived element' actually is

Derived elements are artificial elements, which can be created based on existing OSM data, on some statistical properties or even some constant values.

Unlike common OSM objects (such as nodes, ways and relations), it is not possible to create full metadata for such derived elements, i.e. it is not possible to generate elements with lat/lon values, user, uid, version number or last changed timestamp. This is to prevent automated edits by uploading re-tagged OSM elements.


The convert statement

since v0.7.54

The statement convert produces one derived element per element in its input set. The content of this output element is controlled by the parameters of the statement.

It is necessary to set a fixed type as type for all the derived elements. After that, an arbitrary number of tags can be set (some of them using evaluators).

In addition, it is possible to explicitly set the id of the derived objects. If you do not set an id then an unique id from a global ascending counter is assigned (which will not match the positive ids used by existing elements from the OSM database: they can only be used to derive new elements that may be used in renderer, or that may be used locally in data editors before importing them as new elements with an initial negative id, that will be replaced after import by an actual positive id assigned and returned by the OSM database server).

Finally, it can be specified to copy all tags (or only tags with specific keys) from the input element, or to define tags for additional keys, whose value may also be computed or transformed by evaluators. In this case, it is also possible to selectively suppress some tags.

The base syntax is one of:

 convert             <Type> <List of Tags>
 convert.<Input Set> <Type> <List of Tags>

where the default input set is _ as usual, and <List of Tags> is a comma separated list of items, each of which must be one the following:

 ::id = <Evaluator>
 ::  = <Evaluator>
 <Key> = <Evaluator>
 !<Key>

In the above list, only the ::id metadata is generated (as attributes) in the derived element. As of release 0.7.54, derived objects don't include geometry information yet. This will change in a future version.

All other element metadata attributes (such as the changeset id, version number, user name or id, or timestamp, that are normally set for all existing elements from the OSM database with a defined positive id) are left unspecified for the derived element. This is done on purpose to prevent automated mass retagging.

The make statement

since v0.7.54

The statement make produces one derived element per execution. The content of this output element is controlled by the parameters of the statement, and does not have to match any element in the OSM database.

This statement is most often used to generate simplified analysis or status reports (with basic aggregated data) that are smaller to download and easier/faster to process in client applications, with just a few tags in just one (or very few) elements.

It is necessary to set a fixed type name for the generated element, which can be chosen at will. After that, an arbitrary number of tags can be set (using evaluators).

As opposed to the convert statement, a generic key cannot be set because the convert statement takes no input set (and so it has no implicit input element to reference in evaluators).

Finally, it is possible to explicitly set the id of the generated object. If you do not set an id then an unique id from a global ascending counter is assigned.

All other element metadata attributes (such as the changeset id, version number, user name or id, or timestamp, that are normally set for all existing elements from the OSM database with a defined positive id) are left unspecified for the generated element. In addition, there's currently no way to specify something else than tags for a derived element. In particular this includes geometry and members (as in the case of ways or relations).

The base syntax is

 make <Type name> <List of tags>

where <List of tags> is a comma separated list of items, each of which must be one the following

 ::id  = <Evaluator>
 <Key> = <Evaluator>


Example:

make my_element_name                          // use my_element_name as type
     ::id = 1234,                             // set the id of the resulting element
     "tag1" = "this is the value of tag1",    // add tag1 with a constant string
     "tag2" = 4711,                           // add tag2 with a numeric value
     "tag3" = date("2018-07-01");             // add tag3 with a value returned by calling some function

out;

Result:

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API">
<note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note>
<meta osm_base="2017-03-11T12:55:02Z"/>

  <my_element_name id="1234">
    <tag k="tag1" v="this is the value of tag1"/>
    <tag k="tag2" v="4711"/>
    <tag k="tag3" v="2018.439453125"/>
  </my_element_name>

</osm>

Evaluators

since v0.7.54

Evaluators are building blocks that yield a value on execution. The use of each of the evaluators makes sense depending on the context.

Evaluators can help filter elements within a query statement, they can provide statistical information about query results, and they allow removing and adding tags of elements.

Currently only tag evaluators are supported. Geometry evaluators are planned but not implemented yet.

The following types of evaluators exist and are explained below:

  • Const evaluators always provide the same value regardless of the context.
  • Element-dependent evaluators provide information about an individual object. They only make sense in the context of a single element.
  • Statistical evaluators provide information about a set as a whole.
  • Aggregators let an element-dependent evaluator loop over all elements of a set and combine its results.
  • Operators and endomorphisms combine the result of one or two evaluator executions into a new result.

The order of precedence is as follows, from strong to weak binding:

  • Atomic evaluators:
    • Values
    • Evaluators within parentheses
    • Element-dependent operators
    • Endomorphisms
    • Statistical evaluators or aggregators
  • Unary operators:
    • Arithmetic negation
    • Boolean negation
  • Binary operators:
    • Multiplication and division
    • Addition and subtraction
    • Less, less-equal, greater, greater-equal comparisons
    • Equality, inequality comparisons
    • Boolean conjunction
    • Boolean disjunction

Fixed Values

since v0.7.54

This operator always returns a fixed value. It does not take any argument.

Its syntax is:

 <Value>
  • Fixed values can be quoted strings, integers, or floating-point numbers.
  • Fixed values are used as operands within evaluators.

Element-Dependent Operators

since v0.7.54

Element-dependent operators require one or no parameters.

Their syntax varies, but most have the appearance of a function name and parentheses.

Element-dependent operators can only be called in a context where elements are processed. This applies to convert, to filter, or to arguments of aggregators.

They cannot be called directly from make.

Id and Type

since v0.7.54

These operators apply implicitly to each element selected in the current input set. Both take no parameters.

The id operator returns the id of the element as an integer.

Its syntax is:

 id()
  • Nodes, ways, and relations have the ids from the OSM database.
  • Elements with type "area" have a synthetic id internally generated by the Overpass server.
  • Derived elements created in the query itself using make or convert statements have no defined id.

The type operator returns the type of the element as a string: "node", "way", "relation", "area", or "derived".

Its syntax is:

 type()

Tag Value, Tag Value Check, and Generic Value

since v0.7.54

The tag operator returns the value of the tag of the given key.

Its syntax is:

 t[<Key name>]

The is_tag operator returns "1" if the given element has a tag with this key and "0" otherwise.

Its syntax is:

 is_tag(<Key name>)
  • They only can be called in the context of an element.
  • The <Key name> must be in quotation marks if it contains special characters.

The generic tag operator returns the value of the tag of the key it is called for.

Its syntax is:

 ::
  • It only can be called in the context of an element.
  • In addition, it must be part of the value of a generic property to have its key specified.

Element Properties Count

since v0.7.54

These variants of the count operator count tags or members of the given element. Opposed to the statistical variant of the count operator, they cannot take an input set.

The syntax for tag count is:

 count_tags()

The syntax for member count is:

 count_members()

Example:

Find ways consisting of two nodes only:

[bbox:{{bbox}}];
way(if:count_members() == 2);
out geom;

Find relations without any tags and a single member (=node/way/relation) only:

[bbox:{{bbox}}];
rel(if:count_members() == 1 && count_tags() == 0);
out ;

Aggregators

since v0.7.54

Aggregators need for execution both a set to operate on and an evaluator as argument.

That evaluator will be used for each element of the set, and the aggregator will combine the results into a single value.

Unique and Set

since v0.7.54

These aggregators execute their right hand side evaluators on each element of a set:

The u aggregator returns the unique value found if only one non-empty value returned when evaluating each element of the specified set.

  • If no value is found then u returns an empty string.
  • If multiple different values are found then u returns the diagnostic text "< multiple values found >".

Its syntax is:

 <Set>.u(<Evaluator>)

If the set is the default set _ then you can drop the set parameter:

 u(<Evaluator>)

The set aggregator returns a semi-colon separated list (in an unspecified order) of all distinct non-empty values that appear; that returned string could be potentially very long, and possibly truncated if some internal limit is exhausted.

Its syntax is:

 <Set>.set(<Evaluator>)

If the set is the default set _ then you can drop the set parameter:

 set(<Evaluator>)

Minimum and Maximum

since v0.7.54

These aggregators execute their right hand side evaluators on each element of a set.

Their syntax is:

 <Set>.min(<Evaluator>)
 <Set>.max(<Evaluator>)

If the set is the default set _ then you can drop the set parameter:

 min(<Evaluator>)
 max(<Evaluator>)
  • If no value is found the aggregators return an empty string.
  • If all return values are valid numbers then the values are ordered from small to large.
  • Otherwise, the values are ordered lexicographically as strings.
  • min returns the result ordered first.
  • max returns the result ordered last.

Sum

since v0.7.54

This aggregator executes its right hand side evaluators on each element of the specified set.

Its syntax is:

 <Set>.sum(<Evaluator>)

If the set is the default set _ then you can drop the set parameter:

 sum(<Evaluator>)
  • If all return values are valid numbers then sum returns their sum.
  • Otherwise, sum returns "NaN".

Statistical Count

since v0.7.54

These variants of the count operator counts elements of a given type in a set.

Their syntax is:

 <Set>.count(nodes)
 <Set>.count(ways)
 <Set>.count(relations)
 <Set>.count(deriveds)           // e.g. for areas

If the set is the default set _ then you can drop the set parameter:

 count(nodes)
 count(ways)
 count(relations)
 count(deriveds)

Unary Operators

Unary operators need a single operand for their execution. They are always written in prefix notation.

Their syntax is

 <Operator><Evaluator>

Operators can be grouped with parentheses.

 (<Operator><Evaluator>)

Parenthesis can be used to override operator precedence.

Boolean Negation

since v0.7.54

The Boolean negation evaluates to "1" if its argument evaluates to a representation of Boolean false. Otherwise it evaluates to "1".

Its syntax is:

 ! <Evaluator>

The whitespace is optional.

  • The empty string and every string that is a numerical representation of a zero represents a Boolean false.
  • Every other string represents Boolean true.

Arithmetic Negation

since v0.7.54

The unary minus operator performs arithmetic negation of its argument.

Its syntax is:

 - <Evaluator>

The whitespace is optional.

  • If the argument is an integer number the result is an integer number.
  • If the argument is an floating point number the result is a floating point number.
  • Otherwise the result is "NaN".

String Endomorphisms

since v0.7.54

String endomorphisms are functions that accept a string argument and return another string. They always evaluate their argument.

Their syntax is:

 <Function Name>(<Evaluator>)

Many of them help to normalize or check the value of its argument. For now they are only of this kind, limited to numbers and dates evaluation.

Additional functions may be defined later (such as Unicode normalization, or case transforms), but may need additional parameters (in which case they would no longer be endomorphisms).

Number Check and Normalizer

since v0.7.54

The function number turns its argument into a normalized number.

Its syntax is:

 number(<Evaluator>)
  • If its argument is not a number then number returns "NaN".

The function is_number checks whether its argument is a number. It returns "1" if its argument can be parsed as a number and "0" otherwise.

Its syntax is:

 is_number(<Evaluator>)

Date Check and Normalizer

since v0.7.54

The function date turns its argument into a number representing a date.

Its syntax is:

 date(<Evaluator>)
  • If its argument is not a date then date returns returns "NaD" (not a date).

The function is_date checks whether its argument represents a date. It returns "1" if its argument can be parsed as a date and "0" otherwise.

Its syntax is:

 is_date(<Evaluator>)

A string is parsed for a date as follows:

  • The first group of digits is understood as year.
  • The next group of digits, if present, is understood as month.
  • The next group, if present, is understood as day.
  • If more groups of digits are present then they are understood as hour, minutes, and seconds in this order.

To be a valid date:

  • The year must be more than 1000,
  • The month, if present, must be less or equal to 12,
  • The day if present, must be less or equal to 31,
  • The hour, if present, must be less or equal to 60,
  • The minutes and seconds, if present, must be less or equal to 60.

The date parser may get more liberal in future versions and accept more representations of dates.

The following query can be used as an illustration on how `start_date` tags are converted into numeric date values.

[bbox:{{bbox}}];

node[start_date];              // find all nodes in current bounding box with start_date tag

convert elem                                            // convert nodes from inputset to <elem> 
        ::id = id(),                                    // keeping the node id value
        original_date = t[start_date],                  // value as found in start_date tag
        normalized_date = date(t[start_date]),          // start_date converted to numeric value
        is_date = is_date(t[start_date]);               // is start_date a recognized date?

out;    // show results of convert statement

Binary Operators

since v0.7.54

Binary operators need two operands for execution. They are always written in infix notation.

Their syntax is

 <Evaluator><Operator><Evaluator>

Operators can be grouped with parentheses.

 (<Evaluator><Operator><Evaluator>)

Parenthesis can be used to override operator precedence:

 2 + 3 * 4

is evaluated to 2 + 12, and then 14.

 (2 + 3) * 4

is evaluated to 5 * 4, and then 20.

Multiplication and Division

since v0.7.54

The multiplication and division operators perform the respective arithmetic operations. They have the same priority.

Their syntax is:

 <Evaluator> * <Evaluator>
 <Evaluator> / <Evaluator>

The whitespace is optional.

  • If one or both arguments are not numbers then the result is "NaN".
  • The operators are treated as floating point numbers except for multiplication of two integers.

Addition and Subtraction

since v0.7.54

The addition and subtraction ion operators perform the respective arithmetic operations. They have the same priority.

Their syntax is:

 <Evaluator> + <Evaluator>
 <Evaluator> - <Evaluator>

The whitespace is optional.

  • If both arguments can be interpreted as integers then they are added or subtracted as integers.
  • Otherwise, if both arguments can be interpreted as floating point numbers then they are added or subtracted as floating point numbers.
  • In all other cases the plus operator concatenates the arguments as strings and the minus operator returns "NaN".

The unary minus is an operator distinct from the binary minus operator defined here. It has a higher priority.

Less, Less-Equal, Greater, and Greater-Equal

since v0.7.54

These operators evaluate to "1" if their arguments compare respectively. Otherwise they evaluate to "0".

The syntax for the operators is:

 <Evaluator> <  <Evaluator>
 <Evaluator> <= <Evaluator>
 <Evaluator> >  <Evaluator>
 <Evaluator> >= <Evaluator>

The whitespace is optional.

  • If both arguments can be interpreted as integers then the their values are compared as integers.
  • Otherwise, if both arguments can be interpreted as floating point numbers then the values are compared as floating point numbers.
  • In all other cases their values are compared lexicographically as strings.

Equality and Inequality

since v0.7.54

The equality operator evaluates to "1" if both of its arguments are equal. Otherwise it evaluates to "0".

Its syntax is:

 <Evaluator> == <Evaluator>

The whitespace is optional.

The inequality operator evaluates to "0" if both of its arguments are equal. Otherwise it evaluates to "1".

and for inequality:

 <Evaluator> != <Evaluator>

The whitespace is optional.

  • If both arguments can be interpreted as integers then the their values are compared as integers.
  • Otherwise, if both arguments can be interpreted as floating point numbers then the values are compared as floating point numbers.
  • In all other cases their values are compared as strings.

Boolean Conjunction and Disjunction

since v0.7.54

The Boolean conjunction evaluates to "1" if both of its arguments evaluate to a Boolean true. Otherwise it evaluates to "0".

Its syntax is:

 <Evaluator> && <Evaluator>

The whitespace is optional.


The Boolean disjunction evaluates to "1" if one or both of its arguments evaluate to a Boolean true. Otherwise it evaluates to "0".

Its syntax is:

 <Evaluator> || <Evaluator>

The whitespace is optional.

  • The empty string and every string that is a numerical representation of a zero represents a Boolean false.
  • Every other string represents Boolean true.

Currently, both arguments are always evaluated. This may change in future versions.

Settings

timeout:

The timeout: setting has one parameter, a non-negative integer. Default value is 180.

This parameter indicates the maximum allowed runtime for the query in seconds, as expected by the user. If the query runs longer than this time, the server may abort the query with a timeout. The second effect is, the higher this value, the more probably the server rejects the query before executing it.

So, if you send a really complex big query, prefix it with a higher value; e.g., "3600" for an hour. And ensure that your client is patient enough to not abort due to a timeout in itself.

Example:

  [timeout:180]

Element limit (maxsize:)

The maxsize: setting has one parameter, a non-negative integer. Default value is 536870912 (512 MB).

This parameter indicates the maximum allowed memory for the query in bytes RAM on the server, as expected by the user. If the query needs more RAM than this value, the server may abort the query with a memory exhaustion. The second effect is, the higher this value, the more probably the server rejects the query before executing it.

So, if you send a really complex big query, prefix it with a higher value; e.g., "1073741824" for a gigabyte. The maximum value highly depends on the current server load, e.g. requests for 2GB will likely be rejected during peak hours, as they don't fit into the overall resource management. Technically speaking, maxsize is treated as a 64bit signed number.

Example:

  [maxsize:1073741824]

Important notice: Recently, a new mechanism was introduced to abort queries exceeding 2 GB of memory. This exact size of this limit is still under discussion and might change over time. If you experience error messages like "runtime error: Query run out of memory using about 2048 MB of RAM.", be sure to read this thread as well: http://permalink.gmane.org/gmane.comp.gis.openstreetmap.overpass/237

Output Format (out:)

Note that the out: setting is unrelated to the out action. Syntax should not be mixed

The out setting defines the output format used to return OSM data. It can take one of the five values; default value is xml:

  • xml
  • json (not to be confused with geoJSON)
  • csv
  • custom
  • popup

Example:

  [out:json]

CSV output mode

CSV output format returns OSM data as csv document, which can be directly opened in tools like LibreOffice. It requires additional configuration parameters to define a list of fields to display, as well as two optional parameters for adding/removing the CSV header line and changing the column separator.

Format:

  [out:csv( fieldname_1 [,fieldname_n ...] [; csv-headerline [; csv-separator-character ] ] )]

Notes:

  • Numeric values (coordinates, ids) uses no thousands separator, and uses the English dot (.) for the decimal separator (in geometric coordinates).
  • No escaping is made on for specific characters in string values. This will change with release 0.7.55.
  • The default separator character (tabulation) should still allow most of the time to parse the tabular data without missing/broken/misaligned columns.
  • These CSV defaults may still not match what your spreadsheet application expects (notably the decimal separator in non-English versions) if you open the CSV file directly with your application, and data could seem corrupted, or unparsable: instead, import the data in a text-only column of a new spreadsheet, and convert it to tabular data inside that application using your own settings; or use an external filter script to convert the file before opening it.

List of field names

Besides normal OSM field names (tags), the following special fields (metadata and coordinates attributes) are available for each element in the result set to output:

Special fieldname Description
 ::id OSM Object ID
 ::type OSM Object type: node, way, relation
 ::otype OSM Object as numeric value
 ::lat Latitude (available for nodes, or in out center mode)
 ::lon Longitude (available for nodes, or in out center mode)
The following meta information fields are only available, if out meta; is used to output OSM elements.
 ::version OSM object's version number
 ::timestamp Last changed timestamp of an OSM object
 ::changeset Changeset in which the object was changed
 ::uid OSM User id
 ::user OSM User name

Note that all of these special fields needs to be prefixed by two colons "::".

Example:

  [out:csv(
    ::"id", amenity, name, operator, opening_hours, "contact:website", "contact:phone", brand, dispensing, lastcheck
  )];

Railway stations in Bonn:

  [out:csv(::id,::type,"name")];
  area[name="Bonn"]->.a;
  ( node(area.a)[railway=station];
    way(area.a)[railway=station];
    rel(area.a)[railway=station];
  );
  out;

CSV header line

The presence or absence of a header line can be controled by the first optional parameter, which can be added right after the field list separated by semicolon. Possible values include true and false. If this parameter is not specified, a header line will be printed (i.e. its default value is true).

  [out:csv(
    ::"id", amenity, name, operator, opening_hours, "contact:website", "contact:phone", brand, dispensing, lastcheck;
    false
  )];

CSV separator character

By default all fields are separated by a tab character ("\t"). However, this setting can be changed via the second optional parameter. In the following example all output fields will be separated by a pipe ("|") character instead.

  [out:csv(
    ::"id", amenity, name, operator, opening_hours, "contact:website", "contact:phone", brand, dispensing, lastcheck;
    true; "|"
  )];

out: count in CSV output mode

In addition to the previously outlined output fields for CSV output mode, counting of elements provides additional special field names. See below for an actual example.

Special fieldname Description
The following fields are only populated via an out count; statement
 ::count Returns total number of objects (nodes, ways, relations and areas) in inputset
 ::count:nodes Returns number of nodes in inputset
 ::count:ways Returns number of ways in inputset
 ::count:relations Returns number of relations in inputset
 ::count:areas Returns number of areas in inputset
Checking CSV output for complete data

Unlike other output modes like XML and JSON, there's currently no indication of any error message at all. An empty result (or a result with just a header line) might indicate either that nothing was found or that the query was aborted due to timeout or some other more serious error condition. One way to work around this is to introduce an additional counter, which summarizes the previous query result and is always put as the very last output statement of a query.

The following example extends the previously shown list of all railway stations in Bonn by an additional ouput statement returning an additional aggregated row in the CSV, describing a pseudo-element with type "count" and whose value will be in the last requested "::count" column (whose value remains empty for normal data rows):

  [out:csv(::type,::id,"name",::count)];
  area[name="Bonn"]->.a;
  ( node(area.a)[railway=station];
    way(area.a)[railway=station];
    rel(area.a)[railway=station];
  );
  out;
  out count;

Note that the result now includes an additional line with @type "count" and an indication of how many total elements are contained in the current resultset. If the final count line is missing or the total number differs, you know for sure that something went wrong and the query results are incomplete/inconsistent.

@type	@id	name	@count
node	26945519	Bonn-Oberkassel	
node	1271017705	Bonn-Beuel	
node	2428355974	Bonn-Bad Godesberg	
node	2713060210	Bonn Hauptbahnhof	
node	3400717493	Bonn-Mehlem	
count			5

The values custom and popup also require further configuration. Please see details in the output formats documentation.

Global bounding box (bbox)

The bbox setting can define a bounding box that is then implicitly added to all queries (unless they specify a different explicit bbox).

The bounding box is written in order southern lat, western lon, northern lat, eastern lon (which is the standard order).

  [bbox:south,west,north,east]

Example:

  [bbox:50.6,7.0,50.8,7.3]

Enforces a bounding box roughly around the German city Bonn, which is at 50.7 degrees latitude, 7.15 degrees longitude.

If a query is URL encoded as value of the data= parameter, the bounding box can also be appended as separate parameter. It has then order lon-lat. This is the common order for OpenLayers and other frameworks.

Complete Example:

  /api/interpreter?data=[bbox];node[amenity=post_box];out;&bbox=7.0,50.6,7.3,50.8

This finds all post boxes roughly in Bonn, Germany.

Attic data ("date")

The date setting lets the database answer a query based on a database state in the past. This is useful for example to reconstruct data that has been vandalized.

It consists of the identifier "date", followed by a colon and then a date specification.

Example:

  [date:"2012-09-12T06:55:00Z"]

This processes the rest of the query as if it were posed on 12th September 2012 at 06:55 UTC.

Limitation : The earliest possible date to return a result is 2012-09-12 06:55:00 UTC (1347432900 in epoch seconds).

It corresponds to the first change included in the first ODbL compliant planet file, which was created on 2012-09-14. If your query asks for an object in a state prior to what this planet file contains, Overpass API will return the version contained in the first ODbL compliant planet.

Origin of the name : "Attic Data" refers to the "invisible" data of the versions of OSM data older than the recent one. On the OSM website it can be found behind the "history" link every object has. The term "Attic Data" stems from CVS-terminology and there referred to data which was not really needed anymore but still kept to maybe return the system to the consistent state of an earlier date.

On purpose the term "historic data" was not used since it is not really "historic" as in "old castle" or similar (have a look at OpenHistoricalMap) but as in "deprecated" or "outdated".¹

Delta between two dates ("diff")

The diff setting lets the database determine the difference of two queries at different points in time. This is useful for example to deltas for database extracts.

It consists of the identifier "diff", followed by a colon, then a date specification, and optionally a comma and a second date specification. If only one date specification is given, then the second is assumed to be the current state.

Example:

  [diff:"2012-09-14T15:00:00Z"]

This processes the rest of the query as if it were posed on 14th September 2012 at 15:00, then processes the same query with current data and finally outputs the difference between the two results.

  [diff:"2012-09-14T15:00:00Z","2012-09-21T15:00:00Z"]

Does basically the same, but compares the state of 14th September with the state of 21st September.

Note that the output does not include any intermediate versions, which might exist between the first and the last timestamp, i.e. if there are several changes on an object, only the last version in the given timeframe is returned.

Augmented Delta between two dates ("adiff")

The adiff does basically the same like "diff" , but for all elements that aren't contained in the newer result, it is indicated what happened to them.

If an element has been deleted, then its last deletion date is printed and the indication "visible=false". If an element has changed such that it no longer matches the query then its last change date is printed and the indication "visible=true".

For more information see: Augmented Diffs.

Special syntax

Comments

The query language allows comments in the same style like in C, C++, Javascript, or CSS source code:

  out; // A single line comment
  /* Comments starting with slash asterisk must always be closed with an asterisk slash. */
  /* But they can span
         multiple lines. */

Escaping

The following C-style escape sequences (also defined in Javascript) for representing characters are recognized:

  • \n escapes a newline
  • \t escapes a tabulation
  • \" or \' escapes the respective quotation mark
  • \\ escapes the backslash
  • \u#### (the hash characters stand for four hexadecimal digits) escapes the respective unicode UTF-16 code unit, see Unicode escape sequences.
    Note that the database encodes characters in UTF-8 on 1 byte (only characters in the 7-bit US-ASCII characters subset in the range U+0000..U+007F) or more. All characters that that are assigned a Unicode scalar value in the standard 17 planes are encoded as UTF-8.
    However, this syntax only supports characters assigned in the BMP (Basic Multilingual Plane), excluding surrogates which are not Unicode characters and have no valid UTF-8 encoding (even if code points assigned to surrogates have a 16-bit scalar value). Non-ASCII characters in the BMP are encoded with UTF-8 on 2 bytes (in the range U+0080..U+07FF), or 3 bytes (in the range U+0800..U+FFFF, minus surrogates in the range U+D800..U+DFFF).
    Unicode characters outside the BMP can be represented in UTF-16 as a pair of surrogates: only valid pairs of UTF-16 surrogates (a high surrogate in U+D800..U+DBFF immediately followed by a low surrogate in U+DC00..U+DFFF) are convertible to UTF-8 in the database, and can be escaped as \uD###\uD### (the result of escaping invalid pairs of surrogates or unpaired surrogates is undefined); these valid escaped pairs of surrogates will be internally converted to UTF-8-encoded sequences of 4 bytes (in supplementary planes 1 to 16); characters in the last valid supplementary planes 15 and 16, assigned only for private use, are supported but not useful in OSM data as they are not interoperable.

In general, there is currently no support for the common escaping syntax \U000##### used in modern C to represent a codepoint in any one of the 17 valid Unicode planes (excluding surrogates), and not even for arbitrary 8-bit bytes with the common escaping syntax \x## (defined in C independantly of the encoding used). As much as possible escaping should be avoided if it's not needed, and valid UTF-8 used directly in requests.

However, a development server allows the use of ICU regular expressions, which do support \\U000##### escapes. Please note that ICU support on this endpoint is still experimental and not part of the official Overpass API yet. It may be discontinued at any time without prior notice. To enable this functionality, set the [regexp:ICU]; option and switch to the development server (if you are using Overpass turbo, you may want to add {{data:overpass,server=http://dev.overpass-api.de/api_mmd/}} to your queries in order to switch to the development Overpass API instance. With this addition, other ICU-supported escapes are recognized (using double backslashes in Overpass QL regular expressions), including \\p{Unicode property name} which will match any Unicode character having the specified Unicode property. Here is an example query that finds CJK characters outside the Basic Multilingual Plane. See the blog post and the GitHub issue tracking this feature.

Misc features

Map way/relation to area (map_to_area)

The map_to_area statement maps OSM object ids for both ways and relations to their Overpass API area id counterpart.

This is done by applying the following mapping rules inside Overpass API:

  • For ways: add 2400000000 to the way's OSM id
  • For relations: add 3600000000 to the relations's OSM id.

Example:

  rel(62716);
  out;              // output relation 62716
  map_to_area;      // map OSM relation to Overpass API area by adding 3600000000 to its id
  out;              // output area 3600062716

The main use case of this statement is to search for objects inside an area, which is again inside another area ("area in area query").

Notes:

  • The Overpass API internal area creation job does not create an area for each and every way/relation in OSM. If an area does not exist for a given way/relation, map_to_area will simply skip this object without adding an area. Otherwise the area will be returned but with its geometry as it was when it was last created or updated by an internal background process on the Overpass server, and it may be different from the most recent geometry loaded from the way/relation element in the OSM database.
  • Using areas in queries instead of actual OSM elements may speed up the Overpass queries as these geometries don't need to be fully loaded from possibly many child elements from the OSM database, and then converted by connecting ways with common nodes.
  • Also not all relations and ways may convert to a valid area (even if their tags normally imply that they should be valid areas) if they don't create properly closed rings.

The following examples outline some possible use cases for this statement:

Example 1: Find all pubs in the inner city of Cologne

Querying only for an area named "Innenstadt" would return quite a number of areas, not limited to Cologne.

try it yourself in overpass-turbo
area[name="Köln"]->.b;
rel(area.b)[name="Innenstadt"];
map_to_area -> .a;
node(area.a)[amenity=pub];
out meta;

Example 2: Find all counties in Hessen without fire station

try it yourself in overpass-turbo
area[admin_level=4]["name"="Hessen"][boundary=administrative]->.boundaryarea;
( node(area.boundaryarea)["amenity"="fire_station"];
  way(area.boundaryarea)["amenity"="fire_station"];
  >;
) ->.a;

.a is_in -> .b; 
area.b[admin_level=8] -> .bf; 

rel(area.boundaryarea)[admin_level=8];
map_to_area -> .bllf;

(.bllf - .bf );
rel(pivot);
(._;>;);
out;

Example 3ː Count the number of pharmacies per county

try it yourself in overpass-turbo
[out:csv(::"type",::"id", name, admin_level,::"count")];
area[name="Saarland"][boundary];
 rel(area)[boundary][admin_level=6];
 map_to_area;
 foreach->.d(
   (.d;);out; 
   (node(area.d)[amenity=pharmacy];
    way(area.d)[amenity=pharmacy];
    relation(area.d)[amenity=pharmacy];);
   out count;
 );

See Also