我试图检测给定点(x,y)是否在n * 2数组的多边形中。但似乎多边形边界上的某些点返回它不包括在内。
def point_inside_polygon(x,y,poly):
n = len(poly)
inside =False
p1x,p1y = poly[0]
for i in range(n+1):
p2x,p2y = poly[i % n]
if y > min(p1y,p2y):
if y <= max(p1y,p2y):
if x <= max(p1x,p2x):
if p1y != p2y:
xinters = (y-p1y)*(p2x-p1x)/float((p2y-p1y))+p1x
if p1x == p2x or x <= xinters:
inside = not inside
p1x,p1y = p2x,p2y
return inside
答案 0 :(得分:4)
这是具有多个选项的简单方法
from shapely.geometry import Point, Polygon
# Point objects(Geo-coordinates)
p1 = Point(24.952242, 60.1696017)
p2 = Point(24.976567, 60.1612500)
# Polygon
coords = [(24.950899, 60.169158), (24.953492, 60.169158), (24.953510, 60.170104), (24.950958, 60.169990)]
poly = Polygon(coords)
在功能内使用:
语法:point.within(多边形)
# Check if p1 is within the polygon using the within function
print(p1.within(poly))
# True
# Check if p2 is within the polygon
print(p2.within(poly))
# False
使用包含功能:
语法:polygon.contains(点)
# Check if polygon contains p1
print(poly.contains(p1))
# True
# Check if polygon contains p2
print(poly.contains(p2))
# False
使用触摸功能:
语法:polygon.touches(点)
poly1 = Polygon([(0, 0), (1, 0), (1, 1)])
point1 = Point(0, 0)
poly1.touches(point1)
# True
如果您想加快此过程,请使用
import shapely.speedups
shapely.speedups.enable()
和
利用Geopandas
参考:
答案 1 :(得分:1)
您可以使用来自contains_point
的{{1}}函数,具有较小的负半径和正半径(小技巧)。像这样:
matplotlib.path
结果是
import matplotlib.path as mplPath
import numpy as np
crd = np.array([[0,0], [0,1], [1,1], [1,0]])# poly
bbPath = mplPath.Path(crd)
pnts = [[0.0, 0.0],[1,1],[0.0,0.5],[0.5,0.0]] # points on edges
r = 0.001 # accuracy
isIn = [ bbPath.contains_point(pnt,radius=r) or bbPath.contains_point(pnt,radius=-r) for pnt in pnts]
默认情况下(或[True, True, True, True]
)不包括边框上的所有点,结果为
r=0
答案 2 :(得分:1)
以下是包含边缘的正确代码:
def point_inside_polygon(x, y, poly, include_edges=True):
'''
Test if point (x,y) is inside polygon poly.
poly is N-vertices polygon defined as
[(x1,y1),...,(xN,yN)] or [(x1,y1),...,(xN,yN),(x1,y1)]
(function works fine in both cases)
Geometrical idea: point is inside polygon if horisontal beam
to the right from point crosses polygon even number of times.
Works fine for non-convex polygons.
'''
n = len(poly)
inside = False
p1x, p1y = poly[0]
for i in range(1, n + 1):
p2x, p2y = poly[i % n]
if p1y == p2y:
if y == p1y:
if min(p1x, p2x) <= x <= max(p1x, p2x):
# point is on horisontal edge
inside = include_edges
break
elif x < min(p1x, p2x): # point is to the left from current edge
inside = not inside
else: # p1y!= p2y
if min(p1y, p2y) <= y <= max(p1y, p2y):
xinters = (y - p1y) * (p2x - p1x) / float(p2y - p1y) + p1x
if x == xinters: # point is right on the edge
inside = include_edges
break
if x < xinters: # point is to the left from current edge
inside = not inside
p1x, p1y = p2x, p2y
return inside
更新:修正了错误