Zugehörigkeiten von Knoten abfragen

Hallo,

ich will aus einem GPX Track, den Openrouteservice ausgibt, die Punkte herausfiltern, die defacto eine Kreuzung in der Realität darstellen.

Dabei gehe ich davon aus, dass die Trackpunkte, die Openrouteservice ausgibt, von den Koordinaten identisch sind mit den GPS-Daten, die OSM verwendet.

Also müsste ich mir die OSM-Datei des Gebietes besorgen, welches der Track abdeckt, besorgen. Diese Datei nach den einzelnen Punkten des Tracks abfragen. Wenn ich dann eine entsprechende Node-ID habe, dann sehe ich nach, ob dieser Node in mehreren Wegen enthalten ist. Wenn ja ist es eine Kreuzung.

Ich sehe aber das Problem, dass ich mich durch eine ziemliche große Datenmenge durchwühlen muss. Das Programm würde ziemlich lange rechnen.

Jetzt gibt aber OSM solche Daten wie unter
http://www.openstreetmap.org/browse/node/2039030908
oder
http://www.openstreetmap.org/browse/way/193394355
sehr schnell aus.

Deswegen stellt sich mir die Frage, gibt es eine runterladbare Datei, im welcher steht, zu was für einem Weg ein Node gehört.

Es gibt eine API-Abfrage, die die Elternwege eines Knoten liefert. Allerdings ist zu beachten, daß die API in erster Linie für die Mapper gedacht ist, also zum Bearbeiten der Datenbank. Deswegen erlaube ich mir die Frage, was Du vorhast: Möchtest Du einmalig in einem einzigen, nicht allzu langen Track die Kreuzungen finden? Dann ist sicher nichts dagegen einzuwenden, hierfür die API zu bemühen, auch wenn sie eigentlich nicht dafür gedacht ist. Oder soll das ganze regelmäßig laufen oder eine größere Zahl von Routing-Tracks durchsuchen? In dem Fall muß ein anderer Weg her.

Verrate uns doch einmal das Ziel der Übung. Eventuell gibt es eine andere, womöglich sogar einfachere Möglichkeit.

Nur mal so: Wenn ich ein Gebiet als OSM-Datei sample.osm herunterlade und das XML anschließend mit

cat sample.osm | fgrep '<nd' | sort | uniq -d | grep -o '[0-9]*'

filtere, habe ich eine Liste aller Knoten in dem Gebiet, die Element mehrerer Wege sind. Diese Wege müssen aber nicht allesamt Straßen sein: ein Knoten kann auch in einer Straße und z.B. einem landuse stecken. (Das gleiche Problem stellt sich bei der API-Abfrage im übrigen auch.) Also müssen die OSM-Daten zuvor noch so vorgefiltert werden, daß sie nur noch Straßen enthalten (Stichwort osmfilter, oder osmosis). Aber ansonsten habe ich eine Liste, in der ich nachsehen kann, ob ein Knoten Element mehrerer Wege ist.

ja, wenn du eine DB hast:


osm=# select way_id from way_nodes
where node_id=2039030908;
  way_id   
-----------
 193394355
 193394350
 193394345
(3 rows)

Time: 26,054 ms

Lohnt sich aber nur bei großen Projekten.

Gruss
walter

Ich brauche das zum Radfahren. Aus Sicherheits- und Energiespargründen finde ich ganz praktisch den Bildschirm nicht nutzen zu müssen. Ich nutze momentan drei Programme auf meinem Telephon. Garmin City Navigator, Osmand, und OziExplorerCE.

Alle drei haben eine Sprachausgabe. Bei Oziexplorer ist die Ansage am bestenführend, wenn man entsprechend die Routenpunkte setzt. Besonders schön ist das Nachts im Wald. Wenn ich diese Routen mit der Hand erstelle, brauche ich ungefähr 30 Minuten für 100 Kilometer.

Ein Weg dabei ist, sämtliche Kreuzungen zu markieren. Als ich das XML von Openrouteservice gesehen habe, kam mir die Idee vielleicht da etwas Geeignetes rausfiltern zu können. Ich habe versucht die Anfänge der LineString-Elemente zu nutzen, aber dabei ist nur etwas rausgekommen, das, wenn ich es nachbearbeite, ähnlich viel Zeit braucht, wie meine alte Methode.

Ich bastle mit Visual Basic rum. In anderen Worten ich verstehe den Code nicht.

Dann noch eine Frage, mein Radgebiet ist als osm.xml ungefähr 1,1 GB groß. Der Kern des Gebietes ist die Rhein-Main-Gegegend. Wieviel Prozent der Datenmenge bleibt übrig, wenn ich alle Wege und deren zugehörige Nodes rausfiltere.

Das sind diverse Programmaufrufe, die so wahrscheinlich nicht unter Windows laufen.


osmfilter.exe input.osm --keep="highway=" --drop-author -o=output.osm

Damit hast du dann erstmal nur noch relevante Daten. Damit lässt sich dann besser weiter arbeiten.

Dann könntest du mit VB die Datei Zeilenweise einlesen und die Koordinaten überprüfen. Wenn du ein <way in der Zeile hast bist du mit den Nodes durch. Zum finden des Nodes würde ich mir die Distanz zwischen SOLL und IST errechnen und wenn die kleiner als x m ist in ein 2d-Array speichern (id, Entfernung und ein Zähler). Dann nach Entfernung das Array sortieren und weiter die Ways einlesen. Wenn der Node in einer Zeile vorkamerhöhst du den Zähler um 1. Wenn du am Ende der Datei angekommen bist hast du ein Array mit vielen Nodes und suchst dir den nächsten aus, bei dem der Zähler >= als 2 ist.

Das kann man sicher noch verbessern, aber sollte erstmal ein guter erster Schuss sein mit vertretbarer Zeit.

Das heißt dann also, Du brauchst das regelmäßig. Zusammen mit der Länge der Routen (~100 km) fällt damit die Nutzung der API flach.

Das ist eine Kette von Unix-Shell-Kommandos. Die benötigten Programme (grep, uniq, sort) sind aber auch für M$-Systeme verfügbar.
Hier werden aus der .osm-Datei zuerst mit (f)grep alle Bezüge zu Knoten (beginnen mit “<nd”) ausgefiltert, dann wird die erhaltene Liste sortiert (sort). Ein Knoten, der Teil mehrerer Wege ist, steht anschließend also mindestens zweimal hintereinander in der Liste. Solche wiederholten Zeilen sucht uniq -d heraus (verwirft also alle, die nur einmal referenziert werden), und der letzte Befehl reduziert jeweils die Zeile " auf die Nummer des Knotens.

Macht also in etwa dasselbe, was Henning gerade beschrieben hat - aber in einer einzigen Zeile.

Nachtrag: mit Rücksicht auf den Speicherbedarf von sort ist es so herum sinnvoller (macht grob über’n Daumen einen Faktor 2):

cat sample.osm | fgrep '<nd' | grep -o '[0-9]*' | sort | uniq -d

Zur Orientierung: für den Regierungsbezirk Köln hat der Vorgang etwa 2 Minuten gedauert (abhängig von der Maschine, aber das ist die Größenordnung). Unkomprimiert ist dieser ebenfalls etwa 1,1 GB groß - inklusive Nicht-Straßen. Ergebnis war hier eine Liste von 1,4 Millionen IDs, als blanker Text etwa 15 Megabyte. Am Ende steht natürlich nur eine Liste von Knoten, d.h. der Abgleich mit Deinen Tracks kommt noch dazu, ist dafür aber sehr einfach und ohne Belastung der API möglich.

In Windows wird man die Programme hintereinander ausführen müssen, da Windows pipen nur sehr begrenzt unterstützt. Bei der Verwendung von Argumenten hört es leider auf.

Dafür gibt es dann z.B. cygwin oder MinGW/MSYS; oder man läßt mal eben ein Linux-Livesystem von DVD laufen, oder ein Linux in einer VM. Von radikaleren Schritten ganz zu schweigen. :wink:

Sollte ja nur der Hinweis sein, dass pipen und Windows nicht die besten Freunde sind.

Hast ja auch Recht, wahrscheinlich sogar damit, daß es unter M$ einfacher ist, schrittweise zu arbeiten, als den Umgang mit einem Betriebssystem zu erlernen: also die XML-Datei durch (f)grep schicken, Ausgabe in eine Datei umleiten. Diese Datei mit dem zweiten grep kürzen, Ergebnis in einer Datei speichern, diese wiederum …
Aber was für ein Frevel :roll_eyes: