Hallo!
Ich denke du must das 'geom' als Argument von GeomUnion() durch ein subselect oder eine andere Art der Selektion ersetzen.
Also etwa so:
Gruß UweCode:select GeomUnion((select the_geom from myGeomTable where blabla ));
Hallo,
ich bin noch ein Anfänger was PostGIS angeht und daher gibt es vielleicht eine ganz einfach Erklärung für mein Problem:
Ich möchte um eine Menge von Punkten eine konvexe Hülle bilden. Dazu gibt es die Funktion convexhull(). Laut PostGIS-Tutorial muss ich dazu zuerst mittels geomunion() die Punkte zu einer Einheit zusammenfassen. Das Problem ist jedoch, dass wenn ich den Aufruf:
mache mein postgresql auf 100% last geht und nichts passiert. Ich habe die Anfrage auch mal mehrere Minuten laufen lassen, aber kein Ergebnis. Auch eine Veränderung der Punktzahl bringt nichts, selbst ein Punkt kann geomunion nicht zusammenfassen.Code:select geomunion(geom) from test limit 10;
Die Tabelle sieht so aus:
Wenn ich die Funktion so aufrufe:Code:gisdba=# select asewkt(geom) from test limit 3; asewkt ------------------------------ POINT(4514195 5838521 32.83) POINT(4514188 5838520 32.79) POINT(4514189 5838520 32.78)
gibt es hingegen keine Probleme.Code:select geomunion('POINT(4514195 5838521 32.83)');
Hat jemand eine Idee wie ich das lösen kann?
Eike
Hallo!
Ich denke du must das 'geom' als Argument von GeomUnion() durch ein subselect oder eine andere Art der Selektion ersetzen.
Also etwa so:
Gruß UweCode:select GeomUnion((select the_geom from myGeomTable where blabla ));
Have a lot of fun!
Hallo Uwe,
danke für die Antwort. Leider funktioniert deine Idee nicht:
allerdings habe ich inzwischen festgestellt, dass GeomUnion scheinbar ein Problem damit hat wenn viele (>10000) Punkte in der Tabelle sind bzw. wenn GeomUnion mehr als diese Anzahl Punkte zusammenfügen muss.Code:gisdba=# select GeomUnion((select geom from test limit 10 )); FEHLER: als Ausdruck verwendete Unteranfrage ergab mehr als eine Zeile
Meine Idee ist jetzt mir so zu behelfen, dass ich zunächst immer etwa 10000 Punkte hole, die mit GeomUnion zusammenfasse und diese Unions dann nachher wieder zusammenfasse.
Jetzt belese ich mich gerade in den Postgresql und Postgis-Dokus wie ich das am sinnvollsten anstelle.
Gruß Eike
So hatte grad ein wenig Zeit zum Lesen und Testen:
hat einwandfrei funktioniert mit ca 2200 Punkten, Dauer ca 22s, aber die Daten kommen aus einem View, also sollte es bei einer pysikalischen Tabelle noch etwas fixer sein. Ich such mir aber mal noch nen großen Datensatz.Code:select convexhull(geomunion(geom)) from fok_geom;
Du konntes mal ein explain hier posten, dann könnte man vielleich sehen, wo es hängt.
Der Versuch, das ganze in kleine Stücke mit Union zu hacken, dürfte eher nichts bringen.
Sind die SRIDs der Punkte eigentlich alle gleich?
Gruß Uwe
Have a lot of fun!
Die erste Frage zuerst: Ja, die SRIDs sind alle gleich.
Ein EXPLAIN mit dem Befehl geomunion sagt mir:Code:gisdba=# select srid(geom) from test limit 2; srid ------ -1 -1 (2 Zeilen)
Ich habe selber noch ein wenig getestet und scheinbar steigt die benötigte Zeit mit der Anzahl der Punkte exponentiell:Code:gisdba=# explain SELECT geomunion(geom) FROM test; QUERY PLAN ----------------------------------------------------------------------- Aggregate (cost=277212.20..277212.20 rows=1 width=29) -> Seq Scan on test (cost=0.00..244751.16 rows=12984416 width=29) (2 Zeilen)
Ich habe dann ein Script geschrieben, dass die Tabelle tatsächlich in 1000er-Stücke hackt und diese Stücke dann mittels INSERT in eine weitere Tabelle eingefügt, so dass ich eine Tabelle namens unions haben in der immer 1000 Punkte in einer Geometry zusammengefasst sind. Schließlich mache ich dann ein "SELECT geomunion(geom) FROM unions;". Für 3000 Punkte braucht das Script dann 18 Sekunden statt wie oben gesehen 55 Sekunden.Code:~/ $ psql gisdba -q -c 'DROP TABLE tausend_a ;' -o /tmp/bla ~/ $ gisdba -q -c "SELECT geom INTO tausend_a FROM test LIMIT 1000 ;" -o /tmp/bla ~/ $ time psql gisdba -q -c 'SELECT geomunion(geom) FROM tausend_a ;' -o /tmp/bla real 0m5.869s ~/ $ psql gisdba -q -c 'DROP TABLE tausend_a ;' -o /tmp/bla ~/ $ gisdba -q -c "SELECT geom INTO tausend_a FROM test LIMIT 2000 ;" -o /tmp/bla ~/ $ time psql gisdba -q -c 'SELECT geomunion(geom) FROM tausend_a ;' -o /tmp/bla real 0m24.092s ~/ $ psql gisdba -q -c 'DROP TABLE tausend_a ;' -o /tmp/bla ~/ $ gisdba -q -c "SELECT geom INTO tausend_a FROM test LIMIT 3000 ;" -o /tmp/bla ~/ $ time psql gisdba -q -c 'SELECT geomunion(geom) FROM tausend_a ;' -o /tmp/bla real 0m54.664s
Ich kann mir das Verhalten nicht erklären, aber da ich die convexhull nur sehr selten erstellen muss denke ich, dass ich mit dem Workaround leben kann. Wenn natürlich eine bessere Lösung für das Problem existiert wäre ich natürlich trotzdem dankbar.Code:~/ $ time sh unionpsql.sh real 0m17.903s
Ja ich habe auch festgestellt, das geomunion bzw convexhull sehr teuer ist und die Zeit exponentiell mit der Punktezahl steigt. Hatte am Freitag nur vergessen das Ergebnis zu posten...![]()
Wenn man die Funktion nicht oft braucht ist wohl das Anlegen einer extra Tabelle am sinnvollsten.
Gruß Uwe
Have a lot of fun!
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen