Más

Identificación de "cadenas" de polígonos adyacentes con PostGIS

Identificación de


Tengo una tabla de polígonos (parcelas de tierra en una ciudad) y estoy tratando de identificar "cadenas" de 5 o más polígonos adyacentes. Por ejemplo, si cada letra es un polígono y cada. es un espacio vacío, AB.CD.EFG.HIJKL.MNOP.QRSTU.VWXYZ, entonces quiero HIJKL, QRSTU y VWXYZ. En la vida real no están en una línea como esa, por supuesto.

La solución desordenada que utilicé para un primer intento es esta consulta:

SELECCIONE p1.parcel_c como "Parcel 1", p2.parcel_c como "Parcel 2", p3.parcel_c como "Parcel 3", p4.parcel_c como "Parcel 4", p5.parcel_c como "Parcel 5", ST_Union (array [ p1. p2. , p3.parcel_c, p4.parcel_c, p5.parcel_c) y p2.parcel_c no están en (p1.parcel_c, p3.parcel_c, p4.parcel_c, p5.parcel_c) y p3.parcel_c no están en (p1.parcel_c, p2.parcel_c , p4.parcel_c, p5.parcel_c) y p4.parcel_c no están en (p1.parcel_c, p2.parcel_c, p3.parcel_c, p5.parcel_c) y p5.parcel_c no están en (p1.parcel_c, p2.parcel_c, p3.parcel_c , p4.parcel_c)

Como puede ver, esto es torpe y poco elegante y sospecho que es ineficiente. También devuelve muchos casi duplicados cuando hay una cadena de más de 5 paquetes, por ejemplo, si los paquetes son ABCDEF, devuelve ABCDE y BCDEF cuando una mejor solución devolvería la cadena más larga, ABCDEF. ¿Cómo puedo hacer esta consulta más eficiente, más elegante y en general más versátil?


Creo que tengo una solución para postgis 2.0+:

Primera subconsulta para seleccionar el volcado de polígonos unidos para obtener solo polígonos simples y no multies y también deshacerse de los bordes internos de los polígonos en contacto:

con merged_patches como (seleccione (st_dump (st_union (geom))). geom como geom de abandonded_vacant_lots_table),

La segunda subconsulta descarga los geoms simples de la tabla:

all_patches as (seleccione (st_dump (geom)). geom de abandonded_vacant_lots_table)

La consulta devolverá el recuento de polígonos adyacentes en parches y la geometría del parche combinado:

seleccione count (*), merged_patches.geom de merged_patches, all_patches donde

Donde el bbox se superpone para acelerar las cosas:

all_patches.geom && merged_patches.geom Y

La condición real está aquí: estamos comprobando si el parche actual está dentro de un parche combinado:

ST_Within (all_patches.geom, merged_patches.geom)

Agrupemos estos por merged_patches:

agrupar por merged_patches.geom

si desea devolver merged_patches con más de 5 subparches:

teniendo cuenta (*)> = 5;

Todos juntos:

with merged_patches as (select (st_dump (st_union (geom))). geom as geom from abandonded_vacant_lots_table), all_patches as (select (st_dump (geom)). geom from abandonded_vacant_lots_table) seleccione count (*), merged_patches.geom, de all_patches_merged donde all_patches.geom && merged_patches.geom Y ST_Within (all_patches.geom, merged_patches.geom) agrupan por merged_patches.geom con count (*)> = 5;

Tuve un problema algo similar (Eliminar islas y polígonos completamente rodeados después de la poligonización con QGIS) que inspiró esta respuesta.


Si sus "cadenas" no necesariamente tienen que ser una línea recta (es decir, si pueden bifurcarse), entonces puede abordar esto con las nuevas funciones de agrupamiento en PostGIS 2.2. Por ejemplo:

SELECT geom FROM (SELECT unnest (ST_ClusterIntersecting (geom)) AS geom FROM abandonded_vacant_lots_table) clusters DONDE ST_NumGeometries (clusters.geom)> = 5

En esta consulta, ST_ClusterIntersecting devuelve una matriz deGeometríaColecciónentidades, cada una de las cuales refleja una "cadena" potencialmente bifurcada. La función PostgreSQLdesanimarconvierte las entradas de la matriz en un conjunto de registros, formando elracimossubconsulta. Luego, seleccionamos solo las cadenas que tienen 5 o más geometrías.

La forma más sencilla de vincular estos resultados a su tabla original ("qué ID de parcela hay en los grupos") es utilizar una unión espacial entre los grupos y un punto interior de sus geometrías originales.

Puede encontrar que ST_ClusterWithin sea más útil, especialmente si tiene polígonos de parcela que casi se tocan pero no del todo.


Ver el vídeo: Identificación de los tipos de cadenas de carbono