Overpass API

Aus GISpunkt HSR
(Weitergeleitet von Overpass)
Wechseln zu: Navigation, Suche

Overpass API - Selektiver Download von Daten aus der Hauptdatenbank von OpenStreetMap.

Siehe auch HowTo OpenStreetMap

Webseiten:

Programming:

Beispiele

Overpass XML vs. Overpass QL: => Man bevorzuge Overpass QL!

Umgamg mit bbox:

  • node[...]({bbox}) -- nur innerhalb Overpass (und ggf. uMap)
  • node[...](47.213,8.704,47.336,8.905)
  • Als Konstante... tbd.

Fuzzy-Match mit "~", z.B. Kastanienbäume:

 (
  node(Vorlage:Bbox)
   ["natural"~"tree"]
   ["species"~"hippocastanum"];
  node["name"~"[Bb]aum|[Tt]ree"]
 );
 out;
 
 {{style:
 node[natural=tree]
 { color:red; fill-color:red; }
 }}

Centroide der Flächen ausgeben mit "out center":

 [timeout:25]
 ;
 (
   node["tourism"="zoo"];
   way ["tourism"="zoo"];
 );
 out meta center qt;

Verschiedene

"Rollstuhlparkplätze der Schweiz"
siehe Nutzen von OpenStreetMap-Daten in GIS.
Pizzerias der Schweiz

PostGIS-Terminal (Schweiz):

 SELECT ST_AsText(way) geom, name AS label
 FROM osm_poia
 WHERE tags @> hstore('cuisine', 'pizza')

Overpass Query aller Pizzerias der Schweiz (mit BBox):

 <osm-script>
   <union>
     <query type="node">
       <has-kv k="cuisine" v="pizza"/>
       <bbox-query e="10.5194091796875" n="47.92738566360356" s="45.45627757127799" w="5.69091796875"/>
     </query>
     <query type="way">
       <has-kv k="cuisine" v="pizza"/>
       <bbox-query e="10.5194091796875" n="47.92738566360356" s="45.45627757127799" w="5.69091796875"/>
     </query>
     <recurse type="way-node"/>
   </union>
   <print/>
 </osm-script>

Overpass Query aller Pizzerias der Schweiz (mit effektiven Grenzen):

 <osm-script output="json">
   <union>
     <query type="area">
       <has-kv k="boundary" v="administrative"/>
       <has-kv k="admin_level" v="2"/> 
       <has-kv k="name:en" v="Switzerland"/>
     </query>
     <query type="node">
       <area-query/> 
       <has-kv k="cuisine" v="pizza"/>
     </query>
     <query type="area">
       <has-kv k="boundary" v="administrative"/>
       <has-kv k="admin_level" v="2"/> 
       <has-kv k="name:en" v="Switzerland"/>
     </query>
     <query type="way">
       <area-query/> 
       <has-kv k="cuisine" v="pizza"/>
     </query>
     <recurse type="way-node"/>
   </union>
   <print/>
 </osm-script>

POIs:

  <!--
  This query looks for nodes, ways and relations 
  with the given key/value combination.
  Choose your region and hit the Run button above!
  -->
  {{key=payment:bitcoin}}
  {{value=yes}}
  <osm-script output="json">
    <union>
      <query type="node">
        <has-kv k="{{key}}" v="{{value}}"/>
        <has-kv k="shop" modv="not" regv="."/>
        <has-kv k="amenity" modv="not" regv="."/>
        <has-kv k="office" modv="not" regv="."/>
        <bbox-query {{bbox}}/>
      </query>
      <query type="way">
        <has-kv k="{{key}}" v="{{value}}"/>
        <has-kv k="shop" modv="not" regv="."/>
        <has-kv k="amenity" modv="not" regv="."/>
        <has-kv k="office" modv="not" regv="."/>
        <bbox-query {{bbox}}/>
      </query>
      <query type="relation">
        <has-kv k="{{key}}" v="{{value}}"/>
        <has-kv k="shop" modv="not" regv="."/>
        <has-kv k="amenity" modv="not" regv="."/>
        <has-kv k="office" modv="not" regv="."/>
        <bbox-query {{bbox}}/>
      </query>
    </union>
    <print mode="body"/>
    <recurse type="down"/>
    <print mode="skeleton"/>
  </osm-script>

Beispiel Eisenbahnschienen

Eisenbahnschienen (inkl. Schmalspur) in der Gegend von Rapperswil.

Diskussion:

  • Die BBox-Werte für Osten müssen größer sein als für Westen und genauso die Werte für Norden größer als für Süden. Also: s<n und w<e, sortiert als s,w,n,e (Rapperswil: 47.213,8.704,47.336,8.905).
  • '{{bbox}}' ist eine Variable im Overpass Turbo (funktioniert im Overpass Service natürlich nicht).
  • 'recurse' löst Referenzen von Ways zu Nodes auf (warum auch immer 'recurse' (und nicht z.B. dereference) da dies ja nur einstufig ist?)
  • 'union' fasst Ergebnismengen von Anfragen zusammen - auch wenn's im Falle von recurse nur eine ist (...?) (OR-Verknüpfung)
  • 'print' gibt die Sache aus (warum auch immer print gewählt wurde, da dies ja nichts mit der Konsole zu tun hat... Warum nicht 'format='?)

XML:

 <osm-script timeout="900">
   <union>
     <query type="way">
       <has-kv k="railway" v="rail"/>
       <bbox-query {{bbox}}/>
     </query>
     <recurse type="way-node"/>
     <query type="way">
       <has-kv k="railway" v="narrow_gauge"/>
       <bbox-query {{bbox}}/>
     </query>
     <recurse type="way-node"/>
   </union>
   <print/>
 </osm-script>

QL:

 [timeout:900];
 (
   way
     ["railway"="rail"]
     (47.213,8.704,47.336,8.905);
   node(w);
 );
 out;

Kompakte QL:

Alternative: XML mit Regex:

 <osm-script timeout="900">
   <union>
     <query type="way">
       <has-kv k="railway" regv="^(rail|narrow_gauge)$"/>
       <bbox-query s="47.213" w="8.704" n="47.336" e="8.905"/>
     </query>
     <recurse type="way-node"/>
   </union>
   <print/>
 </osm-script>

XML mit Negation und Regex:

 <osm-script timeout="900">
   <union>
     <query type="way">
       <has-kv k="railway" modv="not" regv="rail|narrow_gauge"/>
       <bbox-query s="47.213" w="8.704" n="47.336" e="8.905"/>
     </query>
     <recurse type="way-node"/>
   </union>
   <print/>
 </osm-script>

Flaechen

Get by OSM id:

  • Step 1: First, goto www.osm.org and look for the id and/or the exact name the area (= multipolygon).
  • Step 2: Do this query given a relaton with the given id 2135966. It works also type=node, type=way. Choose your region and hit the Run button above!
 http://overpass-turbo.eu/?template=type-id&type=relation&id=2135966&R
  {{type=relation}}
  {{id=2135966}}
  <osm-script output="json">
    <id-query type="{{type}}" ref="{{id}}"/>
    <print mode="meta"/><!-- fixed by auto repair -->
    <recurse type="down"/>
    <print mode="meta"/><!-- fixed by auto repair -->
  </osm-script>

Step 3: Given the GeoJSON output (see output="json"), convert it e.g. with an Online Geoconverter like OSM2KML.

Get boundary by OSM name:

  • Use this Overpass API command to get boundaries given a name:
 http://overpass-api.de/api/interpreter?data=area[name="Nordrhein-Westfalen"];rel(area)[admin_level=6];(._;>;);out;

öV-Routen inkl. aller Koordinaten

Mit folgender QL können alle öV-Routen (welche als Relation vorhanden sind) im Raum Bülach/Winterthur geladen werden:

[out:json][bbox:47.46407,8.44228,47.56407,8.64228];
(relation[network=ZVV];);
(._;>;);
out;

Siehe auch: http://overpass-turbo.eu/s/5Ie

Schwierigkeiten und Stolpersteine

Eine Schwierigkeit war die Weiterverarbeitung der Daten, da die Relation auf mehreren Ways und diese wiederum auf Nodes aufbauen. Das obige Query liefert nur die Koordinaten der Nodes zurück. Eine weitere Variante ist die Ausgabe mit out geom; (siehe auch http://overpass-turbo.eu/s/5If) welche auch die Geometrien für die Ways ausgibt. Es wird jedoch immer noch ein Post-Processing benötigt, da die Relationen zwar mit jedem Way die Geometrien besitzt, jedoch sind diese weiterhin verschachtelt und müssen geparst werden. Gibt es eine Möglichkeit die Geometrien einer Relation ready-to-use mit dem Overpass-API abzufragen?

Download und Aufbereitung von Nodes mit PostgreSQL/PostGIS

Für dieses Beispiel wird folgender QL verwendet:

[out:json][bbox:47.46407,8.44228,47.56407,8.64228];
(node[highway=bus_stop];);
(._;>;);
out;

Folgendes Skript lädt mit COPY FROM PROGRAM die Daten (im JSON Format) in eine temporäre Tabelle, anschliessend wird das JSON geparst und in eine Tabelle abgefüllt.

BEGIN TRANSACTION;

CREATE TEMP TABLE network (
  data json 
) 
ON COMMIT DROP;

COPY network
FROM PROGRAM 'json=$(wget -q -O - "$@" "http://overpass-api.de/api/interpreter?data=[out:json][bbox:47.46407,8.44228,47.56407,8.64228]; (node[highway=bus_stop];);(._;>;);out body;");echo $json | sed "s/\n//g";';

CREATE TABLE station (
  id BIGINT PRIMARY KEY, 
  name TEXT, 
  geom GEOMETRY
);

WITH elements AS (
    SELECT json_array_elements((data -> 'elements') :: JSON) AS s
    FROM network
)
INSERT INTO station
  SELECT 
    (s -> 'id')::TEXT::BIGINT, 
    (s -> 'tags' ->> 'uic_name')::TEXT, 
    ST_SetSRID(ST_MakePoint((s -> 'lon')::TEXT::DECIMAL, 
    (s -> 'lat')::TEXT::DECIMAL), 4326)
  FROM elements
  WHERE (s ->> 'type')::TEXT LIKE 'node';

COMMIT;