ich hätte gern mal die Punkte die die Wegstücke in einer Relation - hier z.B. http://www.openstreetmap.org/browse/relation/1900691 - stützen. Kein Ding, da machen wir doch mal eine Abfrage (PostGIS mit Osmosis-Schema):
select st_x(n.geom) as lon, st_y(n.geom) as lat, n.tags->'name' as name
from nodes as n inner join (
select node_id, rm.sequence_id as seq1, wn.sequence_id as seq2 from relation_members as rm
inner join way_nodes as wn on rm.member_id=wn.way_id
where rm.relation_id=1900691 and rm.member_type='W')
as p on n.id=p.node_id
order by seq1, seq2 asc;
Die Punkte sind auch soweit richtig. Nur dummerweise sind einige Wegstücke nicht in Richtung der Buslinie, fährt man die Punkte dann der Reihe nach ab, springts immer mal wieder vor, fährt zurück und springt dann weiter.
Frage: Ist es garantiert, dass es nur einen Weg gibt? Gerade bei Routen ist das nicht der Fall.
Ich würde hier unbedingt die GIS-Funktionen von PostGis ausnutzen, da du hier auf dem untersten Roh-Daten-Level “rumkrebst”. Schliesslich handelt es sich bei der DB nicht nur um eine Ansammlung der in den OSM-Dateien befindlichen Objekte (Nodes, Way und Relations), sondern um wesentlich mehr. Und das sollte man auch ausnutzen.
Selektiere alle Geometrien der Ways (Spalte linestring) und fasse die mit st_union zusammen. Dann hast du eine Geometrie, deren Nodes du mit weiteren PostGIS-Funktionen auslesen kannst. Siehe: http://postgis.refractions.net/docs/reference.html
sorry, Beispiel zu schnell geposted - Nodes waren immer noch nicht sortiert.
Gruss
walter
Zwischenstand:
select st_asText(st_LineMerge(st_Collect(linestring)))
from ways w
inner join ( select member_id
from relation_members
where relation_id=1900691
and member_type='W') as r
on w.id=r.member_id
;
sollte eigentlich das Ergebnis (ein Linestring mit allen verbundenen Ways) liefern - macht es aber noch nicht ganz. Irgendwo klemmt es noch.
Könnte bitte jemand, der eine DB im Snapshot-Schema hat, bitte diese Query laufen lassen und das Ergebnis posten?
select id, st_startpoint(linestring), st_endpoint(linestring), st_astext(linestring)
from ways
where id in(163385719,32749335);
select st_astext(st_collect (linestring))
from ways
where id in(163385719,32749335);
komisch ist, dass zwei Nodes - der erste vom 1 Linestring und der letzte vom 2. Linestring - identisch aussehen (13.3336282 52.5075849) , aber im WKB-Format unterschiedlich sind.
danke erst mal für Deinen Einsatz! Um die Strecke so etwa abfahren zu können, hab ich mal etwas gepfuscht:
select st_x(st_centroid(w.linestring)) as lon, st_y(st_centroid(w.linestring)) as lat, w.tags->'name' as name, w.tags->'highway' as description
from relation_members as r inner join ways as w on w.id=r.member_id
where relation_id=1900690 and member_type='W'
order by r.sequence_id asc;
Das klappt auch recht gut, weicht aber an einigen Stellen mit großen Wegsegmenten ziemlich vom Weg ab, hat was von Ideallinie
Mir wäre auch lieber ich könnte räumliche Aggregatfunktionen benutzen, aber das ändert nichts am Problem dachte ich mir: Wenn die Wegstücke falschrum vorliegen dreht PostGIS mit die doch auch nicht passend, sondern klatscht eben so herum hintereinander?
Ich hab schon daran gedacht, mit st_segmentize die Ways in minimale Stückchen zu hacken und dann erst das Zentroid zu verwenden. Das löst zwar auch das Problem nicht, wäre aber schon dichter an der Lösung.
Kann man vielleicht etwas mit dem Relationsindex anfangen? Ich meine immerhin sollten die Wege ja in der richtigen Reihenfolge in der Relation stehen.
Der zweite Ansatz wäre statt mit den Geometrien zu arbeiten mit den IDs der Punkte zu nehmen und die Wege so zusammenzusetzen. Im anschluss kann man aus den Koordianten immer noch die Geometrie erzeugen.
Mit “sollten” hast Du völlig Recht, leider sieht die Realität oft anders aus. Wenn moenk die Punkte einmalig für eine bestimmte Relation braucht, könnte er vorher die Relation mit JOSM in Ordnung bringen. Wenn er solche Abfragen häufiger für verschiedene (unbekannte) Relationen braucht, scheidet diese Option wohl aus und er muß die Ordnung lokal in seiner Software herstellen.
Bei Relationen mit route=road hingegen kommt man mit der Ordnung meist ohnehin nicht weit - keine Ahnung, ob das für moenks Anwendungsfall relevant ist. Und ja, solche (Sammel-)Relationen haben sich im Grunde überlebt.
Das Problem ist einfach, das manche Endpunkte aufgrund von Rundungsfehlern nicht 100% mit dem nächsten möglichen Startpunkt übereinstimmen. Abweichung in meinem konkreten Fall: 1 Bit!
Die Lösung mit st_LineMerge() ist so elegant, dass ich sie auf jeden Fall verwenden würde - wenn das Problem weg ist. Sie wird in den Manuals so beschrieben und sollte daher auch im OSM-Umfeld funktionieren.
Ich kontaktiere mal Brett (Autor von osmosis), da die in der DB vorhandenen Geometrien (Spalten geom bei nodes, linestring und bbox bei ways) von osmosis beim Import erzeugt werden. Und die PostGis-Leute wohl auch.
Könntest du mir bitte das Ergebnis der oben erwünschte Abfrage schicken? Das könnte mir doch weiter helfen.
Gruss
walter
p.s. Es gibt in PostGis die sog. Topologien- das ist eine relativ neue Erweiterung, mit der man solche Projekte realisieren kann. Hier mal ein mit Topologies erzeugter Graph “deiner” Relation:
Allerdings ist der Einstieg nicht gerade einfach und ich bin auch noch nicht so richtig drin.
Das tun sie auch, daher ja auch die Sortierung, in diesem Fall doppelt sogar (hier seq1,seq2). Das hilft aber nix wenn die Wege schon falsch herum (aus semantischer Sicht der Relation) in der Datenbank liegen. Man kann hächstens die Wege komplett neu sortieren so wie osm2pgsql das AFAICR macht.
die Daten sind sauber, zumindest für diese beiden Ways. Also bitte:
select st_asText(st_LineMerge(st_Collect(linestring)))
from ways w
inner join ( select member_id
from relation_members
where relation_id=1900691
and member_type='W') as r
on w.id=r.member_id;
Das Ergebnis sollte so aussehen (die Koordinaten sind eventuell unterschiedlich):
anders als erwartet kommt bei mir eine leere Menge raus
Sieht so aus als ob auf dem st_collect nichts mehr zurückkommt. Achja:
POSTGIS=“1.5.1” GEOS=“3.2.0-CAPI-1.6.0” PROJ=“Rel. 4.7.1, 23 September 2009” LIBXML=“2.7.7” USE_STATS
Weils ein Produktivsystem ist werd ich das auch grad nicht ändern.
Ohne das st_collect, also nur das st_linemerge auf w.linestring angewendet kommen wieder einzelne ways raus - die sich sogar den Koordinaten nach hätten kombinieren lassen.
Danke, könnte bei dir an postgis 1.5 liegen. 2.0.x ist aktuell und da hat sich einiges getan. Nun denn, dann kann ich nichts mehr für dich tun.
Es sieht übrigens nach einem lokalen Problem in meiner DB aus, das irgendwas mit dem Import vom Planet im Frühjahr zu tun haben muß.
Was du dann tun müsstes:
entweder upgrade auf Postgis 2.0.3
oder selber rechnen. das ganze in pgsql, weil das in eine einzige Query zu quetschen, dürfte nahezu unmöglich sein:
select auf alle Ways einer Relation
einen way suchen, dessen Start/Endpunkt NICHT Start/Endpunkt eines der anderen Ways ist und mit dem anfangen
Schleife über alle “freien” Ways, bis du einen passenden gefunden hast.
gefundenen Way eventuell umdrehen
diesen Way dranhängen und aus der Kandidatenliste löschen
Ende Schleife
Ergebnis ausgeben
kann aber nur klappen, wenn die Routen nicht verzweigt sind. das hab ich aber ganz am Anfang schon geschrieben.