Punkte entlang einer Relation selektieren?

Moin,

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.

Wie kriegt man das denn mal in den Griff?

LG,

-moenk

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. :frowning:

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.


MULTILINESTRING((13.3322228 52.5098621,13.3319644 52.5101493,13.3318528 52.5102016,13.3317035 52.5102379,13.3315564 52.5102399,13.3314374 52.5102115,13.3313037 52.5101751,13.3311852 52.5101428,13.3308118 52.5100156,13.3307345 52.5099425,13.330726 52.5098485,13.330737 52.5097314,13.3324708 52.5091516,13.3329762 52.5089938,13.3339333 52.5086905,13.334093 52.5086196,13.3341424 52.5086041,13.3342711 52.5085632,13.3343691 52.5085364,13.3336413 52.5076185,13.3336282 52.5075849),
(13.3331051 52.5066898,13.3330359 52.5066653,13.332969 52.506645,13.332797 52.5066096,13.3326767 52.5065803,13.3324288 52.5063775,13.3323368 52.5062876,13.3321896 52.5061582,13.3324127 52.5060708,13.3326066 52.5059904,13.3329803 52.5058253,13.3335677 52.5055445,13.333801 52.5054459,13.3338914 52.5054187,13.3340022 52.50539,13.3341882 52.5053602,13.3342093 52.5053565,13.3345149 52.5053184,13.3347878 52.5052959,13.3355211 52.505228,13.3360523 52.5051851,13.3361523 52.5051758,13.3365573 52.5051382,13.3371275 52.5050836,13.3372432 52.5050743,13.33734 52.5050665,13.3374348 52.5050604,13.3376497 52.5050523,13.3377746 52.5050511,13.337945 52.5050538,13.3380742 52.5050644,13.3383035 52.505091,13.3385979 52.5051351,13.3390516 52.5052028,13.3392427 52.5052265,13.339402 52.5052405,13.3394823 52.5052485,13.3395984 52.5052531,13.3398135 52.5052599,13.3399217 52.5052592,13.3399848 52.5052588,13.3401221 52.5052562,13.3403345 52.5052374,13.3405213 52.5052086,13.3407556 52.5051605,13.3409554 52.5051115,13.3411138 52.5050669,13.3412771 52.5050219,13.3424248 52.5047382,13.3428172 52.5046413,13.3428807 52.5046244),
(13.3336282 52.5075849,13.3336637 52.5074617,13.333675 52.5073998,13.3336688 52.5073514,13.3335939 52.5072338,13.3334919 52.5071043,13.3333641 52.5069426,13.3332508 52.5068075,13.3332104 52.5067607,13.3331687 52.5067274,13.3331051 52.5066898),
(13.3428807 52.5046244,13.3430147 52.5045888,13.3432689 52.5045213,13.3436382 52.5044251,13.3443615 52.5042302,13.3459125 52.5039343,13.3462707 52.5038562,13.3466129 52.5037817,13.3469333 52.5037094,13.3478766 52.5034963,13.3483069 52.5033992,13.3485601 52.503342,13.3485826 52.5033358,13.3488471 52.5032626,13.3489611 52.503235,13.3494245 52.5031227,13.3495607 52.5030905),
(13.3495607 52.5030905,13.3499599 52.5030023,13.3500307 52.5029846,13.3501797 52.5031583,13.3505424 52.5035191,13.3511955 52.5043762),
(13.3511955 52.5043762,13.3513922 52.5045988,13.3517563 52.5049637,13.3519842 52.5051624,13.3521837 52.5054965,13.3522473 52.5056077,13.3522956 52.5057519,13.3522915 52.5059059,13.3522711 52.5059934,13.3522009 52.5063856,13.3521698 52.5065057,13.3520031 52.5074909,13.3519137 52.5079227,13.3517399 52.5086097,13.351483 52.5095533,13.3514424 52.5096937,13.3514162 52.5097839,13.3512753 52.5102297,13.3512466 52.5103553,13.3508338 52.5119633,13.3504454 52.5134608,13.350424 52.5135564,13.3504078 52.513625,13.3504087 52.5136648,13.3504091 52.5136854,13.3504629 52.5137868,13.3505646 52.5138867,13.3506918 52.5139776),
(13.3506918 52.5139776,13.3507735 52.5140138,13.3508433 52.5140514,13.3508959 52.5140848,13.3509551 52.5141289,13.3510039 52.5141725,13.3510257 52.5141961,13.3510482 52.5142203,13.3511078 52.5143025,13.35114 52.5143753,13.3511565 52.5144455,13.3511612 52.5145272,13.3511522 52.5145935,13.3511242 52.5146771,13.3510934 52.5147343,13.3510552 52.514788,13.3509995 52.5148504,13.3509975 52.5149232,13.3510058 52.5149957,13.3510151 52.5150404,13.351037 52.5150871,13.3510583 52.5151227,13.3510904 52.5151631,13.3511659 52.515222,13.3512128 52.5152544,13.3513338 52.515341,13.3514341 52.51541,13.3517156 52.5155657,13.3519419 52.5156743,13.3523012 52.5158277,13.3526655 52.5159834,13.3531049 52.5161723,13.3539812 52.5165343,13.3540749 52.5165756,13.3543123 52.5166748,13.3544283 52.5167451,13.354449 52.5167698,13.3546198 52.5170959,13.3553269 52.5169773,13.3565365 52.5168763,13.3570657 52.5168815,13.3576374 52.5169193,13.3579024 52.5169495,13.3587165 52.5170845,13.3602587 52.5174347),
(13.3602587 52.5174347,13.3605731 52.5174849,13.3611117 52.5175763,13.361304 52.517596,13.3617203 52.5176412,13.3621207 52.5176504,13.3625497 52.5176474,13.3630557 52.517626,13.3634019 52.5176108,13.3634839 52.5176079,13.3646059 52.5175392,13.364677 52.5175348,13.3663335 52.5174565,13.3670321 52.5174152,13.3689645 52.5173181,13.3691094 52.5173291,13.369172 52.5173339,13.3699118 52.5177501,13.3700741 52.5177798,13.3708192 52.5177774,13.3738925 52.5177676,13.3740618 52.517767,13.3741364 52.5177668,13.3742178 52.5177666,13.3742363 52.5177665,13.3743265 52.5177662,13.3744181 52.5177659,13.3746532 52.5177652,13.374891 52.5177644,13.3768384 52.5177582,13.3769708 52.5177819,13.377458 52.5178572,13.3802697 52.5180501,13.3804653 52.5181243,13.3806227 52.5172463,13.3807243 52.5166302,13.3807666 52.516519,13.3808446 52.516345),
(13.3808446 52.516345,13.3822207 52.5164321,13.3830667 52.5164821,13.383392 52.5165013,13.3837192 52.5165242,13.3840019 52.5165448,13.3851397 52.5166209,13.3858296 52.5166735,13.3858452 52.5169605,13.3887849 52.5171337,13.3888315 52.5171365,13.3906611 52.5172481,13.3907451 52.5169857,13.3918566 52.5170419,13.3926385 52.5170913,13.3928574 52.5171052,13.3932103 52.517244,13.3932757 52.5172479,13.3932909 52.5172488,13.3945318 52.5173245,13.3950326 52.5173518,13.3951592 52.5173592,13.395885 52.5174049,13.3962558 52.5173215,13.3978822 52.5174128,13.3980453 52.5175392,13.3981985 52.5175434,13.3990127 52.5175928,13.3992028 52.5176217,13.3993386 52.5176423,13.3997079 52.5177242,13.4001448 52.5178929,13.400742 52.5181228,13.4010148 52.5182261,13.4010799 52.518251,13.4011171 52.5182653,13.4016721 52.5184779,13.4021056 52.5186439,13.4026249 52.5188391),
(13.4026249 52.5188391,13.4026968 52.5188665,13.4027334 52.5188799,13.4030883 52.5190235,13.4037598 52.5193696),
(13.4037598 52.5193696,13.4048107 52.5199179,13.4049445 52.5199913,13.4052166 52.520139,13.4056288 52.5203429,13.4061198 52.5205942,13.4073792 52.5212319,13.4087207 52.5219112),
(13.4087207 52.5219112,13.4094211 52.5222673,13.4095106 52.5223097,13.40981 52.5224514,13.4099961 52.5225395,13.4100096 52.5225452,13.410687 52.5229449))

zumindest mach er aus 66 Ways schon mal “nur noch” 12 Linestrings.

Hi, es ist war sehr misteriös:

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);

müsste etwa so aussehen:


  32749335 | 0101000020E6100000F50BC050D1AA2A40C3B8C08AF8404A40 | 0101000020E6100000FA426DC08CAA2A40C01B1C36DB404A40 | LINESTRING(13.3336282 52.5075849,13.3336637 52.5074617,13.333675 52.5073998,13.3336688 52.5073514,13.3335939 52.5072338,13.3334919 52.5071043,13.3333641 52.5069426,13.3332508 52.5068075,13.3332104 52.5067607,13.3331687 52.5067274,13.3331051 52.5066898)
 163385719 | 0101000020E6100000FE953A6D32AB2A40AC6983B817414A40 | 0101000020E6100000F40BC050D1AA2A40C2B8C08AF8404A40 | LINESTRING(13.3343691 52.5085364,13.3336413 52.5076185,13.3336282 52.5075849)
(2 rows)

 MULTILINESTRING((13.3336282 52.5075849,13.3336637 52.5074617,13.333675 52.5073998,13.3336688 52.5073514,13.3335939 52.5072338,13.3334919 52.5071043,13.3333641 52.5069426,13.3332508 52.5068075,13.3332104 52.5067607,13.3331687 52.5067274,13.3331051 52.5066898),(13.3343691 52.5085364,13.3336413 52.5076185,13.3336282 52.5075849))
(1 row)

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.


                  XXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYY
0101000020E6100000F50BC050D1AA2A40C3B8C08AF8404A40
0101000020E6100000F40BC050D1AA2A40C2B8C08AF8404A40
                   |               |

Und wenn die einfach auf Gleichheit verglichen werden, ist nix mit Zusammenfassen :frowning:

Gruss
walter

Nachtrag: Rundungsfehler

                      st_asgeojson                          |                              st_asgeojson                              

----------------------------------------------------------------±-----------------------------------------------------------------------
{“type”:“Point”,“coordinates”:[13.3336282,52.507584899999998]} | {“type”:“Point”,“coordinates”:[13.333628200000001,52.507584900000005]}
(1 row)

Beide Nodes sind fast gleich aber eben nicht ganz. Und schon verbindet PostGis die nicht miteinander :frowning:

Moin,

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 :wink:

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.

LG,

-moenk

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.

Bin noch nicht fertig :wink:

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.

Dachte das hätte sich schon erledigt:

  32749335 | 0101000020E6100000F40BC050D1AA2A40C2B8C08AF8404A40 | 0101000020E6100000F9426DC08CAA2A40BF1B1C36DB404A40 | LINESTRING(13.3336282 52.5075849,13.3336637 52.5074617,13.333675 52.5073998,13.3336688 52.5073514,13.3335939 52.5072338,13.3334919 52.5071043,13.3333641 52.5069426,13.3332508 52.5068075,13.3332104 52.5067607,13.3331687 52.5067274,13.3331051 52.5066898)
 163385719 | 0101000020E6100000FE953A6D32AB2A40AC6983B817414A40 | 0101000020E6100000F40BC050D1AA2A40C2B8C08AF8404A40 | LINESTRING(13.3343691 52.5085364,13.3336413 52.5076185,13.3336282 52.5075849)

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):


LINESTRING(13.3322228 52.5098621, .... .... .... ,13.410687 52.5229449)

dann haben wir genau das, was du brauchst. Sollte da aber


MULTILINESTRING((13.3322228 52.5098621,.....),( .....  ,13.410687 52.5229449))

stehen, haben wir das Problem immer noch.
Schaun mer mal.

Gruss
walter

Moin,

anders als erwartet kommt bei mir eine leere Menge raus :wink:

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.

LG,

-moenk

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.

Gruss
walter