¿Cómo transformar un conjunto de segmentos de calle en bloques de ciudad, con PostGIS2?

8

Teóricamente es posible obtener los polígonos de bloques de ciudades ( bloques urbanos) de las calles, cuando las calles están representadas por el eje de la calle ( LineStrings ).

Los bloques urbanos están delimitados por calles, por lo que los segmentos de calles se pueden usar para formar un polígono que contiene solo una cuadra dentro ... Ver ilustraciones.

Hay un script (SQL) PostGIS 2.X para hacer esto? ¿Un software de complemento?
PD: las geometrías aproximadas de bloques de ciudades son suficientes.

Ilustrando

Comenzando el proceso desde una "malla de segmentos de línea conectados", puede ser: 1) obtener polígonos asociados; 2) aislar los polígonos mediante tampón negativo y restar el tampón de las líneas.

ingrese la descripción de la imagen aquí

Ejemplo: el polígono 262 (que representa una manzana) se originó en los segmentos 2496, 2494, 2369, 1513, ... Y el polígono vecino 263 puede usar algunos segmentos comunes, pero a continuación (por st_buffer negativo u otra operación) será polígonos realmente aislados, por lo tanto, baja precisión es suficiente.


(EDITAR)

Creo que podemos traducir este problema específico en uno más genérico: el conjunto de segmentos de calles puede verse como una especie de teselación , es decir, los segmentos separan el plano en regiones contiguas : los bloques urbanos se encuentran en el interior de estos regiones. Cada segmento es un lado de dos regiones.

El principal problema es transformar el "conjunto de segmentos de la teselación" en polígonos independientes .

Peter Krauss
fuente
Tal vez, con el nuevo módulo de topología postgis, el límite de la calle, podría agruparse para formar este polígono (área cerrada).
cavila
¿Cómo propondrías obtener el bloque? La calle es (conceptualmente) una cadena lineal, mientras que cada bloque es un polígono. ¿Cómo ubicaría un solo bloque urbano dada una cadena lineal, en presencia de servidumbres, parques, reservas naturales, bloques de hachas de batalla (por ejemplo, anewhouse.com.au/2012/07/battleaxe-block ), bloques donde hay un río / arroyo / cresta entre las calles, etc.?
BradHards
Gracias @Cavila, estaba buscando ejemplos, y encontré algunos como este , algo que necesito, pero: todos comienzan con polígonos, no con "segmentos de teselación" (vea mi generalización del problema). Mi entrada es un conjunto de segmentos.
Peter Krauss
@BradHards, gracias por su comentario (!), Lo edité para mostrar el enfoque de mi problema. Sí, hay muchas excepciones como un bloque de hacha de batalla; y sí, necesito agregar segmentos de río, segmentos de ferrocarril, etc. para una "teselación completa". Solo necesito la "primera aproximación" de los bloques, no una construcción completa y automatizada de ellos.
Peter Krauss
Supongo que está dispuesto a obtener el bloque o sector basado en el límite de la calle. Ni un solo lote urbano para una sola propiedad. Una solución podría ser volver a muestrear un andador que traza un símbolo en un punto de inicio y comienza a caminar girando hacia la derecha hasta que regresa al lugar de inicio donde trazó el símbolo. Entonces obtendrá un polígono o límite cerrado.
cavila

Respuestas:

7

El ST_Polygonizeagregado en PostGIS devolverá un que geometry_dumpcontiene todos los polígonos posibles formados por un conjunto de líneas. Supongo que las ID de bloque que se muestran en su ejemplo no están relacionadas con las ID del trabajo de línea de entrada. Si este es el caso, puede obtener sus polígonos e ID con:

SELECT (st_dump).path[1] as poly_id, (st_dump).geom FROM
    (SELECT ST_Dump(ST_Polygonize(geom)) FROM 
        (SELECT ST_Union(geom) as geom FROM lines) mergedlines) polys

La parte lenta aquí es la ST_Union. Parece que esto debería funcionar sin esa llamada, siempre que las líneas de entrada estén correctamente anudadas, pero no he tenido éxito al hacerlo.

Un búfer negativo no dará los resultados exactos que se muestran en su ejemplo, porque el proceso de poligonalización ignorará las calles sin salida. Pero puede tomar un búfer positivo del trabajo de línea original y usarlo ST_Differencepara eliminar esa área de los polígonos de bloque.

dbaston
fuente