Shapefile PRJ a PostGIS SRID tabla de búsqueda?


38

Me preguntaba si existe algo así como un PRJ de archivo de forma a la tabla de búsqueda SRID de PostGIS. Algo que puede traducir las definiciones de PRJ de shapefile más estándar en el SRID probable.

Cuando usa PostGIS y pgAdminIII, si usa postgisgui para importar sus archivos de forma, el SRID se deja como "-1". Parece que la herramienta debería poder analizar el Esri PRJ y determinar la correcta (o al menos un par de opciones) que son los SRID probables, en lugar de simplemente dejar el valor predeterminado.

¿O tiene el importador la capacidad de reproyectar sobre la marcha si elige otro SRID?

Puede parecer flojo de mi parte, pero para mí parece curioso que esta función aún no se haya implementado. ¿Alguien sabe si este concepto está en proceso, o hay buenas razones por las que se ha dejado de lado?

Respuestas:


9

Tomando prestada la idea de @iant, aquí hay un módulo PL / Python3 que buscará los códigos enteros EPSG SRID de un archivo PRJ utilizando el servicio web http://prj2epsg.org .

Primero, instale PL / Python3:

CREATE LANGUAGE plpython3u;

Ahora agregue la función SQL, que tiene 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 usarlo desde PostgreSQL:

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

devuelve 4326 para mi prueba Shapefile.


Voy a marcar esto como la solución. Si bien los demás son excelentes, me encanta esta idea. Ahora, si podemos lograr que alguien con la capacidad de codificación incluya este tipo de funcionalidad en el cargador de archivos de forma pgAdmin PostGIS para que determine automáticamente el SRID correcto al leer el SHP. Mantendré mis dedos cruzados.
RyanDalton

1
La advertencia, por supuesto, es que requiere una conexión a Internet y depende de un servicio web externo que necesita estar en funcionamiento.
Mike T

57

GDAL tiene una interfaz agradable y conveniente para la biblioteca PROJ4.

Si tiene confianza en Python, utilizando los enlaces Python de GDAL, si importa las clases osr, tendrá métodos muy convenientes para leer y exportar representaciones de proyección a una variedad de formatos como PROJ4, WKT, Esri .PRJ.

Por ejemplo, este script convertirá su archivo .PRJ de su shapefile a WKT y PROJ4 (el último se usa desde 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])

Ejecute esto en la línea 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

Encontré dos problemas con este enfoque: (1) +proj=longlat +datum=WGS84 +no_defsno está en la spatial_ref_systabla, por lo que no puede usar la salida para buscar el SRID; y (2) parece que no puedo encontrar ninguna propiedad o método SRID (hay un ImportFromEPSG(SRID)método útil , pero no al revés)
Mike T

44
He actualizado el script con una llamada al método AutoIdentifyEPSG () que hará la magia;)
capooti

Muy genial. ¡Excelente trabajo!
RyanDalton

Cuando gdalsrsinfoy ogrinfofallar, este es el camino a seguir!
kontextify

Tenga en cuenta que srs.GetAuthorityCode(None)aún podría devolver ninguno si no se identificó un SRID cercano.
astrojuanlu

19

Ha pasado un tiempo desde que usé las cuadrículas POSTGIS, pero si son solo códigos EPSG, puede usar http://prj2epsg.org/search para buscarlos desde archivos ESRI.prj (rotos).


Este es un sitio web realmente inteligente. Mirando la API , podría escribir un buen script del lado del servidor para automatizar el procedimiento.
Mike T

4

Como una combinación de soluciones, he creado un script para ayudarme a cargar archivos de formas arbitrarias en postgis. También intenta detectar la codificación del 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)

3

srsly Yo quiero uno también.

Muchas personas parecen buscarlos en http://spatialreference.org

Cuando importa archivos de forma usando PostGIS (y el cargador PostGIS para PGAdmin), busca la información del proyecto en una tabla llamada spatial_ref_sys.

Por lo que entiendo, la tabla spatial_ref_sys estándar empaquetada con PostGIS incluye solo representaciones OGC WKT (Open Geospatial Consortium Well Known Text) de algunos sistemas de referencia espacial y NO los sistemas de referencia espacial ESRI.

De la documentación de PostGIS 1.5.2:>

La tabla spatial_ref_sys es una tabla de base de datos incluida en PostGIS y compatible con OGC que enumera más de 3001 sistemas de referencia espacial conocidos y detalles necesarios para transformar / reproyectar entre ellos.

Si bien la tabla PostGIS spatial_ref_sys contiene más de 3000 de las definiciones de sistemas de referencia espacial más utilizadas que puede manejar la biblioteca de proyectos, no contiene todas las conocidas por el hombre e incluso puede definir su propia proyección personalizada si está familiarizado con las construcciones de proj4 . Tenga en cuenta que la mayoría de los sistemas de referencia espacial son regionales y no tienen significado cuando se usan fuera de los límites para los que fueron destinados.

Un excelente recurso para encontrar sistemas de referencia espacial no definidos en el conjunto básico es http://spatialreference.org/ Algunos de los sistemas de referencia espacial más utilizados son: 4326 - WGS 84 Long Lat, 4269 - NAD 83 Long Lat, 3395 - WGS 84 World Mercator, 2163 - Área igual de Atlas nacional de EE. UU., Sistemas de referencia espacial para cada NAD 83, zona WGS 84 UTM: las zonas UTM son una de las más ideales para la medición, pero solo cubren regiones de 6 grados.

Varios sistemas de referencia espacial del plano del estado de los EE. UU. (Basados ​​en metros o pies): generalmente existe uno o 2 por estado de los EE. UU. La mayoría de los medidores están en el conjunto central, pero muchos de los basados ​​en pies o creados por ESRI deberán extraerse de spatialreference.org.

Sin embargo, ogr2ogr contiene sistemas de referencia espacial ESRI como aprendí recientemente a través de la generosidad de otros.

Tanto en ogr2ogr como spatial_ref_sys, parece que el texto contenido en el archivo .proj se compara con una tabla de OGC WKT, que es un formato de texto ligeramente diferente del formato ESRI WKT que a menudo se encuentra en un archivo .proj. Además, no estoy seguro de cómo PostGIS busca cada SRS, pero las pequeñas diferencias entre ESRI WKT y OGC WKT pueden dar lugar a coincidencias fallidas.

Parece que sería simple adjuntar los sistemas de referencia espacial ESRI a la tabla spatial_ref_sys predeterminada en PostGIS. Quizás alguien ya lo haya hecho, con algún parche o un guión.

Podría estar equivocado, porque me he topado con esto durante los últimos días y me he sentido frustrado con lo mismo. ¿Quizás alguien más conoce un gran recurso?


1

Ha pasado un tiempo desde que lo necesitaba, pero, según recuerdo, http://spatialreference.org/ además de permitirle buscar, también le ofrece la opción de cargar un archivo prj.

Luego, como una de las opciones de salida, le dará la inserción postgis equivalente para insertar en la tabla spatial_ref_sys.

Para la instrucción de inserción que proporciona, reemplazo la cuadrícula generada que crea con la EPSG o ESRI. Si obtiene una violación de clave principal, entonces lo más probable es que ya esté en la tabla.

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.