Overpass API

From OpenStreetMap Wiki
(Redirected from OSM Server Side Script)
Jump to: navigation, search
Available languages
Deutsch English 日本語
Overpass API logo.svg

Introduction

The Overpass API (or OSM3S) is a read-only API that serves up custom selected parts of the OSM map data. It acts as a database over the web: the client sends a query to the API and gets back the data set that corresponds to the query.

Unlike the main API, which is optimized for editing, Overpass API is optimized for data consumers that need a few elements within a glimpse or up to roughly 100 million elements in some minutes, both selected by search criteria like e.g. location, type of objects, tag properties, proximity, or combinations of them. It acts as a database backend for various services.

Overpass API has a powerful query language (language guide, language reference, an IDE) beyond XAPI, but also has a compatibility layer to allow a smooth transition from XAPI.

To support small and well scaling OSM main services, Overpass API is run as a third party service. You can use the public visible instances:

Both servers have a total capacity of about 1.000.000 requests per day. You can safely assume that you don't disturb other users when you do less than 10.000 queries per day or download less than 5 GB data per day.

Queries to the Overpass API are in XML or Overpass QL form. See the semantics explained below.

You can use the Overpass turbo frontend to create and display queries for the above mentioned Overpass API instances.

You can also install your own instance from the latest stable release or the git source code repository. It is licensed under the Affero GPL v3.

The project is maintained by Roland Olbricht (mail: roland.olbricht@gmx.de). Contributions to the source code are welcome.

Now Overpass API also provides permanent links.

The map query

Before we get to a detailed syntax explanation, we present the probably most common use case, the map query, to collect all data from a given bounding box:

  (node(51.249,7.148,51.251,7.152);<;);out;

To run this query, you can feed it into this query form.

The order of values in the bounding box (51.249,7.148,51.251,7.152) is minimum latitude, minimum longitude, maximum latitude, maximum longitude. See more details about bbox below.

Simple usage examples

This section has moved to the query language guide.

Advanced usage examples

The following examples introduce the remaining commands recurse and around. They only make sense in combination with other commands.

Again, all of the following examples can be tested by copying the snippets to http://www.overpass-api.de/query_form.html.

Note: Queries may take several minutes to be completed. If you receive timeouts, you can extend the timeout period.

Recurse

With recurse, you query for membership relations. It is available for ways to get all referred nodes, for relations to get all member nodes or member ways. Or the other way round, to get for a node, way or relation the ways or relations the element is member of. You select among the type of element by the type attribute.

Example: Get the nodes of all relations that have the key ref with value CE 61. In fact, get all bus stops served by CE 61.

<query type="relation">
  <has-kv k="ref" v="CE 61"/>
</query>
<recurse type="relation-node"/>
<print/>

Get the ways of all relations that have the key ref with value CE 61. In fact, that is the itinerary served by CE 61.

<query type="relation">
  <has-kv k="ref" v="CE 61"/>
</query>
<recurse type="relation-way"/>
<print/>

Get the nodes of the above mentioned ways. You don't get the bus stops, but that is intentionally - see below at the union examples.

<query type="relation">
  <has-kv k="ref" v="CE 61"/>
</query>
<recurse type="relation-way"/>
<recurse type="way-node"/>
<print/>

Get all relations that have the nodes named Lichtscheid as members. These are the bus lines stopping there.

<query type="node">
  <has-kv k="name" v="Lichtscheid"/>
</query>
<recurse type="node-relation"/>
<print/>

Get all the ways that have a node member within the given bounding box.

<bbox-query s="51.249" n="51.251" w="7.149" e="7.151"/>
<recurse type="node-way"/>
<print/>

And we can also get relation members of relations:

<query type="relation">
  <has-kv k="name" v="VRR Buslinien"/>
</query>
<recurse type="relation-relation"/>
<print/>

Or the same thing backwards:

<query type="relation">
  <has-kv k="ref" v="CE 65"/>
</query>
<recurse type="relation-backwards"/>
<print/>

Around

around allows you to get all nodes near one or more given nodes. For example, to get all nodes that are at most 10 meters around the nodes called Bristol:

try it yourself in overpass-turbo
<query type="node">
  <has-kv k="name" v="Bristol"/>
</query>
<around radius="10"/>
<print/>

You can also chain queries to get only nodes satisfying a second criterion that are located near nodes matching the first criterion. Here, we will search for all bus stops within 100 meters of pubs named "Bristol":

try it yourself in overpass-turbo
<query type="node">
  <has-kv k="amenity" v="pub"/>
  <has-kv k="name" v="Bristol"/>
</query>
<query type="node">
  <around radius="100"/>
  <has-kv k="highway" v="bus_stop"/>
</query>
<print/>

Building blocks

We still have some helper statements to explain, in particular union, item, the variable mechanism, osm-script, and foreach.

Again, all of the following examples can be tested by copying the snippets to http://www.overpass-api.de/query_form.html.

Union

Union allows you to group the results of several queries. For example, you can get all nodes that have name Lichtscheid or Müngstener Straße.

<union>
  <query type="node">
    <has-kv k="name" v="Lichtscheid"/>
  </query>
  <query type="node">
    <has-kv k="name" v="Müngstener Straße"/>
  </query>
</union>
<print/>

Another usage would be to get a relation with all of its members, including the nodes of member ways.

<union>
  <query type="relation">
    <has-kv k="ref" v="CE 61"/>
  </query>
  <recurse type="relation-node" into="nodes"/>
  <recurse type="relation-way"/>
  <recurse type="way-node"/>
</union>
<print/>

This needs some explanation:

  • query collects the relations with ref CE 61. It writes the result to the default variable _. And the embracing union collects the data.
  • recurse relation-node collects the nodes that are members of the above found relations. The result is placed in the variable nodes (we don't need it there anymore, just to keep relations in the default variable). And it is collected by the embracing union.
  • recurse relation-way sees again the relations from the default variable and returns the ways that are members of the default variable's relations. Again, the embracing union collects the results.
  • recurse way-node finally returns the nodes that are members of the ways just collected. This is the last piece of data that goes into the union's result.

If you think this is complicated, you are right. I'm open to suggestions how to improve the statement semantics, but I haven't found anything systematic yet.

Now we are ready to assemble the map call, by combining a bbox-query with several recurse statements and embracing the whole thing with an union.

Item

Part of the idea behind item and variables have you already seen in the preceeding example: every statement fetches its input from a variable and puts its output into a variable. If you omit the variable name, it defaults to _. This makes in possible to remove almost all explicit specifications of variables. The input is always fetched from the variable named by the attribute from, the output is always put into the variable specified with into.

<query type="way" into="foo">
  <has-kv k="name" v="Am Hofe"/>
</query>
<print from="foo"/>

E.g., this does the same as the respective example at print, but it uses the explicitly stated variable foo.

To make this concept fully versatile, item allows you to specify a set as input in union and query:

<query type="relation">
  <has-kv k="network" v="VRR"/>
  <has-kv k="ref" v="645"/>
</query>
<recurse type="relation-node" into="stops"/>
<query type="node">
  <around from="stops" radius="100"/>
  <has-kv k="highway" v="bus_stop"/>
</query>
<union>
  <item/>
  <recurse type="node-relation"/>
  <query type="node">
    <around from="stops" radius="100"/>
    <has-kv k="park_ride"/>
  </query>
</union>
<print/>

Here, in the middle, the item ensures that the beforehand collected data for bus_stop is included in the results of union. This also shows how the variable stops is necessary to make the query possible.

<bbox-query s="51.15" n="51.35" w="7.0" e="7.3"/>
<recurse type="node-way"/>
<query type="way">
  <item/>
  <has-kv k="highway" v="motorway"/>
</query>
<print/>

The item in query restricts the possibly found items to those already found in the step before, with recurse. Thus, we have a complete query to find ways with arbitrary tags within a bbox.

Osm-Script

The osm-script is silently added if you don't specify it explicitly. The reason to specify one explicitly is to tweak the resource management:

<osm-script timeout="900" element-limit="1073741824">
 
<bbox-query s="51.15" n="51.35" w="7.0" e="7.3"/>
<print/>
</osm-script>

This 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).

Foreach

<query type="relation">
  <has-kv k="type" v="multipolygon"/>
  <has-kv k="name"/>
</query>
<foreach into="pivot">
  <union>
    <recurse type="relation-way" from="pivot"/>
    <recurse type="way-node"/>
  </union>
  <make-area pivot="pivot"/>
</foreach>

This is the essential part of the rule that creates the areas. We do not explain the make-area here. The first part with query collects all relations with certain properties. In the second part, we want to do something with each element in the result of query. This does foreach. The body of the loop is executed once for every element in the input set, containing exactly this single element in the output set, here named as pivot.

Meta data

Beside the special mode of print, there are two statements dedicated to query for specific meta data, user and newer.

User

You can select all data that has been touched the last time by a particular user. Choose the user name (for example, mine):

<user name="Roland Olbricht"/>
<print mode="meta"/>

Or choose a user id:

<user uid="65282"/>
<print mode="meta"/>

This statement can also be used within a query statement. It then restricts the result to data that has been last touched by the provided user:

<query type="node">
  <user name="Roland Olbricht"/>
  <has-kv k="highway" v="bus_stop"/>
  <bbox-query s="51.2" n="51.35" w="7.05" e="7.3"/>
</query>
<print mode="meta"/>

Newer

Newer can be used within query statement (and not as a standalone statement). It restricts the output to elements that are newer than the given date. The date must be in the format YYYY-MM-DDTHH:MM:SSZ. It refers, as the results, always to the timezone UTC.

<query type="node">
  <newer than="2011-08-01T00:00:00Z"/>
  <has-kv k="highway" v="bus_stop"/>
  <bbox-query s="51.2" n="51.35" w="7.05" e="7.3"/>
</query>
<print mode="meta"/>

If you want to get all nodes newer than a certain date from a bbox, you can use query with an item substatement.

<bbox-query s="51.2" n="51.35" w="7.05" e="7.3"/>
<query type="node">
  <item/>
  <newer than="2011-08-01T00:00:00Z"/>
</query>
<print mode="meta"/>

Public transport example

An interesting example of how the Overpass API can be integrated into an application - a service to generate line diagrams for public transport.

Preview of Transportation Example 1

Preview of Transportation Example 2

(Please be patient - each request can take up to 10 seconds to generate, depending on server load.)

XAPI Compatibility Layer

For details and examples see: