Shapefile PRJ para a tabela de pesquisa PostGIS SRID?

38

Eu queria saber se existe algo como um shapefile PRJ para a tabela de pesquisa PostGIS SRID? Algo que pode traduzir as definições mais comuns de PRJ do shapefile no provável SRID.

Ao usar o PostGIS e o pgAdminIII, se você usar o postgisgui para importar seus arquivos de forma, o SRID será deixado como "-1". Parece que a ferramenta deve ser capaz de analisar o Esri PRJ e determinar as corretas (ou pelo menos algumas opções) que são o provável SRID, em vez de apenas deixar o padrão.

Ou o importador tem a capacidade de reprojetar em tempo real se você escolher outro SRID?

Pode parecer preguiçoso da minha parte, mas para mim parece curioso que essa função ainda não tenha sido implementada. Alguém sabe se esse conceito está em andamento, ou por uma boa razão pela qual ele foi deixado de fora?

RyanDalton
fonte

Respostas:

9

Tomando emprestada a idéia do @iant, aqui está um módulo PL / Python3 que procurará os códigos inteiros EPSG SRID de um arquivo PRJ usando o serviço da web http://prj2epsg.org .

Primeiro, instale o PL / Python3:

CREATE LANGUAGE plpython3u;

Agora, adicione a função SQL, que possui código escrito para Python 3:

CREATE OR REPLACE FUNCTION prj2epsg(prj_file text) RETURNS integer AS
$BODY$

import json
from urllib.parse import urlencode
from urllib.request import urlopen

with open(prj_file, 'r') as fp:
    prj_txt = fp.read()

query = urlencode({
    'exact': True,
    'error': True,
    'mode': 'wkt',
    'terms': prj_txt})

webres = urlopen('http://prj2epsg.org/search.json', query.encode())
jres = json.loads(webres.read().decode())

return int(jres['codes'][0]['code'])

$BODY$ LANGUAGE plpython3u VOLATILE COST 100;

Para usá-lo no PostgreSQL:

SELECT prj2epsg(E'C:\\Temp\\countries.prj');

retorna 4326 para o meu teste Shapefile.

Mike T
fonte
Vou marcar isso como a solução. Enquanto os outros são excelentes, adoro essa idéia. Agora, se conseguirmos que alguém com a capacidade de codificação inclua esse tipo de funcionalidade no carregador de shapefile do pgAdmin PostGIS, para que ele determine automaticamente o SRID correto ao ler o SHP. Vou manter meus dedos cruzados.
RyanDalton
1
A ressalva, é claro, é que ela requer uma conexão com a Internet e depende de um serviço da Web externo que precise ser instalado e funcionando.
Mike T
57

O GDAL tem uma interface conveniente e agradável para a biblioteca do PROJ4.

Se você tem confiança no Python, usando as ligações GDAL Python, se importar as classes osr, terá métodos muito convenientes para ler e exportar representações de projeção para vários formatos, como PROJ4, WKT, Esri .PRJ.

Por exemplo, este script converterá o arquivo .PRJ do seu shapefile em WKT e PROJ4 (o último é usado no PostGIS):

#! /usr/bin/env python

import sys
from osgeo import osr

def esriprj2standards(shapeprj_path):
   prj_file = open(shapeprj_path, 'r')
   prj_txt = prj_file.read()
   srs = osr.SpatialReference()
   srs.ImportFromESRI([prj_txt])
   print 'Shape prj is: %s' % prj_txt
   print 'WKT is: %s' % srs.ExportToWkt()
   print 'Proj4 is: %s' % srs.ExportToProj4()
   srs.AutoIdentifyEPSG()
   print 'EPSG is: %s' % srs.GetAuthorityCode(None)

esriprj2standards(sys.argv[1])

Execute isso na linha de comando:

$ python esriprj2standards.py /home/pcorti/data/shapefile/country.prj 
Shape prj is: GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
WKT is: GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
Proj4 is: +proj=longlat +datum=WGS84 +no_defs 
EPSG is: 4326
capooti
fonte
Eu deparei com duas questões dessa abordagem: (1) +proj=longlat +datum=WGS84 +no_defsnão está na spatial_ref_systabela, então você não pode usar a saída para procurar o SRID; e (2) Eu não consigo encontrar qualquer propriedade SRID ou método (há um prático ImportFromEPSG(SRID)método, mas não o contrário)
Mike T
4
Eu atualizei o script com uma chamada para o método AutoIdentifyEPSG () que vai fazer a mágica;)
capooti
Muito legal. Excelente trabalho!
precisa saber é o seguinte
Quando gdalsrsinfoe ogrinfofalhar, este é o caminho a seguir!
precisa saber é o seguinte
Observe que srs.GetAuthorityCode(None)ainda pode retornar nenhum se nenhum SRID próximo tiver sido identificado.
Astrojuanlu
19

Já faz um tempo desde que eu usei POSTGIS srids, mas se eles são apenas códigos EPSG, você pode usar http://prj2epsg.org/search para procurá-los em arquivos ESRI.prj (quebrados).

Ian Turton
fonte
Este é um site realmente inteligente. Observando a API , você pode escrever um bom script do lado do servidor para automatizar o procedimento.
Mike T
4

Como uma mistura de soluções, criei um script para me ajudar a carregar shapefiles arbitrários no postgis. Ele também tenta detectar a codificação do DBF.

from chardet.universaldetector import UniversalDetector
import os.path
import sys
import dbfUtils
import sys
from osgeo import osr
from urllib import urlencode
from urllib2 import urlopen
import json

shp_file = sys.argv[1]
dbf_file = shp_file[0:-4] + '.dbf'
prj_file = shp_file[0:-4] + '.prj'

#Try detecting the SRID, by default we set to 4326 and hope the best
srid=4326
if os.path.isfile(prj_file):
    prj_filef = open(prj_file, 'r')
    prj_txt = prj_filef.read()
    prj_filef.close()
    srs = osr.SpatialReference()
    srs.ImportFromESRI([prj_txt])
    srs.AutoIdentifyEPSG()
    code = srs.GetAuthorityCode(None)
    if code:
        srid= code
    else:
        #Ok, no luck, lets try with the OpenGeo service
        query = urlencode({
            'exact' : True,
            'error' : True,
            'mode' : 'wkt',
            'terms' : prj_txt})
        webres = urlopen('http://prj2epsg.org/search.json', query)
        jres = json.loads(webres.read())
        if jres['codes']:
            srid = int(jres['codes'][0]['code'])

#Try to detect the encoding
dbf = open(dbf_file, 'rb')
db = dbfUtils.dbfreader(dbf)

detector = UniversalDetector()
for row in db:
    detector.feed(str(row))
    if detector.done: break
detector.close()
dbf.close()

encoding = detector.result["encoding"]
if encoding=="ascii":
    encoding="LATIN1"

print "shp2pgsql -s %s -k -i -I -W %s %s.shp public.importing_table" %(srid,encoding,shp_file)
jatorre
fonte
3

srsly. Eu quero um também.

Muitas pessoas parecem procurá-las em http://spatialreference.org

Quando você importa shapefiles usando o PostGIS (e o carregador PostGIS para o PGAdmin), ele procura as informações do projeto em uma tabela chamada spatial_ref_sys.

Pelo que entendi, a tabela spatial_ref_sys padrão fornecida com o PostGIS inclui apenas representações OGC WKT (Texto Conhecido do Open Geospatial Consortium Well Known) de alguns Sistemas de Referência Espacial e NÃO os sistemas de referência espacial ESRI.

Na documentação do PostGIS 1.5.2:>

A tabela spatial_ref_sys é uma tabela de banco de dados compatível com PostGIS e compatível com OGC que lista mais de 3001 sistemas de referência espacial conhecidos e detalhes necessários para transformar / reprojetar entre eles.

Embora a tabela spatial_ref_sys do PostGIS contenha mais de 3000 das definições de sistema de referência espacial mais usadas que podem ser tratadas pela biblioteca do proj, ela não contém todas as conhecidas pelo homem e você pode até definir sua própria projeção personalizada se estiver familiarizado com as construções do proj4 . Lembre-se de que a maioria dos sistemas de referência espacial é regional e não tem significado quando usados ​​fora dos limites para os quais foram projetados.

Um excelente recurso para encontrar sistemas de referência espacial não definidos no conjunto principal é http://spatialreference.org/ Alguns dos sistemas de referência espacial mais usados ​​são: 4326 - WGS 84 Long Lat, 4269 - NAD 83 Long Lat, 3395 - WGS 84 World Mercator, 2163 - Área Nacional do Atlas Nacional dos EUA, sistemas de referência espacial para cada zona NAD 83, WGS 84 UTM - as zonas UTM são uma das mais ideais para medição, mas cobrem apenas regiões de 6 graus.

Vários sistemas de referência espacial do plano de estado dos EUA (com base em metros ou pés) - geralmente um ou 2 existem por estado dos EUA. A maioria dos medidores está no conjunto principal, mas muitos dos que são baseados em pés ou criados pela ESRI, você precisará extrair de spatialreference.org.

No entanto, o ogr2ogr contém sistemas de referência espacial ESRI, como aprendi recentemente com a generosidade de outros.

No ogr2ogr e no spatial_ref_sys, parece que o texto contido no arquivo .proj é comparado com uma tabela do OGC WKT, que é um formato de texto ligeiramente diferente do formato ESRI WKT que você geralmente encontra em um arquivo .proj. Além disso, não sei como o PostGIS consulta cada SRS, mas as pequenas diferenças entre o ESRI WKT e o OGC WKT podem resultar em falhas na correspondência.

Parece que seria simples anexar os sistemas de referência espacial ESRI à tabela spatial_ref_sys padrão no PostGIS. Talvez alguém já tenha, com algum patch ou script.

Eu posso estar errado, porque acabei de encontrar isso nos últimos dias e fiquei frustrado com a mesma coisa. Talvez alguém conheça um ótimo recurso?

BenjaminGolder
fonte
1

Já faz um tempo desde que eu precisava, mas pelo que me lembro, http://spatialreference.org/ , além de permitir que você pesquise, também oferece a opção de fazer upload de um arquivo prj.

Então, como uma das opções de saída, você terá a inserção postgis equivalente para inserir na tabela spatial_ref_sys.

Para a instrução de inserção fornecida, substituo o srid gerado que ele cria pelo EPSG ou ESRI. Se você receber uma violação de chave primária, provavelmente já está na tabela.

LR1234567
fonte