Overpass QL (short for "Overpass Query Language") is the second query language created for the Overpass API, the first being Overpass XML. Overpass QL is a procedural, imperative programming language written with a C style syntax.
This wiki page intends to be a complete technical reference to the structure of Overpass QL. For a collection of practical examples, see also the wiki page Overpass API by Example. People without a technical background may find that page more accessible.
The features supported by an Overpass QL parser are defined by the version of the Overpass API running on the server queried. Be sure that the Overpass API server you query has a new enough API version to support the features you wish to use.
Overpass QL manipulates sets. Statements write their results into sets, and sets are then read by subsequent statements as input. An Overpass QL set can contain any combination of (and any number of) OpenStreetMap nodes, ways, relations, and area elements.
Unless you specify a named set as an input or result, all input is implicitly read from (and all results are written to) the default set named _ (a single underscore). Once a new result is (implicitly or explicitly) assigned to an existing set, its previous contents will be replaced and are no longer available. Overpass QL sets always have global scope (visibility).
implicitly writes the result of the tag query name="Foo" to the default set _, overwriting any previous contents with this result. A result can be written to a specific set using the -> syntax, when that set name is prefixed with .. The statement above is thus equivalent to:
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.
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.
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.
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.
The presence or absence of a header line can be controlled by the first optional parameter, which can be added right after the field list separated by semicolon. Possible values include true and false. Default value is true.
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
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 output 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):
The output now includes an additional column with type ::count and an indication of how many total elements are contained in the current resultset: 5. 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.
The 'bounding box' defines the map area that the query will include. The global bbox setting can be used to define a bounding box and then this is implicitly used in all statements (unless a statement specifies a different explicit bbox). If no bbox is specified the default value is "the entire world".
Note: When a query is URL encoded as the value of the data= parameter, a bounding box can also be appended as a separate bbox variable. When used this way, the order is reversed, lon-lat. (This is the common order for OpenLayers and other frameworks.)
date is a global setting which modifies an Overpass QL query to examine attic data, and return results based on the OpenStreetMap database as of the date specified. This setting can be useful, for example, to reconstruct data that has been vandalized, or simply to view an object as it existed in the database at some point in the past.
It consists of the identifier diff, followed by : , an OpenStreetMap database standard ISO 8601 date enclosed in quotes, in the format YYYY-MM-DDThh:mm:ssZ , and optionally a comma and a second date which defaults to the current date ("now").
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.
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".
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.
The union block statement takes no input set. It produces a result set which is the union of the result sets of all sub-statements, regardless of whether a sub-statement has a redirected result set or not.
The first statement collects all nodes that have a name tag "Foo"; the second statement collects 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 difference block statement is written as a pair of parentheses. Inside the difference statement, exactly two statements must be placed, separated by a minus sign. Note that the square brackets [ ... ] shown below indicate an optional part of the syntax and are not to be typed literally.
The difference block statement takes no input set. It produces a result set which contains all elements that are result of the first sub-statement and not contained in the result of the second sub-statement.
The block statement if executes its substatements only if its condition evaluates to boolean true. This allows e.g. to try more loosely search conditions if stricter search conditions did not deliver a result.
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 the 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. This union is then printed.
Note that during execution, each printed subset in an iteration is independent 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 is broken down as follows: For each element the given evaluator is evaluated and elements with the same value are grouped together. At the beginning of each loop execution, the output set is filled with the relevant subset.
With the special evaluator keys(), one can loop over all the keys that exist in the subset.The respective subset for each key are the elements that have this key set.Unlike for a usual evaluator, the sets are not mutually distinct in that case.
The block statement complete loops through its substatements until the results of the loop stabilize.This allows to track a group of loosely or tightly connected elements like all sections of a way with the same name or a system of tributary rivers.
It is currently undefined whether the content of variables from outside the block is available within the block and vice versa.Future versions may transfer only derived elements, keep the environments completely apart, or morph elements from one point in time to the other.
The statement can have a block of substatements.The block of substatements is executed after computing the diff in the second run, once for the old timestamp and then again for the new timestamp.This allows to do extra computations based on the diff results.
In the first run of a diff query it returns an empty set.In the second run of a diff query it returns the difference of the elements.If the statement gets an evaluator as argument then only those elements that have different values on both timestamps are returned.If the element does not exist on one of the timestamps then its value is regarded as the empty string.Currently, the only purpose of such a difference is to feed it into an output statement.
795a8134c1