ArcMapライセンスなしでPythonを使用してShapefileのコンテンツを表示することはできますか?


40

ArcMapライセンスがなくてもPythonを使用してシェープファイルの内容を見ることができるかどうか疑問に思いました。状況は、ESRIソフトウェアだけでなく、多くの異なるアプリケーションからシェープファイルを作成できることです。空間参照、フィーチャタイプ、属性名と定義、およびシェープファイルのフィールドの内容をチェックし、それらを許容値のセットと比較するPythonスクリプトを作成したいと思います。組織にESRIライセンスがない場合でも、このスクリプトが機能するようにします。このようなことを行うには、ArcPyを使用する必要がありますか、それともArcPyを使用せずにシェープファイルを掘り下げることができますか?


1
どれだけの労力を費やすかによって異なります。いくつかのオープンソースライブラリが役立ちます(Aaronsの回答によるとOGRが好きです)が、本当に制御が必要な場合(そして、そのための準備ができている場合) (元はEsriによる)オープン形式です。en.wikipedia.org/ wiki / Shapefileを
マイケルスティムソン

1
最近(過去数年)のESRIシェープファイルは、新しいジオデータベース形式に隠されています。ARCxxxソフトウェアを除いて、それらを破壊することはできないようです。多くの公的機関が公共情報のためにそれを使用しています...恥。

回答:


34

Python GDAL / OGR APIに精通して、ベクトルデータとラスターデータの両方を操作することをお勧めします。GDAL / OGRの使用を開始する最も簡単な方法は、python(x、y)Anaconda、またはOSGeo4Wなどのpythonディストリビューションを使用することです。

特定のタスクにGDALを使用する方法の詳細:

さらに、USUからの次のチュートリアルをお勧めします。


上記の例から借用して、次のスクリプトはFOSSツールを使用して次のアクションを実行します。

  1. 空間参照を確認してください
  2. シェープファイルのフィールドとタイプを取得する
  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()」メソッドを使用しています。その方法にはどのような問題がありますか?
アーロン

1
Destroy()を使用するとセグメンテーション違反が発生する場合があり、バインディングでこのメソッドを公開するのは設計ミスでした。より良い方法は、のようなGDALオブジェクトを逆参照することですinFeature = None。GDAL / OGRクックブックは、GDAL / OGRコアチームの一部ではなく、GDAL / OGRコアチームによって作成されたものでもありません。
マイクT

@MikeTコメントを含めるように投稿を編集しました。ありがとう。
アーロン

31

Pythonでは、ArcPyよりも古いシェープファイルを読み込むための多くのモジュールがあります。Python パッケージインデックス(PyPi):shapefilesを参照してください。GIS SEには多くの例もあります(たとえば、[Python] Fionaを検索してください)

すべての人がジオメトリ、フィールド、投影を読み取ることができます。

しかしなどの他のモジュールPySAL:Pythonの空間分析図書館Cartopy(使用pyshp)またはmatplotlibのベースマップは、他のものの間で、シェープファイルを読み取ることができます。

使用する最も簡単であるフィオナが、あなたが唯一のArcPy、使用知っていればpyshpをするので、OSGEOフィオナがあることが必要ですGDAL C / C ++ライブラリがインストールされ、GeoPandasが必要パンダのモジュールをしてPySALが大きすぎる(多くの、多くの他の治療法)

シェープファイルのコンテンツのみを読み取りたい場合は、複雑なものは必要ありません。ArcPy(ArcPy:AsShape)でも実装されているジオインターフェースプロトコル(GeoJSON)を使用するだけです

(Python辞書として)Fionaの場合:

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 Fiona:1.6.0 Geopandas:0.1.0.dev-

Webとさえ帳簿上の多くのチュートリアル(存在するPythonの地理空間の開発Pythonの持つ学習地理空間分析およびPythonの持つジオプロセシングはプレスで、)

より一般的には、ArcPyを使用せずにPythonを使用する場合は、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
明らかに、質問はラスターではなく、シェープファイルに関するものです。これらは、ラスターファイル用の他のモジュールです。
遺伝子

素晴らしい答えです!2017年に更新するものはありますか?
マイケル

11

これらの機能を提供するArcPy以外の地理空間Pythonライブラリがあります。以下に2つの例を示します。

Pythonシェープファイルライブラリ(pyshp)

ジオパンダ

他のライブラリに興味がある場合は、基本的なPython Geospatialライブラリに関するこの投稿を参照してください。


1
pyshpの+1、非常に簡単で使いやすい。OPが望むすべてのものが収容されるように聞こえます。
ミスターアダム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.