Tengo una tabla de calles que he seleccionado en función de un conjunto de atributos (digamos que es speed_limit < 25
). Hay grupos de calles que son localmente contiguas; Me gustaría agrupar estos conjuntos de cadenas de líneas conectadas en GeometryCollections. En la imagen a continuación, habría dos GeometryCollections: una con las líneas rojas y otra con las azules.
Traté de ejecutar un par de consultas de "disolver, desagregar" en la línea de:
SELECT (ST_Dump(st_union)).geom
FROM
(SELECT ST_Union(geom) FROM roads) sq
Con todo lo que he probado, termino con una sola característica ( ST_Union
) o mi geometría original ( ST_Dump
de ST_Union
).
¿Tal vez es posible hacer esto con algún tipo de WITH RECURSIVE
magia?
Respuestas:
Entonces, por ejemplo. Aquí hay una tabla simple con dos grupos de bordes conectados:
Ahora, aquí hay una función recursiva que, dada la identificación de un borde, acumula todos los bordes que se tocan:
Eso solo nos deja con la necesidad de encontrar, después de que cada grupo se acumula, la identificación de un borde que aún no es parte de un grupo. Lo cual, trágicamente, requiere una segunda consulta recursiva.
Lo que en conjunto devuelve un buen conjunto con el ID de semilla y cada grupo que acumuló. Lo dejo como un ejercicio para que el lector vuelva a convertir las matrices de id en una consulta para crear geometría para el mapeo.
fuente
grouplist
matriz:insert into lines (id, geom) values ( 15, 'LINESTRING(0 0, 10 10)');
. El cambioarray_agg(id)
en la función return toarray_agg(DISTINCT id)
parece resolver el problema.Aquí hay un enfoque que utiliza una tabla temporal para agregar clústeres de forma incremental. Realmente no me importa el enfoque de la tabla temporal, pero parece funcionar bastante bien a medida que aumenta el número de líneas (tengo 1.2 M líneas en mi entrada).
fuente
ST_ClusterIntersecting
función en PostGIS. Si sus datos son lo suficientemente pequeños como para caber en la memoria, le sugiero que los revise para obtener una solución más eficiente.