Handbuch zur Overpass API

Objekte Zählen
Daten Analysieren
Anhang

Und- und Oder-Verknüpfung

Suche nach Objekten anhand mehrerer Tags und sonstiger Kriterien.

Und-Verknüpfung

Zunächst wollen wir zwei oder mehr Bedingungen so verknüpfen, dass nur Objekte gefunden werden, die alle Bedingungen erfüllen. Einige Beispiele für Und-Verknüpfungen haben wir bereits gesehen: Tag und Bounding-Box, Tag und Gebiet, Tag und zwei Gebiete sowie zwei Tags

Wir arbeiten und an dem Standardfall entlang, einen Geldautomaten finden zu wollen. Es gibt dafür das Tag amenity mit Wert atm. Wegen der großen Anzahl hat das Beispiel eine kleine Bounding-Box:

nwr[amenity=atm]({{bbox}});
out center;

Es werden also ein Filter nach einem Tag (hier amenity=atm) mit einem Filter nach einer Bounding-Box kombiniert, indem man beide Filter einfach hintereinander schreibt.

Die Reihenfolge spielt dabei keine Rolle:

nwr({{bbox}})[amenity=atm];
out center;

Es gibt aber eine weitere Möglichkeit Geldautomaten einzutragen: Oft sind sie Bestandteil einer Bankfiliale; sie werden dann als Eigenschaft der Filiale eingetragen:

nwr[amenity=bank]({{bbox}})[atm=yes];
out center;

Wie in allen anderen Beispielen können auch hier die Filter innerhalb der Query-Anweisung beliebig gereiht werden:

nwr[atm=yes][amenity=bank]({{bbox}});
out center;

Wie man beide Mapping-Arten kombiniert, wird im nächsten Abschnitt erläutert. Erst soll noch klargestellt werden, dass beliebig viele Tags oder sonstige Kriterien kombiniert werden können: Lassen Sie zum Ausprobieren im folgenden Beispiel mal ein oder mehrere Filter weg; es wird sich immer das Ergebnis ändern, da jeder der sechs Tag-Filter und auch die Bounding-Box Einfluss hat:

way
  [name="Venloer Straße"]
  [ref="B 59"]
  (50.96,6.85,50.98,6.88)
  [maxspeed=50]
  [lanes=2]
  [highway=secondary]
  [oneway=yes];
out geom;

Auf überraschende Weise trifft das übrigens auch auf unser Geldautomaten-Beispiel zu: Oft reicht es, gezielt nach einem speziellen Tag zu suchen, denn an allen Objekten mit dem speziellen Tag steht auch das allgemeine Tag:

Eine Suche nach Zäunen (barrier=fence) mit Eigenschaft fence_type=wood liefert dann auch praktisch das gleiche Ergebnis ...

nwr[barrier=fence][fence_type=wood]({{bbox}});
out geom;

... wie eine Suche nach nur fence_type=wood:

nwr[fence_type=wood]({{bbox}});
out geom;

Bei den Geldautomaten haben wir dagegen mehr Treffer, wenn wir nur nach atm=yes suchen:

nwr[atm=yes]({{bbox}});
out center;

Fachlich ist das durchaus überzeugend: Geldautomaten können eben auch an Tankstellen, in Einkaufszentren oder anderen Gebäuden stehen.

Oder-Verknüfung

Wir wollen nun zwei oder mehr Bedingungen so verknüpfen, dass alle Objekte gefunden werden, die mindestens eine der Bedingungen erfüllen. Auch hier haben wir schon einige Beispiele gesehen: Alle Objekte in Bounding-Boxen, Ergänzung benutzter Objekte, Als Beispiel eines Block-Statements

Für unser Beispiel von oben müssen wir das Problem lösen, sowohl alleine stehende Geldautomaten als auch solche in Banken zu finden:

(
  nwr[amenity=atm]({{bbox}});
  nwr[atm=yes]({{bbox}});
);
out center;

Unsere Verknpüfung übernimmt das Union-Statement in den Zeilen 1 bis 4. Es führt seinen inneren Block aus. Zeile 2 schreibt als Ergebnis in das Set _ alle Objekte, die ein Tag amenity mit Wert atm haben und in der von Overpass-Turbo befüllten Bounding-Box liegen. Union behält eine Kopie dieses Ergebnisses. Zeile 3 schreibt als Ergebnis in das Set _ alle Objekte, die ein Tag atm mit Wert yes haben und in der erneut von Overpass-Turbo befüllten Bounding-Box liegen. Danach schreibt Union ins Set _ als Ergebnis alle Objekte, die in mindestens einem der Teilergebnisse vorkommen - die gewünschte Oder-Verknüpfung.

Ein gängiger Fall ist es, eine recht lange Liste an Werten eines Tags prüfen zu müssen. Möchte man z.B. alle PKW-tauglichen Straßen finden, so entsteht an Werten für highway eine Liste der Art motorway, motorway_link, trunk, trunk_link, primary, secondary, tertiary, unclassified, residential. Mit Union kann man dies abfragen als:

(
  way[highway=motorway]({{bbox}});
  way[highway=motorway_link]({{bbox}});
  way[highway=trunk]({{bbox}});
  way[highway=trunk_link]({{bbox}});
  way[highway=primary]({{bbox}});
  way[highway=secondary]({{bbox}});
  way[highway=tertiary]({{bbox}});
  way[highway=unclassified]({{bbox}});
  way[highway=residential]({{bbox}});
);
out geom;

Man kann aber auch die im vorherigen Abschnitt vorgestellten regulären Ausdrücke benutzen und braucht nur noch:

way({{bbox}})
  [highway~"^(motorway|motorway_link|trunk|trunk_link|primary|secondary|tertiary|unclassified|residential)$"];
out geom;

Zeilen 1 und 2 bilden ein Query-Statement für Ways mit zwei Filtern; der Filter ({{bbox}}) für Bounding-Boxen ist bekannt. Vom anderen Filter ist die Tilde ~ das wichtigste Zeichen; sie passt auf Objekte, die ein Tag mit Key links von der Tilde, hier highway, und mit einem Wert tragen, der auf den Ausdruck rechts von der Tilde passt.

Die Syntax mit Caret ^ am Anfang und $ am Ende kennzeichnet, dass der Wert im Ganzen und nicht nur die bestmögliche Teilzeichenkette des Wertes passen muss. Der senkrechte Strich wiederum trennt verschiedene Alternativen voneinander, hier insgesamt 9 potentielle Werte für das Tag.

Der Abschnitt zu regulären Ausdrücken enthält mehr Beispiele.

In unserem Geldautomaten-Beispiel haben wir allerdings keinen gemeinsamen Key. Die Regulären Ausdrücke helfen uns daher hier nicht.

Was sich aber wiederholt, ist die Bedingung auf die Bounding-Box. Will man die Wiederholung vermeiden, so kann man die gemeinsame Bedingung vorziehen und das Ergebnis in einem Set zwischenspeichern; all ist ein sprechender Name dafür. Oft verkürzt es auch die Laufzeit der Abfrage:

nwr({{bbox}})->.all;
(
  nwr.all[amenity=atm];
  nwr.all[atm=yes];
);
out center;

Dem Union-Statement in den Zeile 2 bis 5 ist jetzt ein Query-Statement in Zeile 1 vorangestellt. Dort werden alle Objekte, die in der Bounding-Box liegen, im Set all abgelegt. Dieses Set wird im Union-Block zweimal benutzt: In Zeile 3 und Zeile 4 ist jeweils .all ein Filter, der das Ergebnis auf den Inhalt von all beschränkt. Es werden also in Zeile 3 genau die Objekte gefunden, die im Set all liegen und die ein Tag amenity mit Wert atm besitzen. In Zeile 4 werden genau die Objekte gefunden, die im Set all liegen und die ein Tag atm mit Wert yes besitzen.

Warum nehmen wir nicht einfach das Set _? Zwar wäre dies technisch möglich. Allerdings müssten wir dann bei jeder Zeile im Block daran denken, die Ausgabe umzuleiten. Das zu vergessen ist dann eine beliebte Quelle von Fehlern.

Gemischte Logik

...


weiter: Semikolon-Listen