Versionsgeschichte eines OpenStreetMap-Objekts
Jede Version eines Nodes, Ways oder einer Relation seit 2012, mit Datum, Benutzer und dem, was sich geändert hat, aus der Overpass API.
timeline(node, 26863664); liefert einen Eintrag für jede Version des Elements, mit der Zeit ihrer Entstehung. Führen Sie retro (_.val) { … } für jede dieser Zeiten aus, und Sie erhalten die Version selbst, mit out meta samt Versionsnummer, Zeit und Benutzer. Der Verlauf beginnt mit der Version, die am 12. September 2012 aktuell war.
Die Abfrage
Der Gipfel des Matterhorns, Node 26863664:
[out:json][timeout:60];
timeline(node, 26863664);
for (t["created"]) {
retro (_.val) {
node(26863664);
out meta;
}
}
timeline erzeugt für jede Version ein abgeleitetes Element mit den Tags refversion, created und, für alle ausser der aktuellen Version, expired. for (t["created"]) geht die Entstehungszeiten durch, und retro (_.val) führt den Block an jeder davon aus; node(26863664) liefert also die Version, die damals aktuell war. timeline allein dauerte 0,2 Sekunden, alle 35 Versionen mit retro 1,1 Sekunden.
Was sich in jeder Version geändert hat
Die Versionen kommen der Reihe nach. Das Skript vergleicht die Tags jeder Version mit denen der vorherigen; hat sich kein Tag geändert, wurde der Node verschoben. Es braucht Python 3 und sonst nichts; der Schlüssel kommt aus OVERPASS_CH_KEY.
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];
timeline(node, 26863664);
for (t["created"]) {
retro (_.val) {
node(26863664);
out meta;
}
}"""
data = urllib.parse.urlencode({"data": QUERY}).encode()
versions = json.loads(urllib.request.urlopen(URL, data=data, timeout=90).read())["elements"]
before = None
for v in versions:
tags = v.get("tags", {})
if before is None:
what = "the version of 12 September 2012, where the history starts"
else:
keys = sorted(k for k in before.keys() | tags.keys() if before.get(k) != tags.get(k))
what = ", ".join(f"{k}: {before.get(k, '-')} -> {tags.get(k, '-')}" if k == "name" else k for k in keys) or "position"
print(f"v{v['version']:<3} {v['timestamp'][:10]} {v['user'][:16]:<16} {what}")
before = tags
v16 2011-10-08 Thomas_Schmitt the version of 12 September 2012, where the history starts v17 2013-06-24 efa alt_name v18 2014-10-12 Marco_T wikipedia v19 2015-04-23 captain_slow wikipedia:de, wikipedia:en v20 2015-04-23 captain_slow wikipedia:de, wikipedia:en v21 2015-06-29 vancori alt_name, name: Matterhorn -> Cervino v22 2015-07-14 SimonPoole alt_name, name: Cervino -> Matterhorn v23 2017-02-17 ouleyang wikidata v24 2018-10-28 ManelG prominence, source:prominence v25 2020-04-12 AntEntro name:zh, name:zh-Hant v26 2021-08-11 Thomas_Schmitt position v27 2022-09-16 ManelG prominence, source:prominence v28 2023-07-14 woodрeck_reрair name:ru v29 2023-07-15 快乐的老鼠宝宝 name:ru … (16 weitere Versionen im Juli und August 2023, die name:ru ändern) v46 2024-02-09 Trailpapst fixme v47 2024-02-09 Trailpapst position v48 2024-02-09 Trailpapst position v49 2025-06-17 ds8the1st fixme v50 2025-09-30 harahu fixme
So lesen Sie es
- Version 16 stammt von 2011, aus der Zeit vor dem Beginn des Verlaufs; sie war am 12. September 2012 aktuell. Frühere Versionen sind nicht in den Verlaufsdaten.
- Im Juni 2015 wurde der Gipfel auf seinen italienischen Namen Cervino umbenannt und zwei Wochen später wieder Matterhorn genannt.
- Vom 14. Juli bis zum 21. August 2023 änderten 18 Versionen hintereinander nur
name:ru, den russischen Namen. - Der Benutzer einer Version ist das OpenStreetMap-Konto, das sie gespeichert hat.
out metaliefert auch das Changeset; auf openstreetmap.org zeigt/changeset/<id>seinen Kommentar und die übrigen Änderungen darin.
Ways und Relationen
timeline(way, id) und timeline(relation, id) funktionieren gleich. Ein Way erhält eine neue Version, wenn sich seine Tags oder seine Liste von Nodes ändern, nicht wenn einer seiner Nodes verschoben wird; um der Form zu folgen, fragen Sie auch die Nodes ab. Innerhalb von retro liefert way(id); (._; >;); out meta; den Way und seine Nodes zu jener Zeit.
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:], und das Beispiel alle Versionen eines Objekts führt diese Abfrage live aus.