Có thể xem nội dung của Shapefile bằng Python mà không cần giấy phép ArcMap không?


40

Tôi tự hỏi liệu có thể xem nội dung của một shapefile bằng Python mà không cần có giấy phép ArcMap không. Tình huống là bạn có thể tạo shapefiles từ nhiều ứng dụng khác nhau, không chỉ từ phần mềm ESRI. Tôi muốn tạo một tập lệnh Python để kiểm tra tham chiếu không gian, loại tính năng, tên thuộc tính và định nghĩa và nội dung của các trường trong một shapefile và so sánh chúng với một tập hợp các giá trị chấp nhận được. Tôi muốn tập lệnh này hoạt động ngay cả khi tổ chức không có bất kỳ giấy phép ESRI nào. Để làm một cái gì đó như thế này, bạn có phải sử dụng ArcPy hoặc bạn có thể đào vào một shapefile mà không cần sử dụng ArcPy?


1
Nó phụ thuộc vào mức độ nỗ lực mà bạn muốn dành cho nó .. có một số thư viện nguồn mở sẽ giúp ích (tôi thích OGR theo câu trả lời của Aarons) nhưng nếu bạn thực sự muốn kiểm soát (và sẵn sàng làm việc cho nó) thì Shapefile (ban đầu bởi Esri) là một định dạng mở, xem en.wikipedia.org/wiki/Shapefile
Michael Promotionson

1
Các shapefile ESRI gần đây (vài năm gần đây) được ẩn trong định dạng cơ sở dữ liệu địa lý mới của chúng. Dường như không có gì có thể phá vỡ chúng ngoại trừ phần mềm ARCxxx. Nhiều cơ quan công cộng đang sử dụng nó cho thông tin công cộng ... xấu hổ.

Câu trả lời:


34

Tôi khuyên bạn nên làm quen với API Python GDAL / OGR để làm việc với cả dữ liệu vectơ và raster. Cách dễ nhất để bắt đầu sử dụng GDAL / OGR là thông qua phân phối python như python (x, y) , Anaconda hoặc OSGeo4W .

Thông tin chi tiết về cách sử dụng GDAL cho các nhiệm vụ cụ thể của bạn:

Ngoài ra, tôi muốn giới thiệu hướng dẫn sau từ USU để giúp bạn bắt đầu.


Mượn từ các ví dụ trên, tập lệnh sau sử dụng các công cụ FOSS để thực hiện các hành động sau:

  1. Kiểm tra tham chiếu không gian
  2. Nhận các trường và kiểu shapefile
  3. Kiểm tra xem các hàng trong trường do người dùng xác định có chứa một số giá trị không

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


Cảm ơn vì cái nhìn sâu sắc @MikeT. Tài liệu GDAL / OGR sử dụng phương pháp 'Phá hủy ()' trong toàn bộ sách dạy nấu ăn của họ. Những vấn đề bạn thấy với phương pháp đó?
Aaron

1
Có những tình huống mà segfaults có thể xảy ra khi bạn sử dụng Dest () và đó là một lỗi thiết kế để phơi bày phương thức này trong các ràng buộc. Một phương pháp tốt hơn là để hủy bỏ các đối tượng GDAL như thế nào inFeature = None. Sách dạy nấu ăn GDAL / OGR không phải là một phần hoặc được viết bởi nhóm nòng cốt GDAL / OGR.
Mike T

@MikeT Tôi đã chỉnh sửa bài đăng để đưa ý kiến ​​của bạn - cảm ơn.
Aaron

31

Có nhiều mô-đun để đọc shapefiles trong Python, cũ hơn ArcPy, hãy xem Chỉ số gói Python (PyPi): shapefiles . Ngoài ra còn có nhiều ví dụ trong GIS SE (ví dụ tìm kiếm [Python] Fiona )

Tất cả đều có thể đọc hình học, các trường và các hình chiếu.

Nhưng các mô-đun khác như PySAL: Thư viện phân tích không gian Python , Cartopy (sử dụng pyshp ) hoặc Matplotlib Basemap cũng có thể đọc shapefiles, trong số những thứ khác.

Cách dễ sử dụng nhất là Fiona , nhưng nếu bạn chỉ biết ArcPy, hãy sử dụng pyshp , vì osgeoFiona yêu cầu thư viện GDAL C / C ++ phải được cài đặt, GeoPandas cần mô-đun PandasPySAL quá lớn (nhiều, rất nhiều cách xử lý khác)

Nếu bạn chỉ muốn đọc nội dung của một shapefile, bạn không cần những thứ phức tạp, chỉ cần sử dụng giao thức giao diện địa lý (GeoJSON) cũng được triển khai trong ArcPy ( ArcPy: AsShape )

Với Fiona (như từ điển 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')])}

Với pyshp (như từ điển 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'}

Với osgeo / ogr (như từ điển 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}

Với GeoPandas (dưới dạng khung dữ liệu 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)

* lưu ý trên geopandas Bạn phải sử dụng các phiên bản cũ hơn của Fiona và GDAL với nó nếu không nó sẽ không được cài đặt. GDAL: 1.11.2 Fiona: 1.6.0 Công viên địa chất: 0.1.0.dev-

Có rất nhiều hướng dẫn trên Web và thậm chí cả sách ( Phát triển không gian địa lý Python , Phân tích không gian địa lý học với PythonGeoprocessing với Python , trên báo chí)

Tổng quát hơn, nếu bạn muốn sử dụng Python mà không có ArcPy, hãy xem ánh xạ chủ đề đơn giản của shapefile bằng Python?


Lưu ý rằng trang chính của Fiona nóiThe 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
Bằng chứng, câu hỏi là về shapefiles và không raster. Chúng là các mô-đun khác cho các tệp raster.
gen

Câu trả lời chính xác! Bất cứ điều gì để cập nhật trong năm 2017?
Michael

11

Có các thư viện Python không gian địa lý bên cạnh ArcPy sẽ cung cấp cho bạn các khả năng này. Đây là hai ví dụ:

Thư viện Shapefile Python (pyshp)

GeoPandas

Nếu bạn quan tâm đến các thư viện khác, bài đăng này trên các thư viện không gian địa lý Python cần thiết là một nơi tốt để xem xét.


1
+1 cho pyshp, siêu dễ sử dụng và đơn giản. Âm thanh như mọi thứ mà OP muốn sẽ được cung cấp.
mr.adam
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.