Pythonで複数のポリゴンの交差点を効率的に取得する


11

複数のポリゴンの交差点を取得したいです。Pythonのshapelyパッケージを使用すると、intersection関数を使用して2つのポリゴンの交差を見つけることができます。複数のポリゴンの交差を取得するための同様の効率的な機能はありますか?

これが私の意味を理解するためのコードスニペットです。

from shapely.geometry import Point

coord1 = ( 0,0 )
point1 = Point(coord1)
circle1 = point1.buffer(1)

coord2 = ( 1,1 )
point2 = Point(coord2)
circle2 = point2.buffer(1)

coord3 = ( 1,0 )
point3 = Point(coord3)
circle3 = point3.buffer(1) 

2つの円の交点はで見つけることができますcircle1.intersection(circle2)。で3つすべての円の交差点を見つけることができますcircle1.intersection(circle2).intersection(circle3)。ただし、このアプローチは、より多くのコードを必要とするため、多数のポリゴンに対応できません。任意の数のポリゴンを取り、それらの交差を返す関数が欲しいです。


おそらく、座標をディクショナリに保存し、itertoolsからのインポートの組み合わせを使用しながらループをループすることを考えています。私はすぐに掲載されます
ジギー

「それらの交差点」とはどういう意味ですか?少なくとも1つの他のポリゴンと交差するすべてのエリア、またはすべての入力が交差するエリアを意味しますか?
jpmc26

少なくとも1つではなく、すべてのポリゴンの交差を意味します。
破片

上記のことを明確にする必要があります(おそらく出力例を使用して)。答えのほとんどがあなたが望むように振る舞わないことはかなり確信しています。(そして、いくつかの回答者が誤解しているという事実は、質問が明確化を必要とする十分な証拠です。)
jpmc26

1
@ jpmc26 rtreeが使用されている回答に更新を追加しました。このアプローチは、より効率的でスケーラブルになりました。お役に立てれば!
アントニオファルチャーノ

回答:


6

考えられるアプローチの1つは、ポリゴンのペアの組み合わせ、それらの交差点、最後にカスケード結合を介したすべての交差点の結合(ここで提案しような)を考慮することです

from shapely.geometry import Point
from shapely.ops import cascaded_union
from itertools import combinations

circles = [
    Point(0,0).buffer(1),
    Point(1,0).buffer(1),
    Point(1,1).buffer(1),
]

intersection = cascaded_union(
    [a.intersection(b) for a, b in combinations(circles, 2)]
)
print intersection

より効率的なアプローチでは、多くのジオメトリを処理するために(3つの円の場合ではなく)Rtreeのような空間インデックスを使用する必要があります。

from shapely.geometry import Point
from shapely.ops import cascaded_union
from rtree import index

circles = [
    Point(0,0).buffer(1),
    Point(1,0).buffer(1),
    Point(1,1).buffer(1),
]
intersections = []
idx = index.Index()

for pos, circle in enumerate(circles):
    idx.insert(pos, circle.bounds)

for circle in circles:
    merged_circles = cascaded_union([circles[pos] for pos in idx.intersection(circle.bounds) if circles[pos] != circle])
    intersections.append(circle.intersection(merged_circles))

intersection = cascaded_union(intersections)
print intersection

私はこれがOPが望むことをするとは思わない。OPは少なくとも2つのポリゴンがカバーするエリアを返しますが、OPはセット内のすべてのポリゴンがカバーするエリアのみを探します。コメントの説明を参照してください。
jpmc26

3

繰り返しまたは再帰性を使用しないのはなぜですか?何かのようなもの :

from shapely.geometry import Point

def intersection(circle1, circle2):
    return circle1.intersection(circle2)

coord1 = ( 0,0 )
point1 = Point(coord1)
circle1 = point1.buffer(1)

coord2 = ( 1,1 )
point2 = Point(coord2)    
circle2 = point2.buffer(1)


coord3 = ( 1,0 )
point3 = Point(coord3)
circle3 = point3.buffer(1)
circles = [circle1, circle2, circle3]
intersectionResult = None

for j, circle  in enumerate(circles[:-1]):

    #first loop is 0 & 1
    if j == 0:
        circleA = circle
        circleB = circles[j+1]
     #use the result if the intersection
    else:
        circleA = intersectionResult
        circleB = circles[j+1]
    intersectionResult = intersection(circleA, circleB)

result= intersectionResult

2

このコードを試してみてください。そのコンセプトは非常にシンプルで、あなたが探しているものが手に入ると信じています。

from shapely.geometry import Point
from itertools import combinations
dic ={}
dic['coord1']=Point(0,0).buffer(1)
dic['coord2']=Point(1,1).buffer(1)
dic['coord3']=Point(1,0).buffer(1)
inter = {k[0]+v[0]:k[1].intersection(v[1]) for k,v in combinations(dic.items(),2)}
print inter

出力をシェープファイルとして保存する場合は、fionaを使用します。

from shapely.geometry import Point,mapping
import fiona
from itertools import combinations
schema = {'geometry': 'Polygon', 'properties': {'Place': 'str'}}
dic ={}
dic['coord1']=Point(0,0).buffer(1)
dic['coord2']=Point(1,1).buffer(1)
dic['coord3']=Point(1,0).buffer(1)
inter = {k[0]+v[0]:k[1].intersection(v[1]) for k,v in combinations(dic.items(),2)}
print inter
with fiona.open(r'C:\path\abid', "w", "ESRI Shapefile", schema) as output:
    for x,y in inter.items():
        output.write({'properties':{'Place':x},'geometry':mapping(y)})

この出力-

ここに画像の説明を入力してください


3
私はこれがOPが望むことをするとは思わない。OPは少なくとも2つのポリゴンがカバーするエリアを返しますが、OPはセット内のすべてのポリゴンがカバーするエリアのみを探します。コメントの説明を参照してください。また、kそしてv、あなたの中の変数名の貧しい選択肢ですdict内包。これらの変数はそれぞれdic.items()、キーと値のペアではなく、の異なる要素を参照します。a, b誤解を招くようなものはありません。
jpmc26

1
ああ大丈夫そう私は彼の意味を理解していませんでした
-ziggy

そしてポイントは、よく私のK、Vの選択肢について取ら- dictionary..didntをループするとき、私はちょうど、自動的にそれに多くの思考を与えるK、Vを使用する
ジギー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.