Overpass: «does not support the diff or adiff mode»
Warum eine Verlaufsabfrage mit [diff:] oder [adiff:] mit JSON- oder CSV-Ausgabe scheitert, und zwei Wege zu den Änderungen.
[out:json] oder [out:csv(…)] aus einer Abfrage mit [diff:] oder [adiff:], oder schreiben Sie [out:xml], und lesen Sie das XML. Braucht Ihr Code JSON, führen Sie die Abfrage für jedes Datum einmal mit [date:] aus und vergleichen Sie die beiden Antworten nach Typ, ID und Version.
Der Fehler
[out:json][adiff:"2024-01-01T00:00:00Z","2025-01-01T00:00:00Z"]; nwr(47.3693,8.5385,47.3707,8.5405)(if:t["amenity"]=="restaurant"); out meta;
Overpass lehnt diese Abfrage ab, bevor sie läuft, mit HTTP 400 und einer HTML-Seite mit diesem Text:
Error: line 1: static error: The selected output format does not support the diff or adiff mode.
[out:csv(…)] erhält dieselbe Antwort. Ein Diff ist eine Liste von <action>-Elementen mit einer alten und einer neuen Version, und nur die XML-Ausgabe hat dafür eine Form.
Lösung 1: das XML lesen
Schreiben Sie [out:xml], oder lassen Sie die Einstellung out weg; XML ist der Standard. Python liest die Antwort mit xml.etree.ElementTree aus der Standardbibliothek:
import xml.etree.ElementTree as ET
root = ET.fromstring(answer) # die Bytes der Antwort
for action in root.findall("action"):
old, new = action.find("old/*"), action.find("new/*")
print(action.get("type"), (new if new is not None else action[0]).get("id"))
Jede Aktion ist create, modify oder delete. Bei [adiff:] ist ein delete, dessen neue Version visible="false" hat, ein gelöschtes Element, und eines mit visible="true" gibt es noch, es passt aber nicht mehr zur Abfrage. Änderungen in OpenStreetMap zwischen zwei Daten enthält das ganze Skript.
Lösung 2: zwei Abfragen in JSON
Führen Sie dieselbe Abfrage mit [date:] für jedes der beiden Daten aus und vergleichen Sie die Elemente. Mit out meta hat jedes Element seine Version, eine Bearbeitung zeigt sich also als andere Version:
import json
import os
import urllib.parse
import urllib.request
URL = "https://api.overpass.ch/v1/" + os.environ["OVERPASS_CH_KEY"] + "/interpreter"
QUERY = """[out:json][timeout:60][date:"{date}"];
nw(47.369,8.541,47.376,8.547)(if:t["amenity"]=="restaurant");
out meta center;"""
def at(date):
data = urllib.parse.urlencode({"data": QUERY.format(date=date)}).encode()
els = json.loads(urllib.request.urlopen(URL, data=data, timeout=90).read())["elements"]
return {(e["type"], e["id"]): e for e in els}
a, b = at("2023-01-01T00:00:00Z"), at("2025-01-01T00:00:00Z")
for k in sorted(b.keys() - a.keys()):
print("added ", b[k]["tags"].get("name", k))
for k in sorted(a.keys() - b.keys()):
print("removed ", a[k]["tags"].get("name", k))
edited = [k for k in a.keys() & b.keys() if a[k]["version"] != b[k]["version"]]
print(len(edited), "edited,", len(a.keys() & b.keys()) - len(edited), "unchanged")
added Da Raffaele
added Rank
added Rank
added Wien Zeile
added Rising Sun
added Hirschli
added roots
added Restaurant zum weissen Kreuz
removed Enzian vegan food
removed Isebähnli
removed The Butcher
removed Kormasutra
removed Öpfelchammer
removed barfüsser
removed Bauernschänke
removed Long Wai
removed ('node', 9270127717)
removed ('node', 9870177417)
61 edited, 4 unchanged
Die Restaurants im Zürcher Niederdorf von 2023 bis 2025. Beide Abfragen zusammen dauerten 2,9 Sekunden. Die Summen sind die der Abfrage mit [adiff:] über dasselbe Gebiet, aber dieser Weg kann ein gelöschtes Restaurant nicht von einem unterscheiden, das jetzt etwas anderes ist: Beide fehlen am zweiten Datum. Um es herauszufinden, fragen Sie die fehlenden IDs am zweiten Datum ab, oder verwenden Sie [adiff:].
Gut zu wissen
[date:]allein funktioniert mit jedem Ausgabeformat, auch JSON und CSV. Nur[diff:]und[adiff:]brauchen XML.- Der Verlauf beginnt am 12. September 2012. Ein Datum davor liefert nur die Elemente, die seither niemand bearbeitet hat.
out metafügt Version, Zeit und Benutzer jedes Elements hinzu; ohne diese Angabe hat der JSON-Vergleich oben keine Versionen zum Vergleichen.
Bei overpass.ch
Verlaufsabfragen gehören zu den Tarifen Medium und Large; andere Tarife erhalten HTTP 403 history_not_in_plan. Overpass-Verlaufsabfragen erklärt [date:], [diff:] und [adiff:] mit Beispielen.