Ayuda con la geometría del polígono PostGIS - anillos no cerrados

10

Recogí una copia del libro súper malvado 'Python Geospatial Development' de Erik Westra ( enlace de Amazon ), y estoy trabajando en ello. Actualmente, me está enseñando a cargar datos de la costa de GSHHS desde un shapefile a una base de datos PostGIS, en preparación para construir una aplicación web geoespacial.

Mi problema es este: cuando intento importar los datos de GSHHS en PostGIS, se rechaza debido a que los polígonos de la línea costera no se consideran "válidos". Específicamente, recibo un mensaje de error que describe algunos (pero no todos) de los polígonos de la costa como 'anillos no cerrados'.

Entiendo que este error está tratando de decirme que el primer y el último punto del polígono no son iguales. Sin embargo, esto simplemente no es cierto. He examinado la representación WKT de muchos de los polígonos, y son correctos. Ellos definitivamente comienzan y terminan con la misma coordenada.

Los polígonos se extraen de los archivos de forma utilizando la biblioteca OGR y exportando cada entidad poligonal a WKT. Intenté reconstituir el polígono a través de Shapely y experimenté con WKB, pero fue en vano. Yo he sido capaz de cargar los mismos datos en PostGIS como una tabla MULTIPOLYGON, usando el cargador shp2pgsql.

Me preguntaba si alguien por ahí:
(a) tal vez usó el mismo libro, se quedó atascado en el mismo problema y tiene la respuesta para mí.
(b) ha encontrado un problema similar y ha encontrado una solución?
(c) en su defecto, ¿tiene algún consejo de 'mejores prácticas' para garantizar una geometría válida antes de cargar en PostGIS?

ACTUALIZACIÓN: un colega ha sugerido que el problema de los "anillos no cerrados" puede ser solo un síntoma de otro problema. Es posible que mi configuración PostGIS / PostgreSQL tenga límites de tamaño (en transacciones de inserción, paquetes recibidos, cadenas de texto, etc.).

Como estoy usando polígonos WKT muy largos como entrada, PostGIS puede estar cortándolos demasiado pronto para permitir que se complete cada polígono. Lo probaré mañana, pero suena probable. Mi inserción de las fronteras del país solo aceptaba algunos registros y no otros. De memoria, las geometrías aceptadas eran para pequeñas naciones isleñas como Antigua (y probablemente tenían representaciones cortas de WKT).

Entonces, esto podría terminar siendo más un hilo de administración de la base de datos PostGIS, en lugar de un hilo de geometría no válido.

timmy
fuente
¿Puedes proporcionar un archivo shp de muestra?
Mario Miler
sin worries.The GSHHS costas de datos que estoy usando es una descarga de 96 MB de aquí . Los datos de la frontera mundial que estoy usando es el conjunto de datos de fronteras mundiales de thematicmapping.org
timmy

Respuestas:

6

He visto sus datos y el ejemplo del libro, el problema es que hay tres polígonos no válidos en los datos que se procesan en el libro:

GSHHS_l_L1.shp

ID = 92-W

POLYGON ((-180.0 71.514793999999995,-179.69008299999999 71.577888999999999,-178.648889 71.577416999999997,-178.40644399999999 71.549916999999994,-177.406306 71.244167000000004,-177.877444 71.022889000000006,-179.500111 70.863749999999996,-179.93011100000001 70.979583000000005,-180.0 70.962072000000006))

ID = 486-W

POLYGON ((-180.0 -16.799126,-179.84419399999999 -16.691278,-179.80041700000001 -16.789193999999998,-179.850472 -16.878361000000002,-180.0 -16.959561))

GSHHS_l_L2.shp

ID = 7333-W

POLYGON ((-180.0 65.393473,-179.76583299999999 65.428332999999995,-179.95416700000001 65.385555999999994,-179.90972199999999 65.316389,-180.0 65.321635))

Debido a que este es un ejemplo, sería más fácil eliminar esos polígonos del conjunto de datos o simplemente agregar uno si la declaración en su código

if geometry.IsValid():
       cursor.execute("INSERT INTO gshhs (level, geom) VALUES (%s, ST_GeomFromText(%s, 4326))", (level, wkt))
Mario Miler
fuente
Gracias Mario, parece que me estaba adelantando, en lugar de validar correctamente TODOS mis polígonos de entrada. Su respuesta fue correcta: estos polígonos aparecieron como no válidos cuando se probaron con OGR. Curiosamente, se veían bien en QGis, pero ArcMap mostró que carecían de un anillo completo. Estos tres polígonos cayeron en la línea de fecha, y supongo que la geometría del archivo de forma no contó el borde del polígono a lo largo de la línea de fecha. Su solución es una manera agradable y fácil de detectar polígonos no válidos. Marcaré la publicación como respondida.
timmy
Si se siente caritativo, ¿tiene alguna buena solución para el siguiente paso en el proceso, que es corregir los polígonos no válidos? Intenté usar la función .CloseRing () de OGR, pero fue en vano. Simplemente ignoró la llamada a la función, creo.
timmy
Traté de usar el "truco del búfer" ( talleres.opengeo.org/postgis-intro/validity.html ) con forma y ogr pero sin éxito. Shapely no leerá un polígono inválido y ogr no hará la operación del búfer, actualmente no sé por qué. Si me tropiezo con la respuesta, te lo haré saber. Quizás alguien más tenga más éxito con este problema. Lo siento.
Mario Miler
Creo que tengo la validación de mi polígono funcionando ahora. Creo que estaba usando la función .CloseRings () de OGR de manera incorrecta. Me llamaron como un método del polígono (es decir, poly.CloseRings ()). En cambio, tuve que extraer el Anillo Lineal del polígono y luego ejecutarlo en eso (es decir, lr = poly.GetGeometryRef (0); lr.CloseRings ()). Los resultados se están insertando con éxito en PostGIS, y puedo usar los 3 polígonos problemáticos en QGis sin preocupaciones. Solo hay un poco de un costo computacional en la verificación de la validez de CADA polígono.
timmy