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:

La segunda opción parece factible, pero cualquier ayuda sobre cómo seguir este método sería muy apreciada.

Jelmer Baas
fuente

Respuestas:

6

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.

drop table if exists nodes;
drop table if exists nodes2;
drop table if exists buffers;

-- Get Start and End nodes
select ST_StartPoint(wkb_geometry) startnode,  ST_EndPoint(wkb_geometry) endnode,    ogc_fid into nodes  from sourceTable;
-- Combine all nodes into one table for easier queries
select startnode node, ogc_fid into nodes2 from nodes;
insert into nodes2 select endnode node, ogc_fid from nodes;

-- Some indexes to speed everything up
CREATE INDEX nodesstart_idx ON nodes USING gist  (startnode);
CREATE INDEX nodesend_idx ON nodes USING gist  (endnode);
CREATE INDEX nodes2_idx ON nodes2 USING gist  (node);
CREATE INDEX nodes_ogcfid_idx ON nodes USING btree (ogc_fid ASC NULLS LAST);

-- Create buffers, combine them, split combined objects again
select (ST_Dump(ST_Union(ST_Buffer(node, 1)))).geom geom into buffers from nodes2;
CREATE INDEX buffers_idx ON buffers USING gist  (geom);

-- Update start/end nodes table
UPDATE 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 points
update 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));

DROP TABLE nodes;
DROP TABLE nodes2;
DROP TABLE buffers;
Jelmer Baas
fuente
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.

katahdin
fuente
1

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.

Jordan Arseno
fuente
1
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.
Jelmer Baas