Shapefile PRJ do tabeli odnośników PostGIS SRID?

38

Zastanawiałem się, czy istnieje coś takiego jak plik kształtu PRJ do tabeli odnośników PostGIS SRID? Coś, co może przetłumaczyć najbardziej standardowe definicje pliku kształtu PRJ na prawdopodobny SRID.

Jeśli korzystasz z PostGIS i pgAdminIII, jeśli użyjesz postgisgui do zaimportowania twoich plików kształtu, SRID pozostanie jako „-1”. Wygląda na to, że narzędzie powinno być w stanie przeanalizować Esri PRJ i określić prawidłowe (lub przynajmniej kilka opcji), które są prawdopodobnym SRID, zamiast po prostu pozostawić wartość domyślną.

A może importer ma możliwość ponownej projekcji w locie, jeśli wybierzesz inny identyfikator SRID?

Z mojej strony może to wydawać się leniwe, ale wydaje mi się ciekawe, że ta funkcja nie została jeszcze wprowadzona. Czy ktoś wie, czy ta koncepcja jest w trakcie realizacji, czy też jest dobry powód, dla którego ją pominięto?

RyanDalton
źródło

Odpowiedzi:

9

Pożyczając pomysł z @iant, oto moduł PL / Python3, który wyszukuje kody liczbowe EPSG SRID z pliku PRJ za pomocą serwisu internetowego http://prj2epsg.org .

Najpierw zainstaluj PL / Python3:

CREATE LANGUAGE plpython3u;

teraz dodaj funkcję SQL, która ma kod napisany dla Pythona 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;

Aby użyć go z PostgreSQL:

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

zwraca 4326 za mój test Shapefile.

Mike T.
źródło
Oznaczę to jako rozwiązanie. Podczas gdy pozostałe są doskonałe, uwielbiam ten pomysł. Teraz, jeśli uda nam się po prostu kogoś, kto ma zdolność kodowania, umieści ten typ funkcji w module ładującym pgAdmin PostGIS, tak aby automatycznie określał poprawny SRID po odczytaniu SHP. Będę trzymać kciuki.
RyanDalton
1
Oczywiście należy pamiętać, że wymaga połączenia z Internetem i zależy od zewnętrznej usługi internetowej, która musi zostać uruchomiona i uruchomiona.
Mike T
57

GDAL ma ładny wygodny interfejs do biblioteki PROJ4.

Jeśli masz pewność co do Pythona, korzystając z powiązań GDAL Python, jeśli zaimportujesz klasy osr, będziesz mieć bardzo wygodne metody odczytu i eksportowania reprezentacji projekcji do różnych formatów, takich jak PROJ4, WKT, Esri .PRJ.

Na przykład ten skrypt przekonwertuje plik .PRJ pliku shapefile na WKT i PROJ4 (ostatni jest używany z 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])

Uruchom to w wierszu poleceń:

$ 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
źródło
Natknąłem się na dwa problemy tego podejścia: (1) +proj=longlat +datum=WGS84 +no_defsnie ma w spatial_ref_systabeli, więc nie można użyć danych wyjściowych do wyszukiwania SRID; i (2) Nie mogę znaleźć żadnej właściwości lub metody SRID (istnieje przydatna ImportFromEPSG(SRID)metoda, ale nie na odwrót)
Mike T
4
Zaktualizowałem skrypt za pomocą wywołania metody AutoIdentifyEPSG (), która wykona magię;)
capooti
Bardzo fajny. Wspaniała robota!
RyanDalton,
Kiedy gdalsrsinfoi ogrinfoci się nie uda, to jest najlepsza droga!
kontextify
Zwróć uwagę, srs.GetAuthorityCode(None)że nadal może nie zwracać żadnego, jeśli nie zostanie zidentyfikowany bliski SRID.
astrojuanlu
19

Minęło trochę czasu, odkąd użyłem sridów POSTGIS, ale jeśli są to tylko kody EPSG, możesz użyć http://prj2epsg.org/search, aby wyszukać je z (uszkodzonych) plików ESRI.prj.

Ian Turton
źródło
To naprawdę inteligentna strona internetowa. Patrząc na API , możesz napisać fajny skrypt po stronie serwera, aby zautomatyzować procedurę.
Mike T
4

Jako mieszankę rozwiązań stworzyłem skrypt, który pomoże mi załadować dowolne pliki shapefile do postgis. Próbuje również wykryć kodowanie 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
źródło
3

srsly. Też chcę jednego.

Wydaje się, że wiele osób szuka ich na stronie http://spatialreference.org

Podczas importowania plików kształtów za pomocą PostGIS (i modułu ładującego PostGIS dla PGAdmin), wyszukuje informacje o proj w tabeli o nazwie spatial_ref_sys.

Z tego, co rozumiem, standardowa tabela spatial_ref_sys spakowana z PostGIS zawiera tylko reprezentacje OGC WKT (dobrze znany tekst konsorcjum Open Geospatial) niektórych systemów odniesienia przestrzennego, a NIE systemów odniesienia przestrzennego ESRI.

Z dokumentacji PostGIS 1.5.2:>

Tabela spatial_ref_sys jest tabelą bazy danych zawierającą PostGIS i zgodną z OGC, która zawiera listę ponad 3001 znanych systemów odniesienia przestrzennego oraz szczegóły potrzebne do transformacji / zmiany projektu między nimi.

Chociaż tabela PostGIS spatial_ref_sys zawiera ponad 3000 najczęściej używanych definicji systemu odniesień przestrzennych, które mogą być obsługiwane przez bibliotekę proj, nie zawiera ona wszystkich znanych człowiekowi i możesz nawet zdefiniować własną projekcję, jeśli znasz konstrukcje proj4 . Należy pamiętać, że większość przestrzennych systemów odniesienia ma charakter regionalny i nie ma znaczenia, gdy są używane poza granicami, dla których zostały przeznaczone.

Doskonałym źródłem do znalezienia przestrzennych systemów odniesienia, które nie zostały zdefiniowane w zestawie podstawowym, jest http://spatialreference.org/. Niektóre z najczęściej używanych przestrzennych systemów odniesienia to: 4326 - WGS 84 Long Lat, 4269 - NAD 83 Long Lat, 3395 - WGS 84 World Mercator, 2163 - Równy Obszar Atlasu Narodowego USA, przestrzenne systemy odniesienia dla każdej NAD 83, WGS 84 strefa UTM - strefy UTM są jednymi z najbardziej idealnych do pomiaru, ale obejmują jedynie obszary 6-stopniowe.

Różne systemy odniesienia przestrzennego w płaszczyźnie stanów USA (oparte na metrach lub stopach) - zwykle jeden lub 2 występuje w jednym stanie USA. Większość z nich znajduje się w zestawie podstawowym, ale wiele z nich opartych na stopach lub stworzonych przez ESRI będzie trzeba pobrać ze spatialreference.org.

Jednak ogr2ogr zawiera przestrzenne systemy odniesienia ESRI, o których niedawno dowiedziałem się dzięki hojności innych.

Zarówno w przypadku ogr2ogr, jak i spatial_ref_sys wydaje się, że tekst zawarty w pliku .proj jest porównywany z tabelą OGC WKT, która jest nieco innym formatem tekstowym niż format ESRI WKT, który często znajduje się w pliku .proj. Ponadto nie jestem pewien, jak PostGIS sprawdza każdy SRS, ale niewielkie różnice między ESRI WKT i OGC WKT mogą powodować nieudane dopasowania.

Wygląda na to, że podłączenie systemów odniesienia przestrzennego ESRI do domyślnej tabeli spatial_ref_sys w PostGIS byłoby proste. Może ktoś już ma, z jakąś łatką lub skryptem.

Mogłem się mylić, ponieważ wpadłem na to od kilku dni i byłem sfrustrowany tym samym. Może ktoś inny zna świetne źródło?

BenjaminGolder
źródło
1

Minęło trochę czasu, odkąd musiałem, ale jak pamiętam, http://spatialreference.org/ oprócz umożliwienia wyszukiwania, daje również możliwość przesłania pliku prj.

Wtedy jako jedna z opcji wyjściowych otrzymasz równoważne wstawienie postgis do wstawienia do tabeli spatial_ref_sys.

Dla podanej instrukcji insert zamieniam wygenerowany plik srid na plik EPSG lub ESRI. Jeśli otrzymasz naruszenie klucza podstawowego, najprawdopodobniej wiesz, że jest już w tabeli.

LR1234567
źródło