Fang von Start- und Endknoten von Linien an anderen Linien in PostGIS
9
Es gibt viele Beispiele, die zeigen, wie Linien an Punkten gefangen werden, aber ich konnte keine (schnelle!) Möglichkeit finden, die Start- und Endknoten von Linienzeichenfolgen an Knoten anderer Linien zu fangen.
Im Wesentlichen möchte ich meine Ebene in Postgis (2.0) "reinigen", fast ähnliche Punkte zusammen verschieben und winzige Öffnungen zwischen Linienstrings zusammennähen.
Es wäre nicht so wichtig, ob ich einen weiteren Knoten hinzufüge, den ersten / letzten Knoten einer Linie verschiebe oder beide Punkte in die Mitte verschiebe.
Ich habe zwei Optionen gefunden, bin mir aber nicht sicher, wie ich mit einer von beiden beginnen soll:
Ich habe es geschafft, dieses Problem zu lösen, ohne die genannten GRASS-Tools oder topologischen Funktionen zu verwenden.
Grundsätzlich nehme ich alle Start- und Endknoten, füge sie in eine neue temporäre Tabelle ein, lege einen Puffer um sie, verbinde die Pufferobjekte und verschiebe alle gefundenen Knoten in jedem Puffer zum Schwerpunkt des Puffers.
Wenn das erledigt ist, verschiebe ich den ursprünglichen Start- und Endpunkt an den neuen Ort.
Einfacher als erwartet und immer noch schnell, aber ich hatte erwartet, dass PostGIS eine integrierte Funktion dafür hat - das wäre noch schneller.
Bearbeiten: Um der Community etwas zurückzugeben, ist dies vorerst mein (ziemlich beschissener) Code.
droptableifexists nodes;droptableifexists nodes2;droptableifexists buffers;-- Get Start and End nodesselect ST_StartPoint(wkb_geometry) startnode, ST_EndPoint(wkb_geometry) endnode, ogc_fid into nodes from sourceTable;-- Combine all nodes into one table for easier queriesselect startnode node, ogc_fid into nodes2 from nodes;insertinto nodes2 select endnode node, ogc_fid from nodes;-- Some indexes to speed everything upCREATEINDEX nodesstart_idx ON nodes USING gist (startnode);CREATEINDEX nodesend_idx ON nodes USING gist (endnode);CREATEINDEX nodes2_idx ON nodes2 USING gist (node);CREATEINDEX nodes_ogcfid_idx ON nodes USING btree (ogc_fid ASC NULLS LAST);-- Create buffers, combine them, split combined objects againselect(ST_Dump(ST_Union(ST_Buffer(node,1)))).geom geom into buffers from nodes2;CREATEINDEX buffers_idx ON buffers USING gist (geom);-- Update start/end nodes tableUPDATE nodes SET startnode = ST_Centroid((select geom from buffers WHERE geom && startnode));UPDATE nodes SET endnode = ST_Centroid((select geom from buffers WHERE geom && endnode));-- Update original pointsupdate sourceTable set wkb_geometry = ST_SetPoint(
ST_SetPoint(wkb_geometry,0,(select startnode from nodes where ogc_fid=sourceTable.ogc_fid)),
ST_NumPoints(wkb_geometry)-1,(select endnode from nodes where ogc_fid=sourceTable.ogc_fid));DROPTABLE nodes;DROPTABLE nodes2;DROPTABLE buffers;
Diese Antwort ähnelt ziemlich dem "nicht topologischen" Vorschlag aus meiner Antwort. Es wäre nett, wenn Sie eine Gegenstimme abgeben oder die Antwort auswählen würden. Das ist es, was die Community hier
füttert
Du hast recht. Ich habe Ihre Antwort positiv bewertet und werde meine Antwort so bearbeiten, dass sie meinen Code enthält.
Jelmer Baas
4
Hier sind drei Optionen. Hoffentlich hilft man.
v.clean
Mit den GRASS-Werkzeugen in QGIS können Sie die Topologie eines räumlichen Objekts bereinigen. Der Benutzer @RK gibt in einer Antwort auf eine andere Frage eine Reihe guter Anweisungen dazu . Der Vorteil von GRASS besteht darin, dass auf die Topologie des Shapefiles geschlossen wird. Der Nachteil für Ihre Situation ist, dass sich Ihre Daten nicht in einem Shapefile befinden. Natürlich können Sie die Daten von Postgres mit dem Werkzeug "PostGIS-Ebene hinzufügen" in ein Shapefile exportieren, aber das ist ein zusätzlicher Schritt.
Nicht topologische PostGIS-Funktionen
In PostGIS können Sie die Funktionen ST_EndPoint und ST_StartPoint verwenden, um den End- und Startpunkt für einen Linestring abzurufen. Mithilfe einer Kombination aus ST_DWithi n und ST_Distance können Sie dann den nächsten Start- oder Endpunkt auf einer nahe gelegenen Geometrie finden. Wenn Sie viele Punkte haben, beschleunigt ST_DWithin die Abfrage erheblich - vorausgesetzt, Sie haben einen Index. Von dort aus müssen Sie eine Regel festlegen, die definiert, welche Punkte geändert und welche festgelegt werden sollen.
Der Vorteil hierbei ist, dass Sie Ihre Daten nicht zur Reinigung an GRASS senden müssen, aber es gibt einige Fallstricke, auf die Sie achten müssen.
Topologische PostGIS-Funktionen
Die Frage bezog sich auf die topologischen Funktionen von PostGIS. Diese funktionieren hervorragend, aber wie im Wiki beschrieben , müssen Sie die Kanten, Knoten und Flächen explizit definieren. Dies ist eindeutig ein Problem für Ihren Datensatz, da Sie Probleme mit der Topologie kennen.
Danke, ich bin mir dieser Funktionen bewusst. ST_Snap schnappt ALLE Knoten, ich möchte nur den Start- und Endknoten. ST_SnapToGrid ist nicht wirklich geeignet, da es die gesamte vorhandene Geometrie ändert und die Möglichkeit hat, Knoten zu verschieben, die sich weiter entfernt befinden, da sie kaum in ein anderes Segment fallen.
Hier sind drei Optionen. Hoffentlich hilft man.
v.clean
Mit den GRASS-Werkzeugen in QGIS können Sie die Topologie eines räumlichen Objekts bereinigen. Der Benutzer @RK gibt in einer Antwort auf eine andere Frage eine Reihe guter Anweisungen dazu . Der Vorteil von GRASS besteht darin, dass auf die Topologie des Shapefiles geschlossen wird. Der Nachteil für Ihre Situation ist, dass sich Ihre Daten nicht in einem Shapefile befinden. Natürlich können Sie die Daten von Postgres mit dem Werkzeug "PostGIS-Ebene hinzufügen" in ein Shapefile exportieren, aber das ist ein zusätzlicher Schritt.
Nicht topologische PostGIS-Funktionen
In PostGIS können Sie die Funktionen ST_EndPoint und ST_StartPoint verwenden, um den End- und Startpunkt für einen Linestring abzurufen. Mithilfe einer Kombination aus ST_DWithi n und ST_Distance können Sie dann den nächsten Start- oder Endpunkt auf einer nahe gelegenen Geometrie finden. Wenn Sie viele Punkte haben, beschleunigt ST_DWithin die Abfrage erheblich - vorausgesetzt, Sie haben einen Index. Von dort aus müssen Sie eine Regel festlegen, die definiert, welche Punkte geändert und welche festgelegt werden sollen.
Der Vorteil hierbei ist, dass Sie Ihre Daten nicht zur Reinigung an GRASS senden müssen, aber es gibt einige Fallstricke, auf die Sie achten müssen.
Topologische PostGIS-Funktionen
Die Frage bezog sich auf die topologischen Funktionen von PostGIS. Diese funktionieren hervorragend, aber wie im Wiki beschrieben , müssen Sie die Kanten, Knoten und Flächen explizit definieren. Dies ist eindeutig ein Problem für Ihren Datensatz, da Sie Probleme mit der Topologie kennen.
quelle
PostGIS hat Fangfunktionen. Vielleicht helfen sie?
ST_Snap
: Fang Segmente und Scheitelpunkte der Eingabegeometrie an Scheitelpunkten einer Referenzgeometrie.ST_SnapToGrid
: Fangen Sie alle Punkte der Eingabegeometrie an einem regulären Raster.quelle