如何处理Shapely中的舍入错误

Fab*_*bzi 9 python shapely

我有一个案例,它基于在一条线上投射一个点,然后在它上面分开这一行.我的用例稍微复杂一些,但我的问题可以通过以下代码重现:

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))
Run Code Online (Sandbox Code Playgroud)

通过构造,"pr"应该在第1行和它们的交叉点上:

line1.contains(pr)
line1.intersects(LineString([pt, pr]))
Run Code Online (Sandbox Code Playgroud)

打印两次"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]))
Run Code Online (Sandbox Code Playgroud)

打印"假".

我理解这背后的浮动精度问题,但这是否意味着我永远无法测试线上的点?当我根据点列表构建一条线时,我能确定至少所有"构造"点都在线上吗?

Mik*_*e T 8

从根本上说,需要一个精确的模型,并且有一些计划在某个时候将其实施到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
Run Code Online (Sandbox Code Playgroud)

您还可以使用或运算符链接更便宜和昂贵的测试,例如:

print(line1.contains(pr) or line1.buffer(EPS).contains(pr))
Run Code Online (Sandbox Code Playgroud)

如果第一个返回,它只运行第二个和更昂贵的测试or.


jmo*_*n12 3

截至shapely 2.0(请参阅发行说明),现在可以使用精确模型:覆盖函数的set_precision函数和grid_size参数。

使用前面的示例并对几何形状设置相同的任意精度。

from shapely import set_precision
from shapely.geometry import LineString, Point

precision = 1e-10
line1 = set_precision(LineString([(1, 1.2), (2, 2), (3, 2.3), (4, 1.2)]), precision)
pt = set_precision(Point(2.5, 1.2), precision)
pr = set_precision(line1.interpolate(line1.project(pt)), precision)

print(line1.intersects(LineString([pt, pr])))  # True
Run Code Online (Sandbox Code Playgroud)

注意:我本以为set_precisionpr对象是多余的,因为所有涉及的几何图形都是以任意精度创建的,但事实并非如此......

contains问题

根据我的实验,contains对于任何精度和任何精度组合,谓词都不是正确的。我没有足够的资格GEOS/shapely给出适当的解释。

尽管如此,直观上我认为这与所涉及的几何类型有关:使用buffer@MikeT解释的常用技术,我们实际上将线/点几何图形更改为多边形,这会对边界和内部的尺寸产生影响。涉及到几何图形。