shapelyの使用:ポリゴンとマルチポリゴン間の変換


12

[編集:これに対する解決策は、OGRを使用してシェープファイルを読み取ることでした。geographikaの例を参照してください。]

ESRIシェープファイルでは、ポリゴンとマルチポリゴンを区別しません。さらに、内部の穴と外部のリングの間に明確な区別はありません(特定のポリゴンの「利き手」以外)。

したがって、シェープファイルを読み込んだ後、リングを記述する座標シーケンスのリストがありますが、いくつかのより集中的な処理なしでは、これらのリングのどれが外部リング、内部穴、または追加のポリゴンであるかを区別できません。

のためと思わスッキリポリゴンとMultiPolygonのコンストラクタs」は、外部と内部リング間の明確な区別がなければならないので、どのように私は明らかに指定された内部と外部リングで、分離ポリゴンの順序集合にリングの不明瞭リストから移動する必要があります?

要約すると、ポリゴンリングのリストはあるが、どのリングが内部の穴であるか、または個別のポリゴンであるかわからない場合、指定された内部の穴を持つ個別のポリゴンにどのように分類すればよいですか?

私はPythonで実装でき、数百のポリゴンを1分以内に処理するために使用できる簡単なアルゴリズムソリューションを探しています。そして、私はこれをして多数の交差を実行します。


この質問には、シェープファイルの読み取りに使用するものに関する重要な情報が欠落しています。
inc42

@ inc42 pythonを使用してファイルを直接読み取りました。
ベンジャミン

ああ、Shapelyビットは誤解を招きます。実際の問題は、シェイプファイル形式でリングの「種類」を判断する方法を見つけることでした。:)
inc42

回答:


10

さらに、個々のポリゴンを取得する方法についての回答に加えて、すべてのポリゴンで交差を実行して穴を作成できます。データセットに重複するポリゴンが含まれている場合でも、運が悪い。

既存のシェープファイルリーダーの何が問題なのか、もう一度説明してください。

シェープファイルからフィーチャIDとM値をエクスポートし、既存のシェープファイルリーダーを使用した後、それらをポリゴンに結合するのは簡単ではないでしょうか?

マルチパッチの場合は、ポリゴンIDを「パッチID」に割り当ててから、この属性をフィーチャに追加するという同じ手法を使用できます。

編集:気が変わった場合に備えて、OGRを使用したくないと言いますが..

import ogr
# Get the driver
driver = ogr.GetDriverByName('ESRI Shapefile')
# Open a shapefile
shapefileName = "D:/temp/myshapefile.shp"
dataset = driver.Open(shapefileName, 0)

layer = dataset.GetLayer()
for index in xrange(layer.GetFeatureCount()):
    feature = layer.GetFeature(index)
    geometry = feature.GetGeometryRef()
    #geometry for polygon as WKT, inner rings, outer rings etc. 
    print geometry

ジオメトリは次のように出力されます。

POLYGON ((79285 57742,78741 54273...),(76087 55694,78511 55088,..))

最初のブラケットには外部リングの座標が含まれ、後続のブラケットには内部リングの座標が含まれます。Z値がある場合、ポイントの形式は79285 57742 10(最後の座標は高さ)でなければなりません。

-そうでなければ、格好の良いが、お互いにすべてのポリゴンを評価し、事前に空間インデックスを適用することが含まれており、関数内で使用することができhttp://pypi.python.org/pypi/Rtree/処理をスピードアップします。


おかげで、これは私が探しているものではありませんが、質問に対してさらに明確な説明を見つけました。あなたの質問に答えるには:1、そもそも大量の交差点を作成するためにそれらをソートしているからです。2、何も、私は軽量であり、Pythonから簡単に使用できるものが必要です、そして私はogrを学んでいません。3、いいえ、この場合は簡単ではありません。
ベンジャミン

1
うわー!ありがとう、geographika!私は今、90%がogrがここでの解決策であると確信しています。私はogrでいくつかのインストールの問題に遭遇しましたが、それらは解決する価値があるようです。ogrはwkt出力でリングを整理しますか?また、3Dシェープファイルでも問題ありませんか(3Dを多く使用します)?
ベンジャミン

私の質問に対する答えはイエスとイエスのようです。そして、rtreeを紹介してくれてありがとう。OGRは、今回インストールを正しく構成できる限り、私の問題を完全に解決しているように見えます。
ベンジャミン

OGRの再インストール-Windows用のバイナリとそれに対応するPythonバインディングが必要になることを忘れないでください。
geographika

9

まず、ogrを使用してシェープファイルを開きます。

from osgeo import ogr
source = ogr.Open("mpolys.shp")
layers =  source.GetLayerByName("mpoly")
len(layers)
1

シェープファイルのジオメトリを形の良いジオメトリに変換します

from shapely.wkb import loads
element=layers[0] #(because lenght of layer =1, else you need "for element in layers: ...")
geom = loads(element.GetGeometryRef().ExportToWkb())
geom.geom_type
'MultiPolygon'
print geom
MULTIPOLYGON ((..... # the geometry in shapely wkt format

マルチポリゴンのポリゴンの場合:

poly=[]
for pol in geom:
    poly.append(pol)
poly[0]
<shapely.geometry.polygon.Polygon object at 0x00B82CB0>
poly[0].geom_type
'Polygon'
print(poly[1])
POLYGON ((.... # the geometry in shapely wkt format

そして今、あなたはshapely(shapely)のすべての機能を使用することができます


1

ポリゴンがシェイプファイルに実際に格納される方法についてはあまり詳しくありませんが、開始座標が繰り返される場合にのみ、ポリゴンリングを閉ループにすべきではありませんか?したがって、後続の各座標を開始座標と比較すると、ポリゴンが閉じている最初のポイントが見つかります。それがポリゴンの最後の座標である場合、それは単純なポリゴンであり、そうでない場合、それはマルチポリゴンであり、他のループを処理する必要があります。

それはあなたが避けたい「より集中的な処理」かもしれませんが、とにかくそれらを読まなければならないときに無料でやってくるのは実際には座標の単なる反復です。


謝罪-私の質問は少し誤解を招くものだったので、編集しました。ポリゴンリングがあり、複数のポリゴンリングのリストがあるときは知っていますが、ポイントの時計回りまたは反時計回りの順序は別として、それらが内部リングであるか外部リングであるかはわかりません。それらが内部リングである場合、それらの位置を測定する以外に、それらがどの外部リングに属しているかを確認する方法がありません。
ベンジャミン

そうですか。また、あなたがOGRへの道を見つけたことを嬉しく思います。;)
24:11に再

-2

@ inc42示されているように、ESRI Shapefile技術説明の 8ページ目:ESRIホワイトペーパー--1998年7月(PDFの34ページ中12ページ目)では、ポリゴンレコードの内容について議論しています。

ポリゴンには複数の外側のリングが含まれる場合があります。頂点の順序またはリングの方向は、リングのどちら側がポリゴンの内部であるかを示します。


p.10には、「ポリゴンには複数の外部リングが含まれる場合があります。頂点の順序またはリングの向きは、リングのどちらの側がポリゴンの内部であるかを示しています。」
inc42

@ inc42はそれに応じて更新されましたが、ページ番号は8(または34のうち12)になるはずです。
PolyGeo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.