Как найти, какие точки пересекаются с многоугольником в геопандах?

Я пытался использовать функцию "пересекает" на geodataframe, глядя, какие точки лежат внутри многоугольника. Однако только первая функция в кадре будет возвращена как 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 ответов


согласно документации (http://geopandas.org/user.html#geoseries):

бинарные операции могут быть применены между двумя GeoSeries, в этом случае операция проводится элементарно. Две серии будут выравнивается по соответствующим индексам.

ваши примеры не должны работать. Поэтому, если вы хотите проверить, чтобы каждая точка была в одном полигоне, вам придется do:

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 для вопросов, которые могут возникнуть с точками на границы.


один из способов обойти это, кажется, чтобы получить определенную запись (которая не работает для моего приложения, но может работать на чужого:

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])

другой способ (более полезный для моего приложения) - пересечение с унарным объединением объектов для второго слоя:

points.intersects(poly.unary_union)