Shapefile PRJ ke PostGIS SRID lookup table?

38

Saya bertanya-tanya apakah ada yang namanya PRJ ke postGIS SRID lookup table? Sesuatu yang dapat menerjemahkan definisi PRJ shapefile yang paling standar menjadi kemungkinan SRID.

Saat menggunakan PostGIS dan pgAdminIII, jika Anda menggunakan postgisgui untuk mengimpor shapefile Anda, SRID dibiarkan sebagai "-1". Sepertinya alat harus dapat mengurai Esri PRJ dan menentukan yang benar (atau setidaknya beberapa opsi) yang kemungkinan SRID, daripada hanya meninggalkan default.

Atau apakah importir memiliki kemampuan untuk memproyeksi ulang dengan cepat jika Anda memilih SRID lain?

Mungkin kelihatannya malas di pihak saya, tetapi bagi saya sepertinya penasaran bahwa fungsi ini belum diterapkan. Adakah yang tahu jika konsep ini ada dalam karya, atau alasan bagus mengapa itu ditinggalkan?

Ryan Dalton
sumber

Jawaban:

9

Meminjam gagasan dari @iant, berikut adalah modul PL / Python3 yang akan mencari kode integer EPSG SRID dari file PRJ menggunakan layanan web http://prj2epsg.org .

Pertama, instal PL / Python3:

CREATE LANGUAGE plpython3u;

sekarang tambahkan fungsi SQL, yang memiliki kode yang ditulis untuk 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;

Untuk menggunakannya dari PostgreSQL:

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

mengembalikan 4326 untuk Shapefile pengujian saya.

Mike T
sumber
Saya akan menandai ini sebagai solusinya. Sementara yang lain sangat bagus, saya suka ide ini. Sekarang jika kita bisa mendapatkan seseorang dengan kemampuan pengkodean untuk memasukkan jenis fungsionalitas ini ke dalam pemuat shapefile pgAdmin PostGIS sehingga secara otomatis menentukan SRID yang benar setelah membaca SHP. Aku akan tetap menyilangkan jari.
RyanDalton
1
Peringatan tentu saja itu memerlukan koneksi Internet dan tergantung pada layanan web eksternal yang perlu untuk bangkit dan berjalan.
Mike T
57

GDAL memiliki antarmuka yang nyaman dan bagus ke perpustakaan PROJ4.

Jika Anda yakin dengan Python, menggunakan binding GDAL Python, jika Anda mengimpor kelas osr, Anda akan memiliki metode yang sangat nyaman untuk membaca dan mengekspor representasi proyeksi ke berbagai format seperti PROJ4, WKT, Esri .PRJ.

Misalnya skrip ini akan mengonversi file .PRJ Anda dari shapefile Anda menjadi WKT dan PROJ4 (yang terakhir digunakan dari 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])

Jalankan ini di baris perintah:

$ 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
sumber
Saya menemukan dua masalah pendekatan ini: (1) +proj=longlat +datum=WGS84 +no_defstidak ada dalam spatial_ref_systabel, jadi Anda tidak dapat menggunakan output untuk mencari SRID; dan (2) Saya tidak dapat menemukan properti atau metode SRID (ada ImportFromEPSG(SRID)metode praktis , tetapi tidak sebaliknya)
Mike T
4
Saya telah memperbarui skrip dengan panggilan ke metode AutoIdentifyEPSG () yang akan melakukan keajaiban;)
capooti
Sangat keren. Kerja bagus!
RyanDalton
Kapan gdalsrsinfodan ogrinfogagal Anda, ini adalah cara untuk pergi!
kontextify
Perhatikan bahwa srs.GetAuthorityCode(None)mungkin masih tidak mengembalikan apa-apa jika tidak ditemukan SRID yang dekat
astrojuanlu
19

Sudah lama sejak saya menggunakan srids POSTGIS tetapi jika mereka hanya kode EPSG maka Anda dapat menggunakan http://prj2epsg.org/search untuk mencari mereka dari (rusak) file ESRI.prj.

Ian Turton
sumber
Ini adalah situs web yang sangat cerdas. Melihat API , Anda bisa menulis skrip sisi server yang bagus untuk mengotomatiskan prosedur.
Mike T
4

Sebagai campuran solusi, saya telah membuat skrip untuk membantu saya memuat shapefile yang sewenang-wenang ke postgis. Itu juga mencoba mendeteksi encoding dari 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
sumber
3

srsly. Saya juga mau.

Banyak orang tampaknya melihatnya di http://spatialreference.org

Ketika Anda mengimpor shapefile menggunakan PostGIS (dan loader PostGIS untuk PGAdmin), itu mencari informasi proj dalam tabel yang disebut spatial_ref_sys.

Dari apa yang saya mengerti, tabel spatial_ref_sys standar yang dipaket dengan PostGIS hanya menyertakan OGC WKT (Open Geospatial Consortium Wellknown Text) yang mewakili beberapa Sistem Referensi Spasial dan BUKAN sistem referensi Spasial ESRI.

Dari dokumentasi PostGIS 1.5.2:>

Tabel spatial_ref_sys adalah tabel basis data PostGIS yang disertakan dan sesuai dengan OGC yang mencantumkan lebih dari 3001 sistem referensi spasial yang diketahui dan detail yang diperlukan untuk mentransformasikan / memproyeksikan ulang di antara mereka.

Meskipun tabel spatial_ref_sys PostGIS berisi lebih dari 3000 definisi sistem referensi spasial yang lebih umum digunakan yang dapat ditangani oleh pustaka proj, itu tidak mengandung semua yang diketahui manusia dan Anda bahkan dapat menentukan proyeksi kustom Anda sendiri jika Anda terbiasa dengan konstruksi proj4 . Perlu diingat bahwa sebagian besar sistem referensi spasial bersifat regional dan tidak memiliki makna ketika digunakan di luar batas yang dimaksudkan untuknya.

Sumber yang luar biasa untuk menemukan sistem referensi spasial yang tidak didefinisikan dalam set inti adalah http://spatialreference.org/ Beberapa sistem referensi spasial yang lebih umum digunakan adalah: 4326 - WGS 84 Long Lat, 4269 - NAD 83 Long Lat, 3395 - WGS 84 World Mercator, 2163 - US National Atlas Equal Area, Sistem referensi spasial untuk setiap NAD 83, WGS 84 Zona UTM - Zona UTM adalah salah satu zona yang paling ideal untuk pengukuran, tetapi hanya mencakup wilayah 6 derajat.

Berbagai sistem referensi spasial pesawat negara bagian AS (berbasis meter atau kaki) - biasanya satu atau 2 ada per negara bagian AS. Sebagian besar meteran berada di set inti, tetapi banyak yang berbasis kaki atau yang dibuat ESRI Anda harus menarik dari spatialreference.org.

Namun ogr2ogr mengandung sistem ref spasial ESRI karena saya baru-baru ini belajar melalui kemurahan hati orang lain.

Dalam ogr2ogr dan spatial_ref_sys, tampaknya teks yang terkandung dalam file .proj dibandingkan dengan tabel OGC WKT, yang merupakan format teks yang sedikit berbeda dari format ESRI WKT yang sering Anda temukan dalam file .proj. Juga, saya tidak yakin bagaimana PostGIS mencari setiap SRS, tetapi perbedaan kecil antara ESRI WKT dan OGC WKT mungkin menghasilkan pertandingan yang gagal.

Sepertinya akan mudah untuk melampirkan sistem ref spasial ESRI ke tabel spatial_ref_sys default di PostGIS. Mungkin seseorang sudah memiliki, dengan beberapa tambalan atau skrip.

Saya bisa saja salah, karena saya baru saja mengalami hal ini selama beberapa hari terakhir, dan saya merasa frustrasi dengan hal yang sama. Mungkin orang lain tahu sumber yang bagus?

BenjaminGolder
sumber
1

Sudah lama sejak saya perlu, tetapi seingat saya, http://spatialreference.org/ selain memungkinkan Anda untuk mencari, juga memberi Anda pilihan untuk mengunggah file prj.

Maka itu akan sebagai salah satu opsi output memberi Anda memasukkan postgis setara untuk disisipkan ke tabel spatial_ref_sys.

Untuk pernyataan insert yang diberikannya, saya ganti srid yang dibuatnya dengan EPSG atau ESRI. Jika Anda mendapatkan pelanggaran kunci utama, maka Anda tahu kemungkinan besar sudah ada di tabel.

LR1234567
sumber