Crear polígono a partir de líneas en PostGIS

13

Estoy tratando de dividir un polígono en polígonos más pequeños de una línea, pero creo que no puedo usar la función st_split. Lo que necesito es crear polígonos pequeños dentro de uno grande, usando una cuadrícula de cadena lineal.

He intentado algunas formas, pero no puedo obtener el resultado. Lo que he intentado:

Divida un polígono de un LineString usando st_split ()

De un polígono límite.

ingrese la descripción de la imagen aquí

Y tabla de cadenas de líneas:

ingrese la descripción de la imagen aquí

Necesitaría los siguientes polígonos:

ingrese la descripción de la imagen aquí

Problema : no puedo dividir un polígono de varias líneas, ni un polígono de una multilínea.

El otro método que estoy intentando es crear un polígono a partir de las líneas con st_polygonize (). El SQL que estaba intentando es:

SELECT 
   g.path[1] as gid, 
   g.geom::geometry(polygon, 22033) as geom 
FROM
   (SELECT 
     (ST_Dump(ST_Polygonize(geom))).* 
   FROM linestable
) as g;

Extraído de Crear polígonos a partir de segmentos de línea usando PostgreSQL y PostGIS

Problema : solo puedo obtener un polígono (el límite).

¿Alguien puede decirme cuál sería la mejor manera de obtener los polígonos de la cadena lineal, o si me falta algo?

Nota: Las tablas están en el mismo SRID y las geometrías se ajustan en una cuadrícula. En QGIS puedo ejecutar el proceso de poligonalización de líneas a polígono perfectamente.

Como exige John, aquí está la tabla de cadenas lineales. https://drive.google.com/file/d/0B603y_m735jfS014S0EyVnpMUEU/view?usp=sharing

Pablo Pardo
fuente
1
¿Puedes publicar las geometrías de cadenas lineales en alguna parte? ST_Polygonize junto con ST_Dump debería funcionar.
John Powell
Seguro. He editado la publicación con el enlace a la tabla.
Pablo Pardo
@ JohnPowellakaBarça, ¿puedes mirar esto? Esta pregunta es genial. ST_Polygonize en su conjunto de muestra devuelve un solo polígono. ¿Esencialmente necesitamos descomponer su desorden de LINESTRINGS abiertos y encontrar todos los que puedan hacer rectángulos?
Evan Carroll
1
@EvanCarroll. Seguro. Estoy locamente ocupado en un cajero automático, así que probablemente no por unos días.
John Powell
1
@ppardoz. Espero que esto te ayude. Me di cuenta de que las definiciones de su mesa estaban todas en español :-)
John Powell

Respuestas:

4

Conseguí que esto funcionara usando ST_Node primero, junto con ST_Collect , para convertir las líneas en un conjunto de cadenas de líneas nodas dentro de una MultiLinestring .

Como dice en los documentos para ST_Node :

Noda completamente un conjunto de cadenas de líneas usando el menor número posible de nodos mientras conserva todos los de entrada.

Lo que esto significa es que todas las cadenas lineales se combinan en todas las combinaciones posibles, para formar el equivalente al anillo exterior de un polígono. Mientras que, si intenta ST_Polygonize un conjunto de LineStrings, ninguno de los cuales por sí solo describe un polígono, simplemente recupera LineStrings. Entonces, esto funciona:

WITH multi(geom) AS (
  SELECT ST_Node(ST_Collect(geom))
  FROM leyenda_digitalizar00
)
SELECT ST_AsText( (ST_Dump(ST_Polygonize(geom))).geom )
FROM multi;

Si solo ejecuta la primera parte de esto, es decir, el CTE multi, la salida se ve así:

MULTILINESTRING ((204.5 69.9000000000004,204.5 69.9000000000004), (204.5 68.9,205.4 68.9), (204.5 68.9,204.5 69,204.5 69.1,204.5 69.2,204.5 69.3,204.5 69.4,204.5 69.5,204.5 69.6,204.5 69.7,204.5 69.8,204.5 69.6,204.5 69.7,204.5 69.8,204.5 204.5 69.9000000000004), (209.5 68.9,209.5 68.8,209.5 68.7,209.5 68.6,209.5 68.5,209.5 68.4,209.5 68.3,209.5 68.2,209.5 68.1,209.5 68,209.5 67.9,209.5 67.8,209.5 67.7,209.5 67.6,209.5 67.5,209.5 67.4 , 209.5 .......

Ahora, cuando alimente esta MultiLinestring a ST_Polygonize , funciona como se espera, por ejemplo,

POLÍGONO ((205.4 68.9,204.5 68.9,204.5 69,204.5 69.1,204.5 69.2,204.5 69.3,204.5 69.4,204.5 69.5,204.5 69.6,204.5 69.7,204.5 69.8,204.5 69.9,204.5 69.9000000000004,205.4 69.9,205.4 69.3,205.4 68.9))

POLÍGONO ((204.5 69.9000000000004,204.5 70,204.5 70.1,204.5 70.2,204.5 70.3,204.5 70.4,206.8 70.4,209.5 70.4,209.5 70.3,209.5 70.2,209.5 70.1,209.5 70,209.5 69.9,205.4 69.9,204.5 69.9000000000004))

POLÍGONO ((206.8 70.4,204.5 70.4,204.5 70.5,204.5 70.6,204.5 70.7,204.5 70.8,204.5 70.9,204.5 71,204.5 71.1,204.5 71.2,204.5 71.3,204.5 71.4,206.8 71.4,206.8 70.4))

Obviamente, el ST_AsText es solo para ilustración, y tendrá que ajustar, si también desea la ID de ruta.

La conclusión clave es que ST_Polygonize espera cadenas de líneas que ya describen el contorno de un polígono , que es lo que ST_Node (ST_Collect (.... hace en lo anterior.

John Powell
fuente
Eso es realmente genial, ¡puedo confirmar que esta solución funciona! Por otro lado, me pregunto por qué ST_Polygonize()dice que se necesitan cadenas de línea, o cuál es el caso de uso para eso sin llamar ST_Node()primero
Evan Carroll
1
@EvanCarroll. Creo que la respuesta es que ST_Polygonize toma las cadenas de líneas que ya están en un conjunto que representa un polígono, mientras que las cadenas de líneas en esta pregunta formaron múltiples polígonos posibles. Tengo entendido que esto es lo que hace ST_Node. Intentaré investigar más y actualizar la respuesta.
John Powell