¿Unirse a muchos polígonos pequeños para formar polígonos más grandes usando PostGIS?


47

Tengo la siguiente capa usando SRID 27700 en postgis:

ingrese la descripción de la imagen aquí

Es cada región administrativa en el Reino Unido y (como puede ver en la agrupación de colores) cada una de ellas tiene un campo de texto que especifica el condado en el que se encuentran.

Lo que me gustaría hacer es hacer polígonos de condado más grandes a partir de los más pequeños en un condado determinado, por lo que EG en la imagen sobre todos los polígonos de color verde azulado formaría un polígono grande del anillo exterior único que contiene todas las polis en ese color, como sabio todo púrpura, marrón, rosa, gris, etc., todos deben formar un polígono.

Ya he intentado lo siguiente:

insert into parishesmerged (geometry)
select astext(multi(ST_Union(the_geom))) as the_geom from parishes
group by county_name

Pero sigue generando geometrías rotas que luego tengo grandes problemas para procesar más.

Estoy tratando de hacer un mapa a nivel de condado más simple con las principales áreas de salida.

Cualquier solución no tiene que estar en Postgis tampoco, tengo la pila OS4Geo completa instalada, la última versión de QGis y más utilidades de las que puedo sacudir.

Las únicas cosas que no tengo son los grandes como ArcGis (aunque es posible que tenga un Old Mapinfo por ahí)


Para el registro, el conjunto de datos que estoy tratando de crear es acompañar un libro SIG que estoy escribiendo dirigido a programadores .NET que desean escribir aplicaciones SIG usando .NET


Después de probar las sugerencias a continuación, la que mejor funcionó fue la solución 'Paul Ramseys'.

Ahora tengo un buen archivo simplificado de condados y distritos que es lo suficientemente simple para mi libro, pero lo suficientemente complejo como para permitirme demostrar un interesante SQL geoespacial.

Aunque la solución de Paul finalmente fue la que funcionó para mí, también recurrí a otras respuestas para cosas como simplificar el mapa de polígonos y reducir aún más la complejidad.

Sin embargo, en lo que sí observé al hacer esto, aunque ST_Collect es más rápido que ST_Union, correr por correr también fue el principal responsable de las geometrías rotas. Supongo que el aumento de velocidad se obtiene a expensas de una menor precisión en la función central.


Este proceso se conoce como "disolver". No tengo experiencia con PostGIS, pero creo que puede usar el comando ST_Union para realizar la disolución.
dmahr

Hola dmahr, gracias por la aclaración, no estaba seguro de cómo se llamaba, sin embargo, si lees mi pregunta, verás que ya lo intenté :-)
shawty

Vaya, lo siento ... no vi eso. ¿Has probado la instrucción select sin la astext(multi())parte? Solo estoy saliendo de lo que veo en otros ejemplos de disolución de PostGIS.
dmahr

Todavía no, lo intentaré ahora. Tks ¿Tienes un enlace para disolver ejemplos?
Shawty

Edite para express si desea "el anillo exterior único" o no. (ver mi respuesta)
Peter Krauss

Respuestas:


43

ST_Union funcionaría, pero su línea de trabajo seguramente no está limpia. Entonces, los límites de tus pequeñas cositas no se agradan perfectamente. Puede encajarlos suavemente en una cuadrícula para intentar aumentar las probabilidades de que los vértices se alineen, pero apuesto a que todavía tendrá algunos casos que no funcionan. O estarán más allá de la tolerancia o, lo más probable, habrá lugares donde los vértices no estén emparejados, por lo que hay una línea en un lado y un vértice en el otro.

 CREATE TABLE merged AS
 SELECT ST_Union(ST_SnapToGrid(the_geom,0.0001)) 
 FROM parishes
 GROUP BY county_name;

Si tiene PostGIS 2.0, construir una estructura de topología con tolerancia podría llevarlo a la respuesta que está buscando, si tiene suerte.


¿Una buena pista para la corrección de geometrías, pero sobre "... un gran polígono del anillo exterior único que contiene todas las polis ..."?
Peter Krauss

No sabía sobre 'SnapTo', lo intentaré :-) Tks. Desafortunadamente, no, todavía no estoy usando PG 2, aunque la actualización está en camino.
Shawty

No estoy seguro de que su sintaxis sea correcta. Por postgis.net/docs/ST_Union.html , no hay firma que acepte un número en el segundo parámetro.
Aren Cambre

Tienes razón, el paréntesis estaba en el lugar equivocado. Editado
Paul Ramsey

¿hay un mysql equivalente a esto? Sigo recibiendo Incorrect parameter count in the call to native function 'ST_Union'y no sé si es una limitación de MySQL.
Jayen

7

Usted dice que necesita "... formar un polígono grande a partir del anillo exterior único que contiene todas las polis ...". El ST_ExteriorRing hace esto,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_Union(GEOM)))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

Puede usar ST_Union (), como se sugiere, o probar con ST_Collection ().


NOTAS: para evitar pequeños bucles o "geometrías rotas", puede usar st_convexhull y / o ST_Simplify para cada geom,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_union(ST_Simplify(GEOM,0.5))))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

y verifica tus geometrías,

SELECT * FROM (
   SELECT gid, ST_IsValid(geom) as valid, ST_IsSimple(geom) as simple 
   FROM GEOMTABLE) AS t  
WHERE NOT(valid AND simple); 

Perdón por la confusión: lo que quise decir con mi descripción fue un polígono más grande creado a partir de los más pequeños, me doy cuenta de que, según el contexto, 'Anillo externo' puede significar cosas diferentes para diferentes personas, mi intención era describir un solo polígono creado a partir de límite presente alrededor de cada grupo de polígonos.
Shawty

7

La función ST_Collect es una función "agregada" en la terminología de PostgreSQL

" SELECT ST_Collect(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN" devolverá una GEOMETRYCOLLECTION por separado para cada valor distinto de ATTRCOLUM

http://postgis.net/docs/ST_Collect.html

Nota: ST_Collect es mucho más rápido que ST_Union


3
Lo intenté y obtuve resultados ligeramente diferentes, sin embargo, ¿es una colección de geometría lo que necesito? Básicamente, estoy tratando de hacer un gran polígono, opcionalmente con agujeros (específicamente en Derbyshire y Nottinghamshire, donde tanto Derby como Nottingham forman distritos separados justo en el centro. Sin embargo, observé la diferencia de velocidad, así que eso es muy difícil.
Shawty

2

Supongo por su pregunta que está utilizando el producto Boundary-Line de Ordnance Survey. Si ese es el caso, entonces ya incluye un conjunto de datos a nivel del Condado, por lo que no hay necesidad de intentar generarlo usted mismo desde las áreas parroquiales de nivel inferior.

Si no está utilizando Boundary-Line, le recomiendo que lo haga, ya que es gratuito bajo la licencia OS OpenData y tiene un nivel de Condado como un archivo de forma que puede cargar directamente en PostGIS.


2
¿Qué hay de proporcionar un enlace para aquellos que no lo saben? Gracias.
jonatr

1
Hola CHEnderson, de hecho tienes razón, sí, estoy usando el conjunto de datos de la capa límite de OS Opendata, desafortunadamente los límites del condado no están completos, el archivo de forma del condado real solo incluye aquellos que se nombran como condados, los distritos de Londres contienen las áreas alrededor Londres y otros archivos tienen algunas partes, algunos niveles más bajos y más pequeños que los otros. El único archivo que tiene todo el bosquejo del Reino Unido y, posteriormente, cualquier posibilidad de extraer todos los condados de nivel superior y los límites municipales en una capa es la capa de las parroquias, por lo tanto, estoy intentando hacerlo.
Shawty

Para aquellos que estén interesados se pueden descargar los límites del condado y más, aquí: ordnancesurvey.co.uk/oswebsite/products/os-opendata.html
Shawty
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.