Overpass API: Unterschied zwischen den Versionen
Stefan (Diskussion | Beiträge) K |
Stefan (Diskussion | Beiträge) K |
||
(3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 7: | Zeile 7: | ||
Einstieg: | Einstieg: | ||
− | + | '''"Offizielles" Handbuch zur Overpass API (NEU!): https://dev.overpass-api.de/overpass-doc/de/ ''' | |
* "Learn Overpass": http://osmlab.github.io/learnoverpass//en/ | * "Learn Overpass": http://osmlab.github.io/learnoverpass//en/ | ||
* Getting Started with Overpass Turbo (2020): https://nixintel.info/osint-tools/getting-started-with-overpass-turbo-part-1/ | * Getting Started with Overpass Turbo (2020): https://nixintel.info/osint-tools/getting-started-with-overpass-turbo-part-1/ | ||
* Tutorial: https://osm-queries.ldodds.com/tutorial/index.html | * Tutorial: https://osm-queries.ldodds.com/tutorial/index.html | ||
+ | * Blog: https://dev.overpass-api.de/blog/ | ||
+ | * Beispiele: https://osm-queries.ldodds.com/for-local-mappers/index.html | ||
Language documentation: | Language documentation: | ||
Zeile 36: | Zeile 38: | ||
Vielleicht nützlich: Der Bounding Box Calculator http://lxbarth.com/bbox/#8.781852,47.185543,8.955574,47.232655,12,47.204905,8.943557 | Vielleicht nützlich: Der Bounding Box Calculator http://lxbarth.com/bbox/#8.781852,47.185543,8.955574,47.232655,12,47.204905,8.943557 | ||
+ | |||
+ | === Tankstellenshops der Schweiz === | ||
+ | |||
+ | Achtung: Diese Query findet auch False Positives! d.h. evtl. auch Shops, die einfach 20m in der Nähe aber unabhängig einer Tankstelle sind! | ||
+ | |||
+ | Hinweis: Die Around-Anweisung ist im Union-Block. Sie nutzt die Menge aus der zuletzt davor ausgeführten Anweisung, und das ist unabhängig davon, ob Around in einem Union-Block steht. | ||
+ | |||
+ | [out:json]; | ||
+ | area[name="Zürich"]->.perimeter; | ||
+ | nwr(area.perimeter)[amenity=fuel][!shop]; | ||
+ | ( | ||
+ | nwr(around:20)[shop~"convenience|supermarket"]; | ||
+ | nwr(area.perimeter)[amenity=fuel][shop~"convenience|supermarket"]; | ||
+ | nwr(area.perimeter)[shop][highway~"services|retail"]; | ||
+ | ); | ||
+ | out meta center; | ||
=== POI Query === | === POI Query === |
Aktuelle Version vom 31. August 2021, 11:26 Uhr
Overpass API - Selektiver Download von Daten aus der Hauptdatenbank von OpenStreetMap.
Siehe auch
Einstieg:
"Offizielles" Handbuch zur Overpass API (NEU!): https://dev.overpass-api.de/overpass-doc/de/
- "Learn Overpass": http://osmlab.github.io/learnoverpass//en/
- Getting Started with Overpass Turbo (2020): https://nixintel.info/osint-tools/getting-started-with-overpass-turbo-part-1/
- Tutorial: https://osm-queries.ldodds.com/tutorial/index.html
- Blog: https://dev.overpass-api.de/blog/
- Beispiele: https://osm-queries.ldodds.com/for-local-mappers/index.html
Language documentation:
- http://wiki.osm.org/wiki/Overpass_API
- https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL
- https://wiki.openstreetmap.org/wiki/Overpass_API/Language_Guide
Web-Apps / API:
- Overpass Turbo (interaktive Webapp): http://overpass-turbo.eu/ (Weltweit)
- http://overpass-turbo.osm.ch/ (Schweiz)
- http://overpass-api.de/
Support:
- Mailing list: http://listes.openstreetmap.fr/wws/info/overpass
- https://help.openstreetmap.org/questions/20479/using-osm-data-with-javascript-via-api-in-my-code-display-data-as-text
Inhaltsverzeichnis
Beispiele
>>> Man bevorzuge 'Overpass QL' (versus'Overpass XML')! <<<
Umgang mit bbox:
- node[...]({bbox}) -- nur innerhalb Overpass (und ggf. uMap)
- node[...](47.213,8.704,47.336,8.905)
- Als Konstante... tbd.
Vielleicht nützlich: Der Bounding Box Calculator http://lxbarth.com/bbox/#8.781852,47.185543,8.955574,47.232655,12,47.204905,8.943557
Tankstellenshops der Schweiz
Achtung: Diese Query findet auch False Positives! d.h. evtl. auch Shops, die einfach 20m in der Nähe aber unabhängig einer Tankstelle sind!
Hinweis: Die Around-Anweisung ist im Union-Block. Sie nutzt die Menge aus der zuletzt davor ausgeführten Anweisung, und das ist unabhängig davon, ob Around in einem Union-Block steht.
[out:json]; area[name="Zürich"]->.perimeter; nwr(area.perimeter)[amenity=fuel][!shop]; ( nwr(around:20)[shop~"convenience|supermarket"]; nwr(area.perimeter)[amenity=fuel][shop~"convenience|supermarket"]; nwr(area.perimeter)[shop][highway~"services|retail"]; ); out meta center;
POI Query
/* Alle Castles... FYI: historic hat eigentlich die Werte "castle|yes|tower|ruins|archaeological_site" */ [out:json][timeout:25]; ( node["historic"="castle"]; way["historic"="castle"]; ); out geom tags; ( relation["historic"="castle"]; ); out center tags;
Das liefert nicht ganz dasselbe:
[out:json][timeout:25]; ( node["historic"="castle"]; way["historic"="castle"]; relation["historic"="castle"]; ); out center tags;
Filter by Admin Boundary
Given area relation name... Beispiel: Alle Fussgängerstreifen innerhalb der Stadt Zürich:
/* Crossings/crosswalks */ [out:json][timeout:25]; area[name="Zürich"][admin_level=8] -> .tmp; ( node["highway"="crossing"](area.tmp); ); out body; >; out skel qt;
Given area relation (or way) OSM id...
![]() |
NOTE: Search by area using relation or way id. First lookup OSM id in osm.org. The area id needs to be OSM id + 2400000000 for ways and OSM id + 3600000000 for relations. See https://wiki.osm.org/wiki/Overpass_API/Overpass_QL#By_area_.28area.29 |
Beispiel: Alle Brunnen innerhalb der Stadt Zürich (relation id=1682248):
/* Fountains OR drinking_water within relation 1682248 (= 360 + 1682248) */ [out:json]; area(id:3601682248); nwr[amenity~"fountain|drinking_water"](area); out center;
Fuzzy Match
Alle Namen beginnend mit "St." innerhalb (within) Zürich (Ausgabeproblem bei overpass-turbo.osm.ch ?):
[out:json][timeout:60]; area["name"="Zürich"]; ( nwr["name"~"^St\\."](area); ); out center;
---
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;
Verschiedenes
- "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:
- http://www.overpass-api.de/api/interpreter?data=(way["railway"="rail"](47.213,8.704,47.336,8.905);node(w););out;
- http://www.overpass-api.de/api/interpreter?data=(way%5B%22railway%22%3D%22rail%22%5D(47.213%2C8.704%2C47.336%2C8.905)%3Bnode(w)%3B)%3Bout%3B%0A
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 an OSM element by OSM id (useful e.g. to extract a single boundary of a canton, a county/city):
- Step 1: First, goto www.osm.org and look for the id and/or the exact name the area (= multipolygon), e.g. city of Uster which has relation osm_id 1682225.
- Step 2: Prepare you Overpass query given relation/way/node and the osm_od (here: relation osm_id 1682225 for Uster), then either use the first query in a browser or start Overpass Turbo and use the second query!
http://overpass-turbo.eu/?template=type-id&type=relation&id=1682225&R
/* This query looks for a node, way or relation with the given id. */ [out:json]; // node(); // way(); relation(1682225); // print results out body; >; out skel qt;
Step 3: Given the output (see output="json"), save (or copy) it as GeoJSON.
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?
=== Querying data with history
Query example with history, (plus history data 'attic'), e.g. using https://overpass-turbo.eu/ :
[adiff:"2018-09-01T00:00:00Z"]; ( node(Vorlage:Bbox)(changed); way(Vorlage:Bbox)(changed); ); out; //out meta geom(Vorlage:Bbox); //out count;
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;