Shapefile PRJ alla tabella di ricerca SRID PostGIS?


38

Mi chiedevo se esiste una cosa come uno shapefile PRJ nella tabella di ricerca SRID di PostGIS? Qualcosa che può tradurre le definizioni PRJ dello shapefile più standard nel probabile SRID.

Quando si utilizzano PostGIS e pgAdminIII, se si utilizza Postgisgui per importare i propri shapefile, l'SRID viene lasciato come "-1". Sembra che lo strumento dovrebbe essere in grado di analizzare il PRJ Esri e determinare il corretto (o almeno un paio di opzioni) che sono il probabile SRID, piuttosto che lasciare semplicemente il valore predefinito.

Oppure l'importatore ha la capacità di riproiettare al volo se si sceglie un altro SRID?

Può sembrare pigro da parte mia, ma a me sembra curioso che questa funzione non sia già stata attivata. Qualcuno sa se questo concetto è in cantiere, o una buona ragione è perché è stato lasciato fuori?

Risposte:


9

Prendendo in prestito l'idea da @iant, ecco un modulo PL / Python3 che cercherà i codici interi EPSG SRID da un file PRJ usando il servizio web http://prj2epsg.org .

Innanzitutto, installa PL / Python3:

CREATE LANGUAGE plpython3u;

ora aggiungo la funzione SQL, che ha il codice scritto per 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;

Per usarlo da PostgreSQL:

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

restituisce 4326 per il mio Shapefile di prova.


Lo segnerò come soluzione. Mentre gli altri sono tutti eccellenti, adoro questa idea. Ora, se riusciamo solo a ottenere qualcuno con la capacità di codifica per includere questo tipo di funzionalità nel caricatore dello shapefile pgAdmin PostGIS in modo che determini automaticamente l'SRID corretto dopo aver letto l'SHP. Terrò le dita incrociate.
Ryan Dalton,

1
L'avvertenza ovviamente è che richiede una connessione a Internet e dipende da un servizio Web esterno che deve essere installato e funzionante.
Mike T,

57

GDAL ha un'interfaccia comoda e piacevole per la libreria PROJ4.

Se sei sicuro di Python, usando i collegamenti GDAL Python, se importi le classi osr avrai metodi molto convenienti per leggere ed esportare rappresentazioni di proiezione in una varietà di formati come PROJ4, WKT, Esri .PRJ.

Ad esempio questo script convertirà il tuo file .PRJ del tuo file di forma in WKT e PROJ4 (l'ultimo viene utilizzato da 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])

Esegui questo dalla riga di 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

Mi sono imbattuto in due problemi in questo approccio: (1) +proj=longlat +datum=WGS84 +no_defsnon è nella spatial_ref_systabella, quindi non è possibile utilizzare l'output per cercare l'SRID; e (2) non riesco a trovare alcuna proprietà o metodo SRID (esiste un ImportFromEPSG(SRID)metodo utile , ma non viceversa)
Mike T

4
Ho aggiornato lo script con una chiamata al metodo AutoIdentifyEPSG () che farà la magia;)
capooti

Molto bello. Lavoro eccellente!
Ryan Dalton,

Quando gdalsrsinfoe quando ogrinfofallisci, questa è la strada da percorrere!
kontextify

Si noti che srs.GetAuthorityCode(None)potrebbe comunque non restituire nessuno se non è stato identificato alcun SRID vicino.
astrojuanlu,

19

È passato un po 'di tempo da quando ho usato gli srid POSTGIS ma se sono solo codici EPSG, puoi usare http://prj2epsg.org/search per cercarli dai file ESRI.prj (rotti).


Questo è un sito web davvero intelligente. Osservando l' API , è possibile scrivere uno script sul lato server per automatizzare la procedura.
Mike T

4

Come mix di soluzioni ho creato uno script per aiutarmi a caricare shapefile arbitrari in postgis. Prova anche a rilevare la codifica 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. Ne voglio uno anche io.

Molte persone sembrano cercarli su http://spatialreference.org

Quando si importano shapefile utilizzando PostGIS (e il caricatore PostGIS per PGAdmin), cerca le informazioni del proj in una tabella chiamata spatial_ref_sys.

Da quanto ho capito, la tabella standard spatial_ref_sys impacchettata con PostGIS include solo rappresentazioni OGC WKT (Open Geospatial Consortium Well Known Text) di alcuni sistemi di riferimento spaziale e NON i sistemi di riferimento spaziale ESRI.

Dalla documentazione PostGIS 1.5.2:>

La tabella spatial_ref_sys è una tabella di database inclusa PostGIS e conforme a OGC che elenca oltre 3001 sistemi di riferimento spaziale noti e dettagli necessari per trasformarli / riproiettarli tra loro.

Sebbene la tabella PostGIS spatial_ref_sys contenga oltre 3000 delle definizioni del sistema di riferimento spaziale più comunemente utilizzate che possono essere gestite dalla libreria proj, non contiene tutto ciò che è noto all'uomo e puoi anche definire la tua proiezione personalizzata se hai familiarità con i costrutti proj4 . Tieni presente che la maggior parte dei sistemi di riferimento spaziale sono regionali e non hanno alcun significato se utilizzati al di fuori dei limiti previsti.

Una risorsa eccellente per trovare sistemi di riferimento spaziale non definiti nel set di base è http://spatialreference.org/ Alcuni dei sistemi di riferimento spaziale più comunemente usati sono: 4326 - WGS 84 Long Lat, 4269 - NAD 83 Long Lat, 3395 - WGS 84 World Mercator, 2163 - Area pari atlante nazionale degli Stati Uniti, sistemi di riferimento spaziale per ogni NAD 83, zona UTM WGS 84 - Le zone UTM sono tra le più ideali per la misurazione, ma coprono solo regioni di 6 gradi.

Vari sistemi di riferimento spaziale del piano di stato USA (basati su metro o piedi) - di solito ne esistono uno o 2 per stato USA. La maggior parte dei misuratori sono nel set base, ma molti di quelli basati sui piedi o quelli creati dall'ESRI dovranno essere estratti da spatialreference.org.

Tuttavia ogr2ogr contiene i sistemi di riferimento spaziale ESRI come ho appreso di recente attraverso la generosità degli altri.

In ogr2ogr e spatial_ref_sys, sembra che il testo contenuto nel file .proj sia confrontato con una tabella di OGC WKT, che è un formato di testo leggermente diverso dal formato ESRI WKT che trovi spesso in un file .proj. Inoltre, non sono sicuro di come PostGIS cerchi ogni SRS, ma le piccole differenze tra ESRI WKT e OGC WKT potrebbero comportare errori di corrispondenza.

Sembra che sarebbe semplice collegare i sistemi di riferimento spaziale ESRI alla tabella spatial_ref_sys predefinita in PostGIS. Forse qualcuno l'ha già fatto, con qualche patch o una sceneggiatura.

Potrei sbagliarmi, perché mi sono appena imbattuto in questo negli ultimi giorni e sono stato frustrato con la stessa cosa. Forse qualcun altro conosce una grande risorsa?


1

È passato un po 'di tempo da quando avevo bisogno, ma per quanto ricordo, http://spatialreference.org/ oltre a permetterti di cercare, ti dà anche la possibilità di caricare un file prj.

Quindi come una delle opzioni di output ti darà l'inserimento postgis equivalente da inserire nella tabella spatial_ref_sys.

Per l'istruzione insert che fornisce, sostituisco lo srid generato che crea con quello EPSG o ESRI. Se ricevi una violazione della chiave primaria, allora sai molto probabilmente che è già nella tabella.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.