OpenStreetMap

Overpass-API nutzen um Daten innerhalb einer Relation zu finden.

Posted by a_peter on 20 December 2013 in German (Deutsch)

Da sich die Dokumentation der Overpass-API um dieses Thema herumdrückt, werde ich das mal hier beschreiben.

Ausgangspunkt ist overpass turbo, um Overpass-Abfragen starten zu können.

Als Beispiel nehmen wir mal meine Heimatstadt Berlin. Zuerst müssen wir herausfinden, welche Relation die Stadt Berlin beschreibt. Ab zu openstreetmap.org und "Berlin" in das Suchfeld eingetragen. Bei mir ist es der zweite Treffer "Landesgrenze Berlin, Deutschland, Europäische Union". Mit der Maus über den Link fahren und wir sehen Relation 62422 beschreibt die Berliner Stadtgrenze.

Jezt wollen wir eine Abfrage in overpass machen, die diese Relation als Außengrenze nutzt. Dazu verwenden wir folgende Notation:

node(area:3600062422);

Wo die 3.600.000.000 herkommen, die man zur ID der Relation addieren muss habe ich noch nicht herausgefunden. Vielleich kann mir das jemand noch mitteilen. Auf jeden Fall funktioiniert das mit jeder beliebigen Relation. Zu deren ID 3.600.000.000 addieren und mit Doppelpunkt hinter "area" schreiben. Damit kann man außer "node" natürlich auch "way" und "rel" angeben, um Wege oder Relationen innerhalb einer Relation abzufragen.

Jetzt wollen wir mal sehen, ob es Knoten gibt, die in "addr:city" irgendetwas anderes haben als "Berlin". Ein erster Versuch mit

node(area:3600062422)["addr:city"!~"Berlin"]; out meta;

schlägt fehl. Denn es werden zuviele Knoten gefunden ["addr:city"!~"Berlin"] findet nämlich auch alle Knoten, die gar kein "addr:city" haben. Da müssen wir etwas "komplizierter" denken.

Suchen wir zuerst mal alle Knoten, die überhaupt das Attribut "addr:city" haben. Durch die Einschränkung innerhalb der Relation sind das schon mal nicht ganz soviele:

node(area:3600062422)["addr:city"]; out meta;

Sehr schön. Jetzt fällt uns ein, dass die overpass-api die Möglichkeit bietet, Differenzen zwischen Mengen zu bilden. Nutzen wir das doch dazu, von der Menge aller Knoten, die das Attribut "addr:city" haben all diejenigen abzuziehen, die das Attribut "addr:city=Berlin" haben. Dann bleiben alle übrig, die das Attribut "addr:city" überhaupt haben, bei denen der Wert aber ungleich "Berlin" ist.

Die Syntax für Differenzmengen ist:

(node(...)[...] - node(...)[...];);

Bezogen auf unser Proble ergibt sich:

( node(area:3600062422)["addr:city"] - node(3600062422)["addr:city"="Berlin"]; ); out meta;

Und siehe da: Das Ergebnis sind momentan 45 Knoten mit Werten wie "addr:city=Berlin-Französich-Buchholz", das man schön aufsplitten kann in "addr:city=Berlin" und "addr:suburb=Französisch-Buchholz".

Man muss das Ganze natürlich nicht dazu nutzen, die gleichen Attribute abzufragen. Mann kann auch alle Knoten/Wege/Relationen suchen, die das Attribut "addr:city" haben, denen aber das Attribut "addr:postcode" fehlt:

( node(area:3600062422)["addr:city"] - node(3600062422)["addr:postcode"]; ); out meta;

Oder man sucht alle Restaurants, die keine italienische Küche anbieten

( node(area:3600062422)["amenity"="restaurant"] - node(3600062422)["cuisine"="italian"]; ); out meta;

Ah, ja, 2974 Restaurants, die entweder keine Küchenbezeichnung haben oder deren Küchenbezeichnung nicht "italian" ist. Mehrere Ausschlüsse lassen sich dadurch erreichen, dass man entweder Reguläre Ausdrücke verwendet:

( node(area:3600062422)["amenity"="restaurant"] - node(3600062422)["cuisine"~"(italian|greek)"]; ); out meta;

oder indem man mehrere Mengen abzieht:

( node(area:3600062422)["amenity"="restaurant"] - node(3600062422)["cuisine"="italian"] - node(3600062422)["cuisine"="greek"] ); out meta;

Eine Kombination dieser Methoden ist natürlich auch möglich.

Aus overpass turbo heraus kann man dann mit Klick auf "Export" die Daten direkt in JOSM öffnen lassen und dort korrigieren.

Viel Spaß beim Mappen.

(p.s.: Über die Feiertage werde ich diesen Betrag mal ins Englische übersetzen.)

Comment from chris66 on 26 December 2013 at 23:15

Hi, wieso darf man das area bei dem jeweils zweiten node weglassen?

Hide this comment

Comment from floscher on 27 December 2013 at 07:18

@a_peter: Schau Dir mal diesen Forumsbeitrag an. Da erklärt der Entwickler der Overpass API, woher die 3,6 Mrd. kommen:

Roland Olbricht schrieb:

Die 3.6 Mrd sind ein historisches Artefakt: irgendwie wollte ich die IDs kanonisch von den Element-IDs ableiten, aber alle Elementarten zulassen. Je nach Art des Basiselements werden entweder 0 (für Nodes), 2.4 Mrd (für Ways) oder 3.6 Mrd (für Relations) zur Id dazuaddiert. [...]

Hide this comment

Comment from couchmapper on 27 December 2013 at 07:43

Für den genannten Anwendungsfall könnte man auch komplett ohne den Differenzoperator auskommen, was auch von Performanceseite her empfohlen wird:

area(3600062422)->.a;(node(area.a)["addr:city"]["addr:city"!~"^Berlin$"]);out;

area(3600062422)->.a;(node(area.a)["addr:city"]["addr:postcode"!~"."]);out;

area(3600062422)->.a;(node(area.a)["amenity"="restaurant"]["cuisine"][cuisine!~"italian|greek"]);out;

Suche per Name wäre auch möglich, aber da ist Berlin in USA dabei :) area[name="Berlin"];(node(area)["addr:city"]["addr:city"!~"^Berlin$"]);out;

Hide this comment

Comment from geozeisig on 27 December 2013 at 08:39

Die Frage zum suchen in einer Fläche hatten wir mal im Forum. Da haben wir das nicht über die Relations ID gemacht sondern über Grenzen:

[out:json]; area["admin_level"="4"]["name"="Berlin"]->.a; (way(area.a)["heritage"];>;);out body qt; node (area.a) ["heritage"];out body qt; relation ["admin_level"="4"] ["name"="Berlin"]; out body qt;>;out skel qt;

Hide this comment

Comment from KartoGrapHiti on 29 December 2013 at 11:43

Kann mir jemand sagen, wie ich die Grenzrelation von Gießen bei dieser Abfrage nach Buswartehallen an den Bushaltestellen in Gießen nutzen kann?

http://overpass-turbo.eu/s/1SR

Bisher frage ich in immer das Gebiet des Bildschirmes ab, was den Nachteil hat, dass auch die Haltestellen der Nachbarkommunen angezeigt werden, was ich jedoch nicht möchte.

Gießen hat die Relationsnummer 418617 http://www.openstreetmap.org/relation/418617

Hide this comment

Comment from drolbr on 29 December 2013 at 17:09

Die Grenzrelation von Gießen lässt sich z.B. wie folgt nutzen:

http://overpass-turbo.eu/s/1T2

Generell würde ich benannte Areas empfehlen, da sich Ids auch mal ohne Vorwarnung ändern können. Da es auch einen Landkreis Gießen gibt, habe ich über admin_level=8 gezielt die Stadt gegriffen.

Hide this comment

Comment from Ogmios on 22 May 2014 at 20:46

Gibt es diese Möglichkeit auch für Relationen die keine Grenzrelationen sind wie dem Harz?

Hide this comment

Comment from a_peter on 23 May 2014 at 05:37

Ja, das funktioniert für jede Relation, deren ID man kennt. Einfach 3.600.000.000 zur ID (beim Harz zu 3734750) addieren. In Deinem Fall also 3.603.734.750 eintragen (natürlich ohne die Tausenderpunkte).

Hide this comment

Leave a comment

Parsed with Markdown

  • Headings

    # Heading
    ## Subheading

  • Unordered list

    * First item
    * Second item

  • Ordered list

    1. First item
    2. Second item

  • Link

    [Text](URL)
  • Image

    ![Alt text](URL)

Login to leave a comment