เป็นไปได้หรือไม่ที่จะดูเนื้อหาของ Shapefile โดยใช้ Python ที่ไม่มีลิขสิทธิ์ ArcMap?


40

ฉันสงสัยว่ามันเป็นไปได้ที่จะดูเนื้อหาของ shapefile โดยใช้ Python โดยไม่ต้องมีและสิทธิ์การใช้งาน ArcMap สถานการณ์คือคุณสามารถสร้าง shapefiles จากหลาย ๆ แอปพลิเคชั่นไม่เพียง แต่จากซอฟต์แวร์ ESRI ฉันต้องการสร้างสคริปต์ Python ที่ตรวจสอบการอ้างอิงเชิงพื้นที่ประเภทสถานที่ชื่อคุณลักษณะและคำจำกัดความและเนื้อหาของเขตข้อมูลในรูปแบบไฟล์และเปรียบเทียบกับชุดของค่าที่ยอมรับได้ ฉันต้องการให้สคริปต์นี้ทำงานแม้ว่าองค์กรจะไม่มีใบอนุญาต ESRI ในการทำสิ่งนี้คุณต้องใช้ ArcPy หรือคุณสามารถขุดลงในไฟล์รูปร่างโดยไม่ต้องใช้ ArcPy ได้หรือไม่?


1
มันขึ้นอยู่กับความพยายามเท่าใดคุณต้องการที่จะใส่ลงไปในมัน .. มีหลายห้องสมุดมาเปิดที่จะช่วยให้ (ผมชอบ OGR ตามคำตอบ Aarons') แต่ถ้าคุณจริงๆต้องการควบคุม (และกำลังเตรียมที่จะทำงานให้มัน) เดอะ Shapefile (สร้างสรรค์โดย Esri) เป็นรูปแบบเปิดดูen.wikipedia.org/wiki/Shapefile
Michael Stimson

1
ล่าสุด (สองสามปีที่ผ่านมา) รูปร่าง ESRI ถูกซ่อนอยู่ในรูปแบบฐานข้อมูลใหม่ ดูเหมือนว่าไม่มีอะไรสามารถทำลายพวกเขาได้ยกเว้นซอฟต์แวร์ ARCxxx หน่วยงานสาธารณะหลายแห่งใช้ข้อมูลนี้เพื่อเป็นข้อมูลสาธารณะ ... น่าละอาย

คำตอบ:


34

ฉันขอแนะนำให้ทำความคุ้นเคยกับ Python GDAL / OGR API เพื่อทำงานกับทั้งเวกเตอร์และข้อมูลแรสเตอร์ วิธีที่ง่ายที่สุดที่จะเริ่มใช้ GDAL / OGR ผ่านการกระจายหลามเช่นงูหลาม (x, y) , งูหรือOSGeo4W

รายละเอียดเพิ่มเติมเกี่ยวกับการใช้ GDAL สำหรับงานเฉพาะของคุณ:

นอกจากนี้ฉันขอแนะนำบทแนะนำต่อไปนี้จาก USU เพื่อให้คุณเริ่มต้น


การยืมจากตัวอย่างด้านบนสคริปต์ต่อไปนี้ใช้เครื่องมือ FOSS เพื่อดำเนินการต่อไปนี้:

  1. ตรวจสอบการอ้างอิงเชิงพื้นที่
  2. รับฟิลด์และประเภท shapefile
  3. ตรวจสอบว่าแถวในเขตข้อมูลที่ผู้ใช้กำหนดมีค่าบางอย่างหรือไม่

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


ขอบคุณสำหรับความเข้าใจ @MikeT เอกสารประกอบของ GDAL / OGR ใช้วิธีการ 'ทำลาย ()' ตลอดตำราอาหาร คุณเห็นปัญหาอะไรเกี่ยวกับวิธีการนั้น
แอรอน

1
มีหลายสถานการณ์ที่ segfaults อาจเกิดขึ้นเมื่อคุณใช้ Destroy () และเป็นความผิดพลาดในการออกแบบเพื่อแสดงวิธีการนี้ในการโยง วิธีการที่ดีคือการ dereference วัตถุ GDAL inFeature = Noneเช่น ตำราอาหารของ GDAL / OGR ไม่ได้เป็นส่วนหนึ่งของหรือเขียนโดยทีมหลักของ GDAL / OGR
Mike T

@MikeT ฉันได้แก้ไขโพสต์เพื่อรวมความคิดเห็นของคุณ - ขอบคุณ
แอรอน

31

มีโมดูลจำนวนมากเพื่อ shapefiles อ่านในหลาม, เก่ากว่า ArcPy, ดูที่มีเชปไฟล์: งูหลามแพ็คเกจดัชนี (PyPi) นอกจากนี้ยังมีตัวอย่างมากมายใน GIS SE (ค้นหา[Python] Fionaเป็นต้น)

ทุกคนสามารถอ่านรูปทรงเรขาคณิตฟิลด์และเส้นโครง

  • พี่เป็นosgeo (GDAL / OGR) , ดูที่หลาม GDAL / OGR ตำราตัวอย่างเช่น
  • อีกวิธีคือFionaซึ่งอิงกับ GDAL / OGR แต่ใช้ง่ายกว่า (ด้วยพจนานุกรม Python: รูปแบบ GeoJSON)
  • pyshp (shapefile)เป็นโซลูชัน Python ที่แท้จริง
  • GeoPandasใช้Fionaเพื่ออ่าน / เขียน shapefiles และPandasสำหรับเครื่องมือวิเคราะห์ข้อมูล คุณต้องรู้จักนุ่นเพื่อที่จะใช้มัน

แต่โมดูลอื่น ๆ เช่นPySAL: Python Spatial Analysis Library , Cartopy (ซึ่งใช้pyshp ) หรือMatplotlib Basemapยังสามารถอ่าน shapefiles เหนือสิ่งอื่นใด

วิธีที่ง่ายที่สุดในการใช้คือFionaแต่ถ้าคุณรู้จัก ArcPy ให้ใช้pyshpเนื่องจากosgeoและFionaต้องการให้ติดตั้งไลบรารีGDAL C / C ++, GeoPandasต้องการโมดูลPandasและPySALมีขนาดใหญ่เกินไป (การรักษาอื่น ๆ อีกมากมาย)

หากคุณเพียงต้องการอ่านเนื้อหาของ shapefile คุณไม่ต้องการสิ่งที่ซับซ้อนเพียงใช้โปรโตคอลอินเตอร์เฟสทางภูมิศาสตร์ (GeoJSON) ที่ใช้ใน ArcPy ( ArcPy: AsShape )

ด้วย 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 Fiona: 1.6.0 Geopandas: 0.1.0.dev-

มีบทเรียนมากมายบนเว็บและแม้กระทั่งหนังสือ ( การพัฒนา Python Geospatial , การเรียนรู้การวิเคราะห์เชิงพื้นที่ด้วย Pythonและการประมวลผลทางภูมิศาสตร์กับ Pythonในการกด)

โดยทั่วไปหากคุณต้องการใช้ Python โดยไม่ต้องใช้ ArcPy ให้ดูที่การแมปไฟล์แบบง่าย ๆ เฉพาะเรื่องของ shapefile โดยใช้ Python


โปรดทราบว่าหน้าหลักของฟิโอน่าบอกว่าThe kinds of data in GIS are roughly divided into rasters representing continuous scalar fields (land surface temperature or elevation, for example) and vectors representing discrete entities like roads and administrative boundaries. Fiona is concerned exclusively with the latter
Mawg

2
เห็นได้ชัดว่าคำถามเกี่ยวกับ shapefiles ไม่ใช่ rasters พวกเขาเป็นโมดูลอื่น ๆ สำหรับไฟล์แรสเตอร์
ยีน

คำตอบที่ดี! มีอะไรที่จะอัพเดทในปี 2560?
Michael

11

มีคลัง Python ในเชิงพื้นที่นอกเหนือจาก ArcPy ที่จะให้ความสามารถเหล่านี้แก่คุณ นี่คือสองตัวอย่าง:

Python Shapefile Library (pyshp)

GeoPandas

หากคุณสนใจห้องสมุดอื่น ๆโพสต์นี้เกี่ยวกับห้องสมุด Python Geospatial ที่สำคัญนั้นเหมาะสำหรับการดู


1
+1 สำหรับ pyshp สุดยอดใช้งานง่ายและตรงไปตรงมา ฟังดูเหมือนทุกสิ่งที่ OP ต้องการจะได้รับการดูแล
mr.adam
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.