Shapefile PRJ到PostGIS SRID查找表?


38

我想知道是否有诸如Shapefile PRJ到PostGIS SRID查找表的东西?可以将最标准的shapefile PRJ定义转换为可能的SRID的东西。

使用PostGIS和pgAdminIII时,如果使用postgisgui导入shapefile,则SRID保留为“ -1”。似乎该工具应该能够解析Esri PRJ并确定可能的SRID正确(或至少有两个选择),而不仅仅是保留默认值。

或者,如果您选择另一个SRID,进口商是否有能力即时进行重新投影?

在我看来,这似乎很懒,但是对我来说,似乎很好奇这个功能还没有到位。有谁知道这个概念是否在起作用,还是有充分的理由将其排除在外?

Answers:


9

从@iant借用这个想法,这是一个PL / Python3模块,它将使用http://prj2epsg.org网络服务从PRJ文件中查找EPSG SRID整数代码。

首先,安装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');

为我的测试Shapefile返回4326。


我将其标记为解决方案。虽然其他人都很棒,但我喜欢这个主意。现在,如果我们可以让某个具有编码能力的人将这种类型的功能包括到pgAdmin PostGIS shapefile加载器中,以便它在读取SHP时自动确定正确的SRID。我会保持手指交叉。
RyanDalton

1
注意事项当然是它需要Internet连接,并取决于需要启动和运行的外部Web服务。
Mike T

57

GDAL具有到PROJ4库的很好的便捷接口。

如果您对Python很有信心,请使用GDAL Python绑定,如果导入osr类,您将有非常方便的方法来读取和导出投影表示形式,并将其转换为各种格式,例如PROJ4,WKT,Esri .PRJ。

例如,此脚本会将您的shapefile的.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

我用这种方法遇到了两个问题:(1)+proj=longlat +datum=WGS84 +no_defs不在spatial_ref_sys表中,因此您不能使用输出来查找SRID;和(2)我似乎找不到任何SRID属性或方法(有一个方便的ImportFromEPSG(SRID)方法,但没有其他方法)
Mike T

4
我已经通过调用AutoIdentifyEPSG()方法更新了脚本,该方法将
起到

很酷。优秀作品!
RyanDalton 2011年

gdalsrsinfoogrinfo失败的你,这是要走的路!
kontextify

请注意,srs.GetAuthorityCode(None)如果未找到关闭的SRID ,则可能仍不返回任何内容。
astrojuanlu

19

自从我使用POSTGIS srids已经有一段时间了,但是如果它们只是EPSG代码,则可以使用http://prj2epsg.org/search从(损坏的)ESRI.prj文件中查找它们。


这是一个非常聪明的网站。查看API,您可以编写一个漂亮的服务器端脚本来自动化该过程。
Mike T

4

作为多种解决方案的组合,我创建了一个脚本来帮助我将任意shapefile加载到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)

3

不好意思 我也要一个

许多人似乎在http://spatialreference.org上查找了它们

使用PostGIS(和用于PGAdmin的PostGIS加载程序)导入shapefile时,它将在名为spatial_ref_sys的表中查找项目信息。

据我了解,PostGIS打包的标准space_ref_sys表仅包含某些空间参考系统的OGC WKT(开放式地理空间协会知名文本)表示形式,而不包含ESRI空间参考系统。

从PostGIS 1.5.2文档中:>

spacear_ref_sys表是一个包含PostGIS且符合OGC的数据库表,该表列出了3001多个已知空间参考系统以及在它们之间进行转换/重新投影所需的详细信息。

尽管PostGISspatial_ref_sys表包含可以由proj库处理的3000多个更常用的空间参考系统定义,但它不包含人类已知的所有定义,如果您熟悉proj4构造,甚至可以定义自己的自定义投影。 。请记住,大多数空间参照系是区域性的,在其预期范围之外使用时没有任何意义。

查找核心集中未定义的空间参考系统的绝佳资源是http://spatialreference.org/。 一些更常用的空间参考系统是:4326-WGS 84 Long Lat,4269-NAD 83 Long Lat,3395- WGS 84世界墨卡托,2163年-美国国家地图集相等区域,每个NAD 83的空间参考系统,WGS 84 UTM区域-UTM区域是最理想的测量范围之一,但仅覆盖6度区域。

各种美国州平面空间参考系统(基于米或英尺)-每个美国州通常存在一个或两个。大多数仪表都在核心集中,但是您需要从spatialreference.org中提取许多基于英尺的仪表或由ESRI创建的仪表。

但是,ogr2ogr 包含ESRI空间参考系统,这是我最近从他人的慷慨中获悉的。

在ogr2ogr和spatial_ref_sys中,似乎都将.proj文件中包含的文本与OGC WKT表进行了比较,该表与您通常在.proj文件中找到的ESRI WKT格式略有不同。另外,我不确定PostGIS如何查找每个SRS,但是ESRI WKT和OGC WKT之间的细微差别可能会导致匹配失败。

将ESRI空间参考系统附加到PostGIS中的默认spacear_ref_sys表似乎很简单。也许有人已经拥有了一些补丁或脚本。

我可能是错的,因为过去几天我一直在碰到这个问题,而我对同一件事感到沮丧。也许别人知道一个很好的资源?


1

自从我需要一段时间以来,但是回想一下, 除了允许您进行搜索之外,http://spatialreference.org/还为您提供了上载prj文件的选项。

然后,它将作为输出选项之一,为您提供等效的postgis插入,以插入到space_ref_sys表中。

对于它给出的insert语句,我用EPSG或ESRI一个替换它创建的生成的srid。如果您遇到主键冲突,那么您很可能已经知道它已经存在于表中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.