2011-01-04 7 views
5

私はESRIシェイプファイルを持っています(ここから:http://pubs.usgs.gov/ds/425/)。私は、指定された緯度/経度でシェイプファイル(この場合は表面的なマテリアル)から情報を検索するためにpythonを使用したいと考えています。ESRIシェイプファイル内の特定の緯度/経度で情報を検索するためにpythonを使用するにはどうすればよいですか?

この問題を解決する最善の方法は何ですか?

ありがとうございました。

最終的な解決策:

#!/usr/bin/python 

from osgeo import ogr, osr 

dataset = ogr.Open('./USGS_DS_425_SHAPES/Surficial_materials.shp') 
layer = dataset.GetLayerByIndex(0) 
layer.ResetReading() 

# Location for New Orleans: 29.98 N, -90.25 E 
point = ogr.CreateGeometryFromWkt("POINT(-90.25 29.98)") 

# Transform the point into the specified coordinate system from WGS84 
spatialRef = osr.SpatialReference() 
spatialRef.ImportFromEPSG(4326) 
coordTransform = osr.CoordinateTransformation(
     spatialRef, layer.GetSpatialRef()) 

point.Transform(coordTransform) 

for feature in layer: 
    if feature.GetGeometryRef().Contains(point): 
     break 

for i in range(feature.GetFieldCount()): 
    print feature.GetField(i) 
+0

ポイントが「フィーチャー」のいずれにも見つからない場合、最後のフィーチャーはマッチとして扱われ(フィールドが印刷されます)。私は別の変数 'matched_feature'を宣言し、' break'の直前にそれを代入し、 'feature'変数の代わりに次のループのために使用します。 –

答えて

2

gdal/ogrツールキットに対するPythonバインディングを使用できます。ここでは例です:

from osgeo import ogr 

ds = ogr.Open("somelayer.shp") 
lyr = ds.GetLayerByName("somelayer") 
lyr.ResetReading() 

point = ogr.CreateGeometryFromWkt("POINT(4 5)") 

for feat in lyr: 
    geom = feat.GetGeometryRef() 
    if geom.Contains(point): 
     sm = feat.GetField(feat.GetFieldIndex("surface_material")) 
     # do stuff... 
+0

ありがとう、私はこの解決策を見ていきます。 – arkottke

+0

緯度/経度からシェイプファイルで使用される参照システムへの座標変換が必要なため、ポイントを指定するのが難しいです。私はこれがgdalツールキットのどこかにあると仮定していますが、それを見つけることができないようです...まだ。 – arkottke

+0

osgeo.osr.SpatialReferenceとgeom.Transform()(IIRC)を調べてください。私は明日(afk)の例を更新します – albertov

3

アウトPython Shapefile Library

これは、ジオメトリと異なる情報を与える必要があります。

+0

はい、それはジオメトリを提供しますが、ポイントが指定されたジオメトリ内にあるかどうかを確認します。 – arkottke

2

別のオプションは、格好の良い(GEOS、PostGISのためのエンジンをベースにPythonライブラリ)と(ファイルを書き込む/読み取るため、基本的です)フィオナを使用することです:

import fiona 
import shapely 

with fiona.open("path/to/shapefile.shp") as fiona_collection: 

    # In this case, we'll assume the shapefile only has one record/layer (e.g., the shapefile 
    # is just for the borders of a single country, etc.). 
    shapefile_record = fiona_collection.next() 

    # Use Shapely to create the polygon 
    shape = shapely.geometry.asShape(shapefile_record['geometry']) 

    point = shapely.geometry.Point(32.398516, -39.754028) # longitude, latitude 

    # Alternative: if point.within(shape) 
    if shape.contains(point): 
     print "Found shape for point." 

ポリゴンが大きく/複雑な場合(ポリゴンが極端に不規則な海岸線を持ついくつかの国のシェイプファイルなど)、ポイントポリゴンテストを行うことはコストがかかることに注意してください。それはすぐに、より集中的なテストを行う前に、物事を除外するために境界ボックスを使用するように助けることができるいくつかのケースでは:

minx, miny, maxx, maxy = shape.bounds 
bounding_box = shapely.geometry.box(minx, miny, maxx, maxy) 

if bounding_box.contains(point): 
    ... 

最後に、残念ながら(それは大/不規則なシェープファイルをロードし、解析に時間がかかることに注意してくださいこれらのタイプのポリゴンは、しばしばメモリに保存するのに高価です)。

+0

[fiona](https://pypi.python.org/pypi/Fiona)を指摘してくれてありがとう、すばらしいパッケージのようです。 – arkottke

関連する問題