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

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

如果您选择其他SRID,进口商有能力即时进行重新投影吗?有谁知道这个概念是否在起作用,还是有充分的理由将其排除在外?

#1 楼

从@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。我会保持手指交叉。

– RyanKDalton
11年3月28日在23:07

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

– Mike T
2011-3-28在23:33

#2 楼

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不在space_ref_sys表中,因此您不能使用输出来查找SRID;和(2)我似乎找不到任何SRID属性或方法(有一个方便的ImportFromEPSG(SRID)方法,但没有其他方法)

– Mike T
2011-3-27在21:44

我已经通过调用AutoIdentifyEPSG()方法更新了脚本,它将起到神奇的作用;)

– capooti
2011年4月6日14:41

很酷。优秀作品!

– RyanKDalton
2011年4月6日15:46

当gdalsrsinfo和ogrinfo使您失败时,这就是方法!

– Kontextify
17年4月4日在12:07

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

–astrojuanlu
17年7月26日在16:10

#3 楼

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

评论


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

– Mike T
2011-3-27在9:27

#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)
 


#5 楼

不好意思我也想要一个。

很多人似乎都在http://spatialreference.org

上查找它们。 ,它会在称为space_ref_sys的表中查找项目信息。

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

从PostGIS 1.5.2文档:空间参考系
系统以及在它们之间进行转换/重新投影所需的细节。通过proj库,它不包含人类已知的所有内容,如果您熟悉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中的默认spatial_ref_sys表。也许有人已经有了一些补丁或脚本。

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

#6 楼

自从我需要一段时间以来,但是回想一下,http://spatialreference.org/除了允许您进行搜索之外,还为您提供了上传prj文件的选项。作为输出选项之一,它将为您提供等效的postgis插入,以插入到space_ref_sys表中。对于它给出的insert语句,我用EPSG或ESRI替换了它创建的生成的srid。如果遇到主键冲突,那么很可能已经知道它已经在表中。