Anleitung

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 meta liefert 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.