Ajustar nodos iniciales y finales de líneas a otras líneas en PostGIS
9
Hay muchos ejemplos que muestran cómo ajustar líneas a puntos, pero no he podido encontrar ninguna forma (¡rápida!) De ajustar los nodos inicial y final de las cadenas de línea a nodos de otras líneas.
Esencialmente quiero "limpiar" mi capa en postgis (2.0), moviendo puntos casi similares y cosiendo pequeñas aberturas entre cadenas de líneas.
No importaría tanto si agrego otro nodo, muevo el primer / último nodo de cualquier línea o muevo ambos puntos al centro.
He encontrado dos opciones, pero no estoy seguro de cómo comenzar con cualquiera de ellas:
He logrado resolver esto, sin usar las herramientas GRASS mencionadas o las funciones topológicas.
Básicamente tomo todos los nodos de inicio y final, los coloco en una nueva tabla temporal, coloco un búfer alrededor de ellos, unimos los objetos del búfer y muevo todos los nodos encontrados en cada búfer al centroide del búfer.
Cuando termine, muevo los puntos de inicio y finalización originales a la nueva ubicación.
Más fácil de lo esperado y aún rápido, pero esperaba que PostGIS tuviera alguna función incorporada para esto, eso sería aún más rápido.
Editar: en interés de devolver a la comunidad, este es mi código (bastante malo) por ahora.
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;
Esta respuesta se parece bastante a la sugerencia "no topológica" de mi respuesta. Sería amable si hicieras un voto positivo o seleccionaras la respuesta. Esos son los que alimentan a la comunidad aquí :)
katahdin
Tienes razón. He votado tu respuesta y editaré mi respuesta para incluir mi código.
Jelmer Baas
4
Aquí hay tres opciones. Esperemos que uno ayude.
v.limpiar
Usando las herramientas GRASS en QGIS puede limpiar la topología de un objeto espacial. El usuario @RK da un buen conjunto de instrucciones sobre cómo hacer esto en una respuesta a una pregunta diferente . La ventaja de GRASS es que inferirá la topología del shapefile. La desventaja de su situación es que sus datos no están en un archivo de forma. Por supuesto, puede exportar los datos de Postgres a un archivo de forma usando la herramienta "Agregar capa PostGIS", pero eso es un paso adicional.
Funciones no topológicas de PostGIS
En PostGIS puede usar las funciones ST_EndPoint y ST_StartPoint para obtener el punto final y de inicio de una cadena lineal. Luego, utilizando una combinación de ST_DWithi n y ST_Distance , puede encontrar el punto inicial o final más cercano en una geometría cercana. Si tiene muchos puntos, ST_DWithin acelerará mucho la consulta, suponiendo que tenga un índice en su lugar. A partir de ahí, deberá establecer una regla que defina qué puntos deben modificarse y cuáles son fijos.
La ventaja aquí es que no tiene que enviar sus datos a GRASS para su limpieza, pero hay algunas dificultades a tener en cuenta.
Funciones topológicas de PostGIS
La pregunta hacía referencia a las funciones topológicas de PostGIS. Estos funcionan muy bien, pero, como lo describe la wiki , debes definir explícitamente los bordes, nodos y caras. Claramente, esto será un problema para su conjunto de datos ya que tiene problemas conocidos con la topología.
Gracias, estoy al tanto de estas funciones. ST_Snap ajusta TODOS los nodos, solo quiero el nodo inicial y final. ST_SnapToGrid no es realmente adecuado porque modifica toda la geometría existente y tiene la posibilidad de mover nodos que están más cerca, ya que apenas caen en otro segmento.
Aquí hay tres opciones. Esperemos que uno ayude.
v.limpiar
Usando las herramientas GRASS en QGIS puede limpiar la topología de un objeto espacial. El usuario @RK da un buen conjunto de instrucciones sobre cómo hacer esto en una respuesta a una pregunta diferente . La ventaja de GRASS es que inferirá la topología del shapefile. La desventaja de su situación es que sus datos no están en un archivo de forma. Por supuesto, puede exportar los datos de Postgres a un archivo de forma usando la herramienta "Agregar capa PostGIS", pero eso es un paso adicional.
Funciones no topológicas de PostGIS
En PostGIS puede usar las funciones ST_EndPoint y ST_StartPoint para obtener el punto final y de inicio de una cadena lineal. Luego, utilizando una combinación de ST_DWithi n y ST_Distance , puede encontrar el punto inicial o final más cercano en una geometría cercana. Si tiene muchos puntos, ST_DWithin acelerará mucho la consulta, suponiendo que tenga un índice en su lugar. A partir de ahí, deberá establecer una regla que defina qué puntos deben modificarse y cuáles son fijos.
La ventaja aquí es que no tiene que enviar sus datos a GRASS para su limpieza, pero hay algunas dificultades a tener en cuenta.
Funciones topológicas de PostGIS
La pregunta hacía referencia a las funciones topológicas de PostGIS. Estos funcionan muy bien, pero, como lo describe la wiki , debes definir explícitamente los bordes, nodos y caras. Claramente, esto será un problema para su conjunto de datos ya que tiene problemas conocidos con la topología.
fuente
PostGIS tiene funciones de ajuste ... ¿tal vez ayudarán?
ST_Snap
: Ajusta segmentos y vértices de la geometría de entrada a los vértices de una geometría de referencia.ST_SnapToGrid
: Ajuste todos los puntos de la geometría de entrada a una cuadrícula regular.fuente