ArcMap 라이센스없이 Python을 사용하여 Shapefile의 내용을 볼 수 있습니까?


40

ArcMap 라이센스없이 Python을 사용하여 shapefile의 내용을 볼 수 있는지 궁금합니다. 상황은 ESRI 소프트웨어뿐만 아니라 다양한 응용 프로그램에서 셰이프 파일을 만들 수 있다는 것입니다. 공간 참조, 기능 유형, 속성 이름 및 정의 및 셰이프 파일의 필드 내용을 확인하고 허용 가능한 값 집합과 비교하는 Python 스크립트를 만들고 싶습니다. 조직에 ESRI 라이센스가없는 경우에도이 스크립트가 작동하기를 원합니다. 이와 같은 작업을 수행하려면 ArcPy를 사용해야합니까, 아니면 ArcPy를 사용하지 않고 모양 파일을 파헤칠 수 있습니까?


1
그것은 얼마나 많은 노력을 기울이고 있는지에 달려 있습니다. (아론의 대답에 따라 OGR을 좋아합니다) 도움이 될 몇 가지 오픈 소스 라이브러리가 있지만 실제로 제어를 원하고 (그리고 그것을 위해 준비가되어 있다면) Shapefile (원래 Esri) 공개 형식은 en.wikipedia.org/wiki/Shapefile
Michael Stimson

1
최근 (최근 2 년) ESRI shapefile은 새로운 지리 데이터베이스 형식으로 숨겨져 있습니다. ARCxxx 소프트웨어를 제외하고는 아무것도 깨뜨릴 수없는 것 같습니다. 많은 공공 기관이 공공 정보를 위해 그것을 사용하고 있습니다 ... 수치심.

답변:


34

벡터 및 래스터 데이터를 모두 사용하려면 Python GDAL / OGR API에 익숙해지는 것이 좋습니다 . GDAL / OGR 사용을 시작하는 가장 쉬운 방법은 python (x, y) , Anaconda 또는 OSGeo4W 와 같은 python 배포판을 사용하는 입니다.

특정 작업에 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 문서는 요리 책 전체에서 'Destroy ()'메소드를 사용합니다. 그 방법에 어떤 문제가 있습니까?
Aaron

1
Destroy ()를 사용할 때 segfault가 발생할 수있는 상황이 있으며, 바인딩에이 메소드를 노출시키는 것은 설계상의 실수였습니다. 더 나은 방법은과 같은 GDAL 객체를 역 참조하는 것 inFeature = None입니다. GDAL / OGR 요리 책은 GDAL / OGR 핵심 팀의 일원이 아니거나 GDAL / OGR 핵심 팀이 작성하지 않습니다.
Mike T

@MikeT 귀하의 의견을 포함하도록 게시물을 편집했습니다. 감사합니다.
Aaron

31

Python에서 ArcPy보다 오래된 shapefile을 읽는 많은 모듈이 있습니다 .PyPi (Python Package Index) : shapefiles를보십시오 . GIS SE에는 많은 예제가 있습니다 (예 : [Python] Fiona 검색 ).

모두 지오메트리, 필드 및 투영을 읽을 수 있습니다.

그러나 PySAL과 같은 다른 모듈 : Python Spatial Analysis Library , Cartopy ( pyshp 사용 ) 또는 Matplotlib Basemap 도 모양 파일을 읽을 수 있습니다.

가장 사용하기 쉬운이다 피오나 ,하지만 당신은 단지 ArcPy, 사용 알고있는 경우 pyshp을 하기 때문에, 를 OSGeo피오나는 해야 GDAL C / C ++ 라이브러리를 설치, GeoPandas이 필요 팬더의 모듈 및 PySAL가 너무 큰 (많은, 많은 다른 치료)

모양 파일의 내용 만 읽으려면 복잡한 것을 필요로하지 않고 ArcPy ( ArcPy : AsShape )로 구현 된 Geo 인터페이스 프로토콜 (GeoJSON)을 사용하면 됩니다.

피오나 (파이썬 사전) :

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)

* 지오 판다에 대한 참고 사항 이전 버전의 Fiona 및 GDAL을 함께 사용해야합니다. 그렇지 않으면 설치되지 않습니다. GDAL : 1.11.2 피오나 : 1.6.0 Geopandas : 0.1.0.dev-

웹과 책에 대한 많은 자습서가 있습니다 ( Python Geospatial Development , Python으로 지리 공간 분석 학습Python 으로 지오 프로세싱 )

좀 더 일반적으로 ArcPy없이 Python을 사용하려면 Python을 사용 하여 shapefile의 간단한 주제 매핑을 살펴보십시오 .


Fiona의 메인 페이지에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
분명히 문제는 래스터가 아닌 셰이프 파일에 관한 것입니다. 이들은 래스터 파일을위한 다른 모듈입니다.
유전자

좋은 답변입니다! 2017 년에 업데이트 할 것이 있습니까?
Michael

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.