ogrとPythonを使用したポリゴン内の(ラインストリングの)ポイント


10

私は現在、シェープファイルにあるジオメトリ機能からトポロジーネットワークを構築する必要があるプロジェクトに取り組んでいます。これまでのところ、Ben Reillyのオープンソースプロジェクトを使用して、ラインストリングをnetworkxエッジに変換し、近接フィーチャ(他のラインストリングが言う)を検出して、それらを最も近いポイントに追加して、最短パスアルゴリズムを実行できるようにしました。

しかし、これは1つのシェープファイルでは問題ありません。ただし、ここで、さまざまなシェープファイルの機能を大きなnetworkxグラフに接続する必要があります。したがって、たとえば、ポイントがポリゴン内にある場合、それを接続します(接続するとは、次のシェープファイル内のポイントでnetworkxエッジ-add_edge(g.GetPoint(1)、g.GetPoint(2)を追加することを意味します)。も同様の属性(IDなど)を共有するポリゴン内にあります。異なるshp内のポリゴンは、座標ではなく同じIDのみを共有することに注意してください。ポリゴン内にあるポイントも同じ座標を共有しません。

この問題に対する私の解決策は、ポリゴンに存在するポイントを特定して保存し、同じIDを持つポリゴンに存在する次のシェープファイルでポイントを見つけて、それらの間にnetworkxエッジを追加することでした。

ポイントがポリゴン内にあるかどうかを確認するにはどうすればよいですか?よく知られているアルゴリズムがあります。それを行うRayCastingアルゴリズムです。アルゴリズムを実装するためにはポリゴンの座標が必要であり、OGRのジオメトリのドキュメントをざっと見てみた後でも、それらにアクセスする方法が今はわからないので、ここで実際に行き詰まりました。それで、私が質問している質問は、ポリゴンポイントまたは座標にアクセスする方法です。または、ポイントがポリゴン内にあるかどうかを検出する簡単な方法はありますか?osgeo.ogrライブラリでPythonを使用して、次のコードを記述しました。

 if g.GetGeometryType() == 3: #polygon
                c = g.GetDimension()
                x = g.GetPointCount()
                y = g.GetY()
                z = g.GetZ()

私の問題のより良い理解のために画像を見てください。 代替テキスト

[編集] これまでのところ、すべてのポリゴンオブジェクトをリストに保存して、線ストリングの最初と最後のポイントを比較してみました。ただし、Paoloの例は、ポイントオブジェクト参照とポリゴンオブジェクト参照の使用に関連しています。これは、ライン全体がポリゴン内ではなく、ラインストリングの最初または最後のポイント内にあるため、ラインオブジェクト参照では機能しません。

[編集3]ラインストリング の最初と最後のポイントの座標から新しいジオメトリポイントオブジェクトを作成し、それを使用してリストに保存されたポリゴンジオメトリオブジェクトと比較すると、問題なく動作するようです。

for findex in xrange(lyr.GetFeatureCount()):
    f = lyr.GetFeature(findex)
    flddata = getfieldinfo(lyr,f,fields)
    g = f.geometry()
    if g.GetGeometryType() == 2:
        for j in xrange(g.GetPointCount()):
            if j == 0 or j == g.GetPointCount():
                point = ogr.Geometry(ogr.wkbPoint)
                point.AddPoint(g.Getx(j),g.GetY(j))
                if point.Within(Network.polygons[x][0].GetGeometryRef()):
    print g.GetPoint(j)

ヒントを提供してくれたPaoloChrisに感謝します。

回答:


11

Shapelyはクールでエレガントですが、空間演算子(OGRGeometryクラス内)を備えたogrを使用しないのはなぜですか?

サンプルコード:

from osgeo import ogr
driver = ogr.GetDriverByName('ESRI Shapefile')
polyshp = driver.Open('/home/pcorti/data/shapefile/multipoly.shp')
polylyr = polyshp.GetLayer(0)
pointshp = driver.Open('/home/pcorti/data/shapefile/point.shp')
pointlyr = pointshp.GetLayer(0)
point = pointlyr.GetNextFeature()
polygon = polylyr.GetNextFeature()
point_geom = point.GetGeometryRef()
polygon_geom = polygon.GetGeometryRef()
print point_geom.Within(polygon_geom)

GEOSサポートを使用してGDALをコンパイルする必要があることに注意してください。


grzie Paolo、しかし私が本当に必要なのは、ポイントのオブジェクトリファレンスをポリゴンのオブジェクトリファレンスと比較することではなく、現在GetPointでアクセスしているラインストリングの最後と最初のポイントを比較することです。気づいたGetPointRefはありません。それを実装するにはどうすればよいですか?
user39901230

1
ラインストリングは、ポイント(頂点)の反復可能なジオメトリコレクションであり、最初と最後に簡単にアクセスできます。
capooti '23年

ポリゴンオブジェクトをリストに保存しようとしましたが、後でこれを使用して、ラインストリングの最初と最後のポイントをチェックします。ただし、何らかの理由により、ポリゴン内のポイントのリストにポイントが追加されていません。ここをご覧ください:codepad.org/Cm2BV5mp
user39901230

8

私はnetworkxに精通していませんが、あなたの質問を正しく理解していれば、shapelyおよびOGR libを使用して、シェープファイルからポリゴン内のポイントを見つけることができます。これは、1つのシェープファイルからのポリゴンで1つのポイント(2000,1200)が失敗した場合の検索方法の1つの例です。結果として、そのポリゴンの座標が出力されます。

from shapely.geometry import Point, Polygon
from shapely.wkb import loads
from osgeo import ogr

file1 = ogr.Open("d:\\fileWithData.shp")
layer1 = file1.GetLayerByName("fileWithData")

point1 = Point(2000,1200)

polygon1 = layer1.GetNextFeature()

while polygon1 is not None:
    geomPolygon = loads(polygon1.GetGeometryRef().ExportToWkb())
    if geomPolygon.contains(point1):
        xList,yList = geomPolygon.exterior.xy
        print xList
        print yList
    polygon1 = layer1.GetNextFeature()

お役に立てば幸いです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.