Ajuda com geometria de polígono PostGIS - anéis não fechados

10

Peguei uma cópia do livro super-perverso 'Python Geospatial Development' de Erik Westra ( link da Amazon ), e estou trabalhando nisso. Atualmente, ele está me ensinando a carregar dados da costa GSHHS de um arquivo de forma em um banco de dados PostGIS, em preparação para a construção de um aplicativo da web geoespacial.

Meu problema é o seguinte: quando tento importar os dados GSHHS para o PostGIS, eles são rejeitados porque os polígonos da costa não são considerados 'válidos'. Especificamente, recebi uma mensagem de erro que descreveu alguns (mas não todos) dos polígonos da costa como sendo 'anéis não fechados'.

Entendo que esse erro está tentando me dizer que o primeiro e o último ponto do polígono não são os mesmos. No entanto, isso simplesmente não é verdade. Examinei a representação WKT de muitos polígonos e eles estão corretos. Eles definitivamente começam e terminam com o mesmo co-ordenada.

Os polígonos são extraídos dos shapefiles usando a biblioteca OGR e exportando cada recurso de polígono para o WKT. Tentei reconstituir o polígono via Shapely e experimentei o WKB, mas sem sucesso. Eu ter sido capaz de carregar os mesmos dados em PostGIS como uma tabela MULTIPOLYGON, usando o carregador shp2pgsql.

Fiquei me perguntando se alguém lá fora tinha:
(a) talvez tenha usado o mesmo livro, ficou preso no mesmo problema e tem a resposta para mim?
(b) encontrou um problema semelhante e encontrou uma solução?
(c) na falta disso, tem algum conselho de "melhores práticas" para garantir geometria válida antes de carregar no PostGIS?

ATUALIZAÇÃO: um colega sugeriu que o problema dos 'anéis não fechados' pode ser apenas um sintoma de outro problema. É possível que minha configuração do PostGIS / PostgreSQL tenha limites de tamanho (em transações de inserção, pacotes recebidos, seqüências de texto, etc.).

Como estou usando polígonos WKT muito longos como entrada, o PostGIS pode cortá-los muito cedo para permitir que cada polígono seja concluído. Vou testá-lo amanhã, mas parece provável. Minha inserção das fronteiras do país estava apenas aceitando alguns registros e não outros. De memória, as geometrias aceitas eram para pequenas nações insulares como Antígua (e provavelmente tinham representações curtas do WKT).

Portanto, isso pode acabar sendo mais um encadeamento de administrador de banco de dados PostGIS, em vez de um encadeamento de geometria inválido.

timmy
fonte
você pode fornecer um arquivo shp de amostra?
Mario Miler
Os dados da linha de costa GSHHS que estou usando são um download de 96mb a partir daqui . Os dados fronteira mundo que eu estou usando é a Borders Dataset Mundial de thematicmapping.org
Timmy

Respostas:

6

Analisei seus dados e o exemplo do livro. O problema é que existem três polígonos inválidos nos dados processados ​​no livro:

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))

Como este é um exemplo, seria mais fácil excluir esses polígonos do conjunto de dados ou apenas adicionar uma instrução if no código

if geometry.IsValid():
       cursor.execute("INSERT INTO gshhs (level, geom) VALUES (%s, ST_GeomFromText(%s, 4326))", (level, wkt))
Mario Miler
fonte
Obrigado Mario, parece que eu estava me adiantando muito, em vez de validar corretamente TODOS os meus polígonos de entrada. Sua resposta estava correta - esses polígonos se mostraram inválidos quando testados com OGR. Curiosamente, o QGis parecia bem, mas o ArcMap os mostrava sem um anel completo. Todos esses três polígonos caíram na linha de dados, e acho que a geometria do shapefile não contou a borda do polígono ao longo da linha de dados. Sua solução é uma maneira fácil e agradável de detectar polígonos inválidos. Vou marcar a postagem como respondida.
Timmy
Se você se sente caridoso, tem boas soluções para a próxima etapa do processo, que é a correção de polígonos inválidos? Tentei usar a função .CloseRing () do OGR, mas sem sucesso. Simplesmente ignorou a chamada de função, eu acho.
Timmy
Tentei usar o "truque de buffer" ( workshops.opengeo.org/postgis-intro/validity.html ) com formas e ogr, mas sem sucesso. Shapely não lê polígono inválido e ogr não faz operação de buffer, atualmente não sei por quê. Se eu tropeçar na resposta, eu o informarei. Talvez alguém tenha mais sucesso com esse problema. Desculpa.
Mario Miler
Acho que tenho minha validação de polígono funcionando agora. Eu acho que estava usando a função .CloseRings () do OGR da maneira errada. Eu fui chamado como um método do polígono (isto é, poly.CloseRings ()). Em vez disso, tive que extrair o anel linear do polígono e depois executá-lo (por exemplo, lr = poly.GetGeometryRef (0); lr.CloseRings ()). Os resultados estão sendo inseridos com êxito no PostGIS, e eu posso usar os três polígonos problemáticos no QGis, sem preocupações. Existe apenas um custo computacional na verificação da validade de TODOS OS polígonos.
Timmy