Importar um shapefile para o postgis com o ogr2ogr fornece: Não é possível abrir a fonte de dados

12

Eu quero usar ogr2ogr para importar um shapefile em um banco de dados postgis. Instalei com êxito o ogr2ogr e executo no pgsql o seguinte comando:

ogr2ogr -f "PostgreSQL" PG:"host=localhost user=user_1 password=***** dbname=imports" world_boundaries.shp

O que eu recebo de volta é uma mensagem de erro:

Unable to open datasource `world_boundaries.shp' with the following drivers: --a list of drivers follows (ESRI Shape File etc.)

Também tentei definir o caminho completo do shapefile, mas recebi a mesma mensagem.

Também tentei executar o:

ogrinfo world_boundaries.shp

Mesma coisa.


Depois de corrigir os problemas com as permissões do arquivo, recebo o seguinte erro:

  ERROR 1: AddGeometryColumn failed for layer world_boundaries, layer creation has failed.
  ERROR 1: Terminating translation prematurely after failed
  translation of layer world_boundaries (use -skipfailures to skip errors)

Eu também tentei importá-lo através da GUI shp2pgsql e recebo o seguinte erro:

ALTER TABLE "public".""
Failed in pgui_exec(): ERROR:  permission denied for relation spatial_ref_sys
 CONTEXT:  SQL statement "SELECT SRID         FROM spatial_ref_sys WHERE SRID = new_srid"
PL/pgSQL function addgeometrycolumn(character varying,character   varying,character varying,character varying,integer,character varying,integer,boolean) line 50 at SQL statement
 SQL statement "SELECT AddGeometryColumn('',$1,$2,$3,$4,$5,$6,$7)"
 PL/pgSQL function addgeometrycolumn(character varying,character  varying,character varying,integer,character varying,integer,boolean) line 5 at     SQL statement

Shapefile import failed.

O problema desta vez foi que esse usuário do banco de dados não tinha permissões suficientes. Isso corrigiu:

GRANT ALL ON TABLE spatial_ref_sys TO my_user_name;

A próxima mensagem de erro é:

  Warning 1: Geometry to be inserted is of type 3D Multi Polygon, whereas the layer geometry type is 3D Polygon.
 Insertion is likely to fail
 ERROR 1: INSERT command for new feature failed.
 ERROR:  Geometry type (MultiPolygon) does not match column type (Polygon)

Parece que preciso usar o parâmetro: -nlt MULTIPOLYGON Mas quando faço isso, recebo outro erro, o que não faz sentido para mim:

ERROR 1: PostgreSQL driver doesn't currently support database creation.
Please create database with the `createdb' command.
PostgreSQL driver failed to create PG:host=localhost user=my_user_name dbname=my_database password=password -nlt POLYGON

Mas ele é carregado usando a GUI shp2pgsql.


O comentário de @elrobis permitiu que isso finalmente funcionasse. Dados carregados em db corretamente!

ogr2ogr -f "PostgreSQL" PG:"host=localhost user=geonode dbname=geonode_imports password=geonode" -nlt GEOMETRY wld_bnd_adm0_gaul_2015.shp
user1919
fonte
Parece que seu shapefile não é válido. Funciona em outro software?
Evil Genius
1
Sim. É carregado corretamente no QGIS.
User1919
1
Além disso, supondo que seu banco de dados já exista e que esteja escrito corretamente em sua instrução ogr2ogr, e que o usuário do postgres no comando tenha o complemento completo dos privilégios necessários (SELECT, INSERT, UPDATE, CREATE ... etc), tente adicionar o -nln layernameargumento, talvez junto -overwritepara ver se ganha vida. Além disso, se eu fosse você, executaria o ogr2ogr sudojunto com meu superusuário do postgres, apenas para ter uma super super certeza de descartar permissões e privilégios. Quando o script estiver sólido, você poderá conferir as permissões e privilégios desagradáveis. :)
elrobis
3
Obrigado. Adicionando -nlt GEOMETRIA em vez de -nlt POLYGON fez o truque.
User1919
1
Ainda bem que funcionou. Vou seguir em frente e dar uma resposta adequada em uma resposta que também descreve por que acho que funcionou.
27416 elrobis

Respostas:

17

Como você descobriu por tentativa e erro, havia alguns problemas persistentes que você precisava corrigir, o último dos quais foi resolvido usando o argumento -nlt GEOMETRY* do ogr2ogr .

* Observe a recomendação no comentário de @ LeeHachadoorian que deve -nlt PROMOTE_TO_MULTIser usada como uma solução padrão, e não nlt GEOMETRYcomo a primeira promove melhores práticas, além de benefícios auxiliares.

Permissões de usuário e mensagens de erro

Primeiro, o ogr2ogr não pôde abrir o seu shapefile e você percebeu que os problemas de permissões estavam afetando o usuário do sistema operacional que acessava o shapefile. Mas há uma lição importante aqui para outros, especificamente, a mensagem de erro do ogr2ogr neste ponto foi enganosa! De fato, um dos primeiros comentaristas achou que o seu shapefile era inválido e, admito, meu primeiro palpite foi que provavelmente havia um erro / erro de digitação no caminho / nome do arquivo ou que poderia haver um caracter não convencional no caminho do arquivo - como um espaço - isso estava quebrando a capacidade do ogr2ogr de apontar para o shapefile. Como você descobriu, na verdade era apenas um problema com as permissões do usuário. Como a mensagem de erro cria um arenque vermelho, essa é uma possibilidade que os outros precisam manter em mente. :)

Privilégios de usuário SQL e falhas de mistério

Eu ficaria surpreso com o seu segundo erro por um tempo, mas testando seu usuário do SQL com um utilitário de importação diferente (shp2pgsql), que era inteligente, você recebeu uma mensagem de erro mais precisa e deu ao usuário do SQL privilégios necessários na spatial_ref_systabela. Portanto, alguém com dificuldade em fazer com que sua instrução de importação ogr2ogr funcione corretamente deve garantir que seu usuário SQL tenha privilégios suficientes no próprio banco de dados e na tabela 'spatial_ref_sys'.

Tipos de geometria mista e práticas recomendadas

O último obstáculo que você encontrou parece estar relacionado ao fato de que os shapefiles permitem que geometrias únicas e multipartes coexistam no mesmo conjunto de dados / arquivo. É uma prática recomendada misturar tipos de geometria na mesma tabela, mesmo para peças únicas / multipartes do mesmo tipo de recurso e, por padrão, os players de código aberto em sua cadeia de ferramentas tentarão protegê-lo da mistura de tipos de geometria. Felizmente, eles oferecem algumas opções. Inicialmente, eu recomendei definir o argumento -nlt GEOMETRY* em sua instrução ogr2ogr, o que permitiu importar seu conjunto de dados de polígonos, apesar da convenção mais flexível da ESRI. Esteja ciente, no entanto, isso significa que você provavelmente tem geometrias de peça única e peça múltipla em sua tabela e isso pode criar outras dores de cabeça para os seus posteriores!

Vale ressaltar que o ogr2ogr tem outra -nltopção que você deve considerar, a saber PROMOTE_TO_MULTI. Para citar a documentação ..

A partir do GDAL 1.10, o PROMOTE_TO_MULTI pode ser usado para promover automaticamente camadas que misturam polígonos ou multipolígonos em multipolígonos e camadas que misturam cadeias de linhas ou cadeias de linhas múltiplas a cadeias múltiplas. Pode ser útil ao converter arquivos de forma para PostGIS e outros drivers de destino que implementam verificações estritas de tipos de geometria.

Em outras palavras, se você usar o PROMOTE_TO_MULTIsinalizador, TODOS os seus recursos serão convertidos em recursos com várias partes, mesmo quando eles consistirem em uma única peça. Conforme observado por @LeeHachadoorian nos comentários - e tenho certeza que a maioria concordaria -, é aconselhável que você prefira PROMOTE_TO_MULTIo GEOMETRYsinalizador mais fraco, pois ele está em conformidade com as melhores práticas, unificando as geometrias de recursos em sua tabela. Basicamente, qualquer código que você escreve deve esperar apenas geometrias de várias partes. É certo que isso pode ser mais limpo e simplificar parte do desenvolvimento.

Conselho genérico para alguém com problemas de importação de SHP para POST

  1. Verifique se os caminhos não possuem caracteres descolados e se não há erros de digitação ou erros de ortografia no caminho ou no nome do arquivo
  2. Como o @ user1919 descobriu, verifique se o usuário do SO possui privilégios suficientes para acessar o shapefile! Como demonstraram, pode ajudar a tentar abrir o shapefile em outro software, como o QGIS - se funcionar em um software, não estará corrompido e deverá funcionar em outro software.

Primeiro, considere executar o comando ogr2ogr sudopara descartar problemas de permissão até depois de ter certeza de que seu script está funcionando conforme o esperado .

  1. Além disso, como @ user1919 percebeu, verifique se o usuário do SQL possui privilégios suficientes no banco de dados segmentado pelo seu script e na spatial_ref_systabela.

Novamente, primeiro, considere usar o superusuário PostGRESql aqui para descartar problemas de privilégio SQL até que seu script esteja funcionando. Se o seu script funcionar com o superusuário e falhar com um usuário de automação preferido, você saberá que o problema está relacionado ao usuário do SQL e não aos seus dados ou ao seu ambiente (instalação gdal / ogr, etc.)

  1. Tente definir o -nltsinalizador como PROMOTE_TO_MULTIou GEOMETRY. Como os shapefiles permitem uma convenção de tipo de recurso mais flexível, às vezes você precisa instruir seus utilitários de código aberto a serem mais flexíveis :)

  2. Se você está importando para PostgreSQL ou MySQL, tente definir -lco PRECISION=no..fair aviso, eu não exatamente entender o que esse argumento faz, mas aqui está o que eu experimentei .. Como você sabe, shapefiles muitas vezes incluem as SHAPE_LENGTHe SHAPE_AREAcampos, e eu notei algumas vezes quando estou enfrentando falhas misteriosas; se eu excluir esses campos, os dados podem ser importados corretamente. No entanto, se eu usar -lco PRECISION=no, posso obter os dados para importar sem precisar excluir esses campos. Minha recomendação é usar esse parâmetro como uma etapa de solução de problemas, mas para entender qual problema ele está realmente resolvendo antes de aceitar a importação em uma solução de produção.

  3. Finalmente, se você estiver usando o MySQL, lembre-se de que algumas geometrias de recursos muito grandes podem ofender o max_allowed_packetparâmetro do MySQL . Você pode ler mais sobre isso na documentação do driver MySQL. Mas a solução é alterar sua configuração do MySQL para permitir um valor maior que o padrão.

Exemplo de comando SHP para importação PostGIS para ogr2ogr

Para qualquer iniciante que possa passear por aqui, é assim que a maioria das minhas importações de SHP to Post se parece usando ogr2ogr. Observe que envolvo os caminhos / nomes dos arquivos entre aspas, protegendo contra espaços, caracteres estranhos e quebra de linha no terminal. Também incluí a maioria dos argumentos discutidos acima, além de substituições no campo nome da geometria, o Campo FID e o nome da camada:

ogr2ogr -f "PostgreSQL" "PG:host=127.0.0.1 user=myuser dbname=mydb password=mypassw0rd" "C:/path/to/some_shapefile.shp" -lco GEOMETRY_NAME=the_geom -lco FID=gid -lco PRECISION=no -nlt PROMOTE_TO_MULTI -nln new_layername -overwrite

elrobis
fonte
3
Em relação a -nlt PROMOTE_TO_MULTI, essa é realmente uma prática recomendada para geometrias de polígonos. Sugiro alterar sua resposta para aconselhá-la como uma forte opção padrão, apenas para ser violada após uma cuidadosa consideração. Eu também desaconselho fortemente o uso do geometrytipo genérico para lidar com polígonos / multipolígonos mistos, a menos que o usuário / desenvolvedor realmente saiba o que está fazendo e precise misturar tipos de polígonos, linhas e pontos.
Lee Hachadoorian
1
@LeeHachadoorian, concordou. Eu editei a resposta conforme recomendado. Em minha defesa, PROMOTE_TO_MULTIé novo o suficiente (GDAL 1.10) que eu ainda uso a solução original que estava disponível quando comecei tudo isso. :) ... com toda a justiça, no entanto, um shapefile só combina tipos únicos e multipartes, portanto nunca haveria um cenário em que o ogr2ogr pressionasse um shp -nlt GEOMETRYe construísse uma tabela com pontos, linhas e polys :))))) No entanto, concordo plenamente com a sua posição sobre o assunto.
Elrobis 27/05
1
Os arquivos de forma permitem vários polígonos em seu tipo de polígono. Eles nem têm o tipo MultiPolygon. Portanto, mesmo ao encontrar esse tipo de arquivo de forma, é preciso usar -nlt PROMOTE_TO_MULTIpara fazer esse trabalho.
CMCDragonkai