我想知道是否可以在没有ArcMap许可的情况下使用Python查看shapefile的内容。这种情况是,您不仅可以通过ESRI软件,还可以通过许多不同的应用程序创建shapefile。我想创建一个Python脚本,用于检查空间参考,要素类型,属性名称和定义以及shapefile中字段的内容,并将它们与一组可接受的值进行比较。即使组织没有任何ESRI许可证,我也希望此脚本能够运行。要执行这样的操作,是否必须使用ArcPy或不使用ArcPy就能挖入shapefile?

评论

这取决于您要投入多少精力。.有几个开源库会有所帮助(根据Aarons的回答,我喜欢OGR),但是如果您真的想控制(并准备为此工作),Shapefile (最初由Esri提供)是一种开放格式,请参见en.wikipedia.org/wiki/Shapefile

最近(过去几年)的ESRI shapefile隐藏在其新的地理数据库格式中。除ARCxxx软件外,似乎没有其他方法可以破坏它们。许多公共机构正在将其用于公共信息...可惜。

#1 楼

我建议您熟悉Python GDAL / OGR API,以同时使用矢量和栅格数据。开始使用GDAL / OGR的最简单方法是通过python发行版,例如python(x,y),Anaconda或OSGeo4W。
针对特定任务使用GDAL的更多详细信息:

获取Shapefile字段和类型
此外,我还建议您从USU推荐以下教程来开始使用投影。 br />

从以上示例中借用,以下脚本使用FOSS工具执行以下操作:
检查用户定义字段中的行是否包含某个值


# Import the necessary modules
from  osgeo import ogr, osr

driver = ogr.GetDriverByName('ESRI Shapefile')
shp = driver.Open(r'C:\your\shapefile.shp')

# Get Projection from layer
layer = shp.GetLayer()
spatialRef = layer.GetSpatialRef()
print spatialRef

# Get Shapefile Fields and Types
layerDefinition = layer.GetLayerDefn()

print "Name  -  Type  Width  Precision"
for i in range(layerDefinition.GetFieldCount()):
    fieldName =  layerDefinition.GetFieldDefn(i).GetName()
    fieldTypeCode = layerDefinition.GetFieldDefn(i).GetType()
    fieldType = layerDefinition.GetFieldDefn(i).GetFieldTypeName(fieldTypeCode)
    fieldWidth = layerDefinition.GetFieldDefn(i).GetWidth()
    GetPrecision = layerDefinition.GetFieldDefn(i).GetPrecision()
    print fieldName + " - " + fieldType+ " " + str(fieldWidth) + " " + str(GetPrecision)

# Check if rows in attribute table meet some condition
inFeature = layer.GetNextFeature()
while inFeature:

    # get the cover attribute for the input feature
    cover = inFeature.GetField('cover')

    # check to see if cover == grass
    if cover == 'trees':
        print "Do some action..."

    # destroy the input feature and get a new one
    inFeature = None
    inFeature = inLayer.GetNextFeature()


评论


虽然不是大问题,但是某些对象包含Destroy()方法,但是您永远不要使用它

– Mike T
16年12月13日在20:24

感谢您对@MikeT的见识。 GDAL / OGR文档在其整个食谱中均使用“ Destroy()”方法。您认为该方法有哪些问题?

–亚伦♦
16 Dec 14 '17:28



在某些情况下,当您使用Destroy()时可能会发生段错误,并且在绑定中公开此方法是一个设计错误。更好的方法是取消引用GDAL对象,例如inFeature = None。 GDAL / OGR食谱不属于GDAL / OGR核心团队,也不由GDAL / OGR核心团队编写。

– Mike T
16年12月14日在23:12

@MikeT我已经编辑了帖子,以包含您的评论-谢谢。

–亚伦♦
16 Dec 15'在20:04

#2 楼

有许多模块可以读取Python中的shapefile,其版本早于ArcPy,请查看Python软件包索引(PyPi):shapefile。 GIS SE中也有许多示例(例如,搜索[Python] Fiona)

所有人都可以读取几何图形,字段和投影。


较老的是osgeo(GDAL / OGR),请查看Python GDAL / OGR Cookbook例如。另一个解决方案是Fiona,它也基于GDAL / OGR,但更易于使用(使用Python词典:GeoJSON格式)。
pyshp(shapefile)是一个纯Python解决方案。

GeoPandas使用Fiona读取/写入shapefile和Pandas,用于数据分析工具。您需要了解熊猫才能使用它。

但是PySAL等其他模块:Python空间分析库,Cartopy(使用pyshp)或Matplotlib底图等也可以读取shapefile。

最容易使用是Fiona,但如果您只知道ArcPy,请使用pyshp,因为osgeo和Fiona要求安装GDAL C / C ++库,因此GeoPandas需要Pandas模块,而PySAL太大(很多其他方法)

如果您只想读取shapefile的内容,则不需要复杂的东西,只需使用同样在ArcPy(ArcPy:AsShape)中实现的地理接口协议(GeoJSON)

Fiona(作为Python字典):

import fiona
with fiona.open('a_shape.shp') as shp:
     # schema of the shapefile
     print shp.schema
     {'geometry': 'Point', 'properties': OrderedDict([(u'DIP', 'int:2'), (u'DIP_DIR', 'int:3'), (u'TYPE', 'str:10')])}
     # projection
     print shp.crs
     {u'lon_0': 4.367486666666666, u'ellps': u'intl', u'y_0': 5400088.438, u'no_defs': True, u'proj': u'lcc', u'x_0': 150000.013, u'units': u'm', u'lat_2': 49.8333339, u'lat_1': 51.16666723333333, u'lat_0': 90}
     for feature in shp:
        print feature              
{'geometry': {'type': 'Point', 'coordinates': (272070.600041, 155389.38792)}, 'type': 'Feature', 'id': '0', 'properties': OrderedDict([(u'DIP', 30), (u'DIP_DIR', 130), (u'TYPE', u'incl')])}
{'geometry': {'type': 'Point', 'coordinates': (271066.032148, 154475.631377)}, 'type': 'Feature', 'id': '1', 'properties': OrderedDict([(u'DIP', 55), (u'DIP_DIR', 145), (u'TYPE', u'incl')])}
{'geometry': {'type': 'Point', 'coordinates': (273481.498868, 153923.492988)}, 'type': 'Feature', 'id': '2', 'properties': OrderedDict([(u'DIP', 40), (u'DIP_DIR', 155), (u'TYPE', u'incl')])}


与pyshp(作为Python字典)

import shapefile
reader= shapefile.Reader("a_shape.shp")
# schema of the shapefile
print dict((d[0],d[1:]) for d in reader.fields[1:])
{'DIP_DIR': ['N', 3, 0], 'DIP': ['N', 2, 0], 'TYPE': ['C', 10, 0]}
fields = [field[0] for field in reader.fields[1:]]
for feature in reader.shapeRecords():
    geom = feature.shape.__geo_interface__
    atr = dict(zip(fields, feature.record))
    print geom, atr
{'type': 'Point', 'coordinates': (272070.600041, 155389.38792)} {'DIP_DIR': 130, 'DIP': 30, 'TYPE': 'incl'}
{'type': 'Point', 'coordinates': (271066.032148, 154475.631377)} {'DIP_DIR': 145, 'DIP': 55, 'TYPE': 'incl'}
{'type': 'Point', 'coordinates': (273481.498868, 153923.492988)} {'DIP_DIR': 155, 'DIP': 40, 'TYPE': 'incl'}


与osgeo / ogr(作为Python词典)

from osgeo import ogr
reader = ogr.Open("a_shape.shp")
layer = reader.GetLayer(0)
for i in range(layer.GetFeatureCount()):
    feature = layer.GetFeature(i)
    print feature.ExportToJson()
{"geometry": {"type": "Point", "coordinates": [272070.60004, 155389.38792]}, "type": "Feature", "properties": {"DIP_DIR": 130, "DIP": 30, "TYPE": "incl"}, "id": 0}
{"geometry": {"type": "Point", "coordinates": [271066.032148, 154475.631377]}, "type": "Feature", "properties": {"DIP_DIR": 145, "DIP": 55, "TYPE": "incl"}, "id": 1}
{"geometry": {"type": "Point", "coordinates": [273481.49887, 153923.492988]}, "type": "Feature", "properties": {"DIP_DIR": 155, "DIP": 40, "TYPE": "incl"}, "id": 2}


与GeoPandas(作为Pandas数据框)

import geopandas as gp
shp = gp.GeoDataFrame.from_file('a_shape.shp')
print shp
        DIP_DIR    DIP  TYPE                       geometry
0         130       30  incl          POINT (272070.600041 155389.38792)
1         145       55  incl          POINT (271066.032148 154475.631377)
2         155       40  incl          POINT (273481.498868 153923.492988)


*注意在geopandas上
您必须使用较早版本的Fiona和GDAL,否则它将无法安装。
GDAL:1.11.2
菲奥纳:1.6.0
Geopandas:0.1.0.dev-

网上有很多教程,甚至还有书籍(Python地理空间开发,正在使用Python学习地理空间分析和使用Python进行地理处理)

更一般而言,如果您想在没有ArcPy的情况下使用Python,请查看使用Python对shapefile进行简单的专题映射?

评论


请注意,Fiona的主页显示GIS中的数据种类大致分为代表连续标量场(例如,地表温度或海拔)的栅格和代表离散实体(如道路和行政边界)的向量。 Fiona仅关注后者

–莫格说要恢复莫妮卡
16-09-21在9:52

显然,问题是关于shapefile而不是栅格。它们是栅格文件的其他模块。

–基因
16-09-21在15:19

好答案! 2017年有什么更新吗?

–迈克尔
17年12月2日在7:56

#3 楼

除了ArcPy之外,还有地理空间Python库将为您提供这些功能。这是两个示例:

Python Shapefile库(pyshp)

GeoPandas

如果您对其他库感兴趣,那么这篇关于基本库Python Geospatial库是一个不错的地方。