繁体   English   中英

从线串中提取到给定点的最近点索引?

[英]Extract nearest point index from a linestring to a given point?

让我们将线串视为点列表,我将其命名为 Trail。 我需要检测哪个点离这条小径足够近。 我有另一个名为兴趣点的线串,我需要从轨迹线串返回最近的索引点。 我想提一下,这些兴趣点不包含在轨迹线串中,因此我将通过给出该兴趣点以某种方式评估该轨迹中的索引点。 结果兴趣点将获得存在于轨迹列表中的值。

在此处输入图片说明

[编辑]:

我将使用普通数字转换这个问题。 我觉得这很容易。

输入列表 [0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]。 输入数:3.30

我可以很容易地看到条件:list[n] < number < list[n+1] 然后我可以检查成本:

cost1 = number - list[n] cost2 = list[n+1] - number。

然后我可以得到 N 的索引 if (cost1 < cost2) return N else return N+1。

[重要的]:

点对象不能与数字相比,这让我陷入了一个盲点。

如果您只需要执行一次,或者速度不是很重要,并且您的轨迹不会自行循环,因此检测最近的两个点可能与检测它们之间的线段不同,那么这很容易。

首先,您需要一个点的距离平方公式(这代替了普通数字的差异):

 def dSq(x0: Double, y0: Double, x1: Double, y1: Double) =
   (x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0)

请注意,除了您必须计算额外的平方根之外,使用普通距离而不是距离平方并没有真正的优势。 (但可以随意定义def d(...) = sqrt(dSq(...))并改用它。)

现在您可以找到从轨迹到目标点的距离:

 val ds = trace.map(p => dSq(target.x, target.y, p.x, p.y))

你会发现点对之间的距离:

 val pairDs = ds.sliding(2).map(xx => xx(0) + xx(1))

你会找到其中最小的索引:

 val smallest = pairDs.min
 val index = pairDs.indexWhere(_ == smallest)

然后在您的原始列表中,两点是indexindex+1

或者,您可以找到最近的单个点,然后通过将距离与这些点进行比较来决定您想要下一个还是上一个。 (同样,请注意,所有这些都不准确——要真正做到正确,您必须计算该点与两点之间的线段的最接近点,这是一个较长的公式。)

如果您必须经常这样做,那么您将需要一种更快的方法来忽略不相关的大距离。 一种常见的方法是在跟踪上放置一个网格,然后在每个网格元素内制作子跟踪。 然后,当给定一个兴趣点时,您首先查找其网格位置,然后在网格内执行相同的搜索技巧。 (您可能还需要搜索 8 个相邻的邻居,具体取决于您如何剪辑网格内的点。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM