我有一个案例,该案例基于在一条线上投影一个点,然后在其上分开该线。我的用例稍微复杂一点,但是我的问题可以用以下代码重现:
from shapely import *
line1 = LineString([(1,1.2), (2,2), (3, 2.), (4,1.2)])
pt = Point(2.5, 1.2)
pr = line1.interpolate(line1.project(pt))
根据构造,“ pr”也应位于第1行及其交点上:
line1.contains(pr)
line1.intersects(LineString([pt, pr]))
打印两次“ True”。但是更改输入坐标会稍微中断工作流程:
from shapely import *
line1 = LineString([(1,1.2), (2,2), (3, 2.3), (4,1.2)])
pt = Point(2.5, 1.2)
pr = line1.interpolate(line1.project(pt))
line1.contains(pr)
line1.intersects(LineString([pt, pr]))
打印“ False”。
我了解这背后的浮动精度问题,但这是否意味着我永远无法测试在线上的点?当我基于点列表构造一条线时,是否可以确定至少所有“构造”点都在该线上?
从根本上讲,需要一个精确的模型,并且有各种计划在某个时候将其实现到GEOS中(不要屏住呼吸,因为这已经讨论了好几年了)。
否则,这些选项可以是基于距离的测试(推荐),也可以是稍作调整的更昂贵的基于缓冲区的技术(请参阅机器epsilon):
from shapely.geometry import LineString, Point
line1 = LineString([(1, 1.2), (2, 2), (3, 2.3), (4, 1.2)])
pt = Point(2.5, 1.2)
pr = line1.interpolate(line1.project(pt))
# Distance based
print(line1.distance(pr) == 0.0) # True
# Buffer based
EPS = 1.2e-16
print(line1.buffer(EPS).contains(pr)) # True
print(line1.buffer(EPS).intersects(LineString([pt, pr]))) # True
您还可以使用or
运算符链接便宜和昂贵的测试,例如:
print(line1.contains(pr) or line1.buffer(EPS).contains(pr))
如果第一个返回,则仅运行第二个和更昂贵的测试False
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句