1 votos

¿Buscar y fusionar líneas que se tocan en PostGIS?

Me gustaría seleccionar y fusionar segmentos que se tocan como en la imagen de abajo.

Mi tabla contiene segmentos individuales con su propio id (mostrado en la figura), sólo quiero aislar un único "grupo" de segmentos que crea líneas individuales con su propio ID nuevo. He utilizado diferentes colores para explicar los diferentes grupos de segmentos que quiero encontrar.

No tengo ni idea de cómo hacerlo, porque no sé la longitud de las líneas.

figure

7voto

MBCook Puntos 8316

Puedes evitar la necesidad de una consulta recursiva adoptando el siguiente enfoque:

  • De cada LineString de entrada, extraiga los puntos finales en un MultiPoint de dos puntos
  • Ejecutar ST_ClusterWithin en los puntos finales extraídos
  • Une espacialmente las agrupaciones de puntos finales a las geometrías originales.

He aquí un ejemplo:

CREATE  TABLE test_lines (id serial, geom geometry);

INSERT INTO test_lines (geom)
VALUES
('LINESTRING (0 0, 1 1)'),
('LINESTRING (2 2, 1 1)'),
('LINESTRING (7 3, 0 0)'),
('LINESTRING (2 4, 2 3)'),
('LINESTRING (3 8, 1 5)'),
('LINESTRING (1 5, 2 5)'),
('LINESTRING (7 3, 0 7)');

WITH endpoints AS (SELECT ST_Collect(ST_StartPoint(geom), ST_EndPoint(geom)) AS geom FROM test_lines),
     clusters  AS (SELECT unnest(ST_ClusterWithin(geom, 1e-8)) AS geom FROM endpoints),
     clusters_with_ids AS (SELECT row_number() OVER () AS cid, ST_CollectionHomogenize(geom) AS geom FROM clusters)
SELECT ST_Collect(test_lines.geom) AS geom
FROM test_lines
LEFT JOIN clusters_with_ids ON ST_Intersects(test_lines.geom, clusters_with_ids.geom)
GROUP BY cid;

El resultado son las tres MultiLineStrings siguientes: enter image description here

5voto

dr_jts Puntos 61

Otra opción: utilizar el PostGIS ST_LineMerge función. Aquí está el ejemplo anterior rehecho con ella:

WITH data(geom) AS (VALUES
('LINESTRING (0 0, 1 1)'),
('LINESTRING (2 2, 1 1)'),
('LINESTRING (7 3, 0 0)'),
('LINESTRING (2 4, 2 3)'),
('LINESTRING (3 8, 1 5)'),
('LINESTRING (1 5, 2 5)'),
('LINESTRING (7 3, 0 7)') 
),
merged AS (SELECT (ST_Dump( ST_LineMerge( ST_Collect(geom) ) )).geom FROM data
)
SELECT row_number() OVER () AS cid, geom FROM merged;

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X