ジオデータフレームで「交差」機能を使用して、ポリゴン内にあるポイントを確認しようとしています。ただし、フレームの最初の機能のみがtrueとして返されます。私は何が間違っているのですか?
from geopandas.geoseries import *
p1 = Point(.5,.5)
p2 = Point(.5,1)
p3 = Point(1,1)
g1 = GeoSeries([p1,p2,p3])
g2 = GeoSeries([p2,p3])
g = GeoSeries([Polygon([(0,0), (0,2), (2,2), (2,0)])])
g1.intersects(g) # Flags the first point as inside, even though all are.
g2.intersects(g) # The second point gets picked up as inside (but not 3rd)
ドキュメント によると:
二項演算は2つのGeoSeries間で適用できます。その場合、演算は要素ごとに実行されます。 2つのシリーズは、一致するインデックスによって整列されます。
あなたの例はうまくいくはずがありません。したがって、各ポイントが単一のポリゴン内にあるかどうかをテストする場合は、次のことを行う必要があります。
poly = GeoSeries(Polygon([(0,0), (0,2), (2,2), (2,0)]))
g1.intersects(poly.ix[0])
出力:
0 True
1 True
2 True
dtype: bool
または、特定のGeoSeriesのすべてのジオメトリをテストする場合:
points.intersects(poly.unary_union)
Geopandasは、幾何学的な作業をShapelyに依存しています。直接使用すると便利な(そして読みやすい)場合があります。次のコードも宣伝どおりに機能します。
from shapely.geometry import *
p1 = Point(.5,.5)
p2 = Point(.5,1)
p3 = Point(1,1)
poly = Polygon([(0,0), (0,2), (2,2), (2,0)])
for p in [p1, p2, p3]:
print(poly.intersects(p))
境界上のポイントで発生する可能性のある問題については、 Shapelyでの丸め誤差の処理方法 も参照してください。
これを回避する1つの方法は、特定のエントリを取得することです(これは私のアプリケーションでは機能しませんが、他の誰かのアプリケーションでは機能する可能性があります。
from geopandas.geoseries import *
p1 = Point(.5,.5)
p2 = Point(.5,1)
p3 = Point(1,1)
points = GeoSeries([p1,p2,p3])
poly = GeoSeries([Polygon([(0,0), (0,2), (2,2), (2,0)])])
points.intersects(poly.ix[0])
もう1つの方法(私のアプリケーションではより便利です)は、2番目のレイヤーの機能の単一の和集合と交差することです。
points.intersects(poly.unary_union)
以下の簡単な関数を使用して、ポリゴン内にあるポイントを簡単に確認できます。
import geopandas
from shapely.geometry import *
p1 = Point(.5,.5)
p2 = Point(.5,1)
p3 = Point(1,1)
g = Polygon([(0,0), (0,2), (2,2), (2,0)])
def point_inside_shape(point, shape):
#point of type Point
#shape of type Polygon
pnt = geopandas.GeoDataFrame(geometry=[point], index=['A'])
return(pnt.within(shape).iloc[0])
for p in [p1, p2, p3]:
print(point_inside_shape(p, g))