Шейп-файл PRJ для таблицы поиска PostGIS SRID?

38

Мне было интересно, существует ли такая вещь, как шейп-файл PRJ для таблицы поиска PostGIS SRID? Что-то, что может перевести самые стандартные определения PRJ шейп-файлов в вероятный SRID.

При использовании PostGIS и pgAdminIII, если вы используете postgisgui для импорта своих шейп-файлов, SRID остается как «-1». Похоже, что инструмент должен иметь возможность анализировать PRI Esri и определять правильные (или, по крайней мере, пару вариантов), которые являются вероятным SRID, вместо того, чтобы просто оставить значение по умолчанию.

Или у импортера есть возможность перепроецировать на лету, если вы выберете другой SRID?

Это может показаться ленивым с моей стороны, но мне кажется любопытным, что эта функция еще не реализована. Кто-нибудь знает, есть ли эта концепция в разработке, или веская причина, почему она была исключена?

RyanDalton
источник

Ответы:

9

Заимствуя идею из @iant, вот модуль PL / Python3, который будет искать целые коды EPSG SRID из файла PRJ, используя веб-сервис http://prj2epsg.org .

Сначала установите PL / Python3:

CREATE LANGUAGE plpython3u;

Теперь добавьте функцию SQL, код которой написан для 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;

Чтобы использовать его из PostgreSQL:

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

возвращает 4326 для моего теста Shapefile.

Майк Т
источник
Я собираюсь отметить это как решение. В то время как другие все отлично, мне нравится эта идея. Теперь, если мы сможем просто заставить кого-то, обладающего способностью кодирования, включить этот тип функциональности в загрузчик шейп-файлов PostgIS pgAdmin, чтобы он автоматически определял правильный SRID при чтении SHP. Я буду держать пальцы скрещенными.
RyanDalton
1
Предостережения, конечно, требуют подключения к Интернету и зависят от внешнего веб-сервиса, который должен быть запущен и запущен.
Майк Т
57

GDAL имеет приятный удобный интерфейс к библиотеке PROJ4.

Если вы уверены в Python, используя привязки GDAL Python, если вы импортируете классы osr, у вас будут очень удобные методы для чтения и экспорта проекционных представлений в различные форматы, такие как PROJ4, WKT, Esri .PRJ.

Например, этот скрипт преобразует ваш файл .PRJ вашего шейп-файла в WKT и PROJ4 (последний используется из 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])

Запустите это в командной строке:

$ 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
источник
При таком подходе я столкнулся с двумя проблемами: (1) +proj=longlat +datum=WGS84 +no_defsнет в spatial_ref_sysтаблице, поэтому вы не можете использовать вывод для поиска SRID; и (2) я не могу найти какое-либо свойство или метод SRID (есть удобный ImportFromEPSG(SRID)метод, но не наоборот)
Mike T
4
Я обновил скрипт с помощью вызова метода AutoIdentifyEPSG (), который будет творить чудеса;)
capooti
Очень круто. Превосходная работа!
RyanDalton
Когда gdalsrsinfoи ogrinfoподведет тебя, это путь!
kontextify
Обратите внимание, что он srs.GetAuthorityCode(None)все еще может вернуть ничего, если не был идентифицирован близкий SRID.
astrojuanlu
19

Я давно использовал srids POSTGIS, но если они являются просто кодами EPSG, вы можете использовать http://prj2epsg.org/search, чтобы найти их в (поврежденных) файлах ESRI.prj.

Ян Тертон
источник
Это действительно умный сайт. Глядя на API , вы можете написать хороший серверный скрипт для автоматизации процедуры.
Майк Т
4

В качестве комбинации решений я создал скрипт, который поможет мне загружать произвольные шейп-файлы в postgis. Он также пытается определить кодировку 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
источник
3

srsly. Я тоже хочу один.

Многие люди, кажется, ищут их на http://spatialreference.org

Когда вы импортируете шейп-файлы с использованием PostGIS (и загрузчика PostGIS для PGAdmin), он ищет информацию о proj в таблице, которая называется пространственным_реф_сисом.

Из того, что я понимаю, стандартная таблицаatial_ref_sys, поставляемая с PostGIS, включает в себя только представления OGC WKT (Open Geospatial Consortium Well Known Text) некоторых пространственных систем отсчета, а НЕ пространственных систем отсчета ESRI.

Из документации PostGIS 1.5.2:>

Таблицаatial_ref_sys - это таблица базы данных, включенная в PostGIS и совместимая с OGC, в которой перечислены более 3001 известных систем пространственной привязки и сведения, необходимые для преобразования / перепроектирования между ними.

Несмотря на то, что таблица PostGISatial_ref_sys содержит более 3000 наиболее часто используемых определений системы пространственной привязки, которые могут обрабатываться библиотекой proj, она не содержит все известные человеку, и вы даже можете определить свою собственную пользовательскую проекцию, если вы знакомы с конструкциями proj4 , Имейте в виду, что большинство систем пространственной привязки являются региональными и не имеют смысла при использовании за пределами границ, для которых они были предназначены.

Отличным ресурсом для поиска систем пространственной привязки, не определенных в базовом наборе, является http://spatialreference.org/. Некоторые из наиболее часто используемых систем пространственной привязки: 4326 - WGS 84 Long Lat, 4269 - NAD 83 Long Lat, 3395 - WGS 84 World Mercator, 2163 - Национальная равная зона Атласа США, Системы пространственной привязки для каждого NAD 83, Зона UTM WGS 84 - Зоны UTM являются одними из самых идеальных для измерения, но охватывают только 6-градусные области.

Различные системы пространственной привязки штатов США (на основе метра или футов) - обычно одна или две существуют в каждом штате США. Большинство измерителей находятся в базовом наборе, но многие из основанных на футах или созданных ESRI вам нужно будет взять с сайтаrealreference.org.

Однако ogr2ogr содержит системы пространственных ссылок ESRI, как я недавно узнал благодаря щедрости других.

Кажется, что и в ogr2ogr, и вpace_ref_sys текст, содержащийся в файле .proj, сравнивается с таблицей OGC WKT, которая немного отличается от формата ESRI WKT, который вы часто встречаете в файле .proj. Кроме того, я не уверен, как PostGIS ищет каждую SRS, но небольшие различия между ESRI WKT и OGC WKT могут привести к неудачным совпадениям.

Кажется, было бы просто присоединить системы пространственных ссылок ESRI к таблице пространственных_реф_сисов по умолчанию в PostGIS. Может быть, кто-то уже с каким-то патчем или скриптом.

Я могу ошибаться, потому что я только что столкнулся с этим в течение последних нескольких дней, и я был разочарован тем же. Может, кто-то знает отличный ресурс?

BenjaminGolder
источник
1

Прошло много времени с тех пор, как мне это было нужно, но, насколько я помню, http://spatialreference.org/, помимо возможности поиска, также дает вам возможность загрузить файл prj.

Затем он в качестве одного из вариантов вывода даст вам эквивалентную вставку postgis для вставки в таблицу пространственный_реф_сис.

Для оператора вставки, который он дает, я заменяю созданный srid, который он создает, на EPSG или ESRI. Если вы получили нарушение первичного ключа, то вы, скорее всего, знаете, что оно уже есть в таблице.

LR1234567
источник