以下是我构建算法的方式。我假设目标点和测量点是“线性的”(我不会在任何时候倒退)。
第 1 步:定义虚拟细分
您从Calculating the distance between a point and a virtual line of two lat/lngs 知道如何确定点到虚拟线的距离。因此,您可以将目标点列表视为一系列虚拟线。假设您的目标点是在 x,y 对 targetCoords 的数组中提供的,如果您有 n = len(targetCoords) 目标点,那么您将拥有 n-1 虚拟段。
对于目标点中的每个点,确定它与下一个目标点的距离。您可以通过简单的列表理解来做到这一点:
targetPointDistances = [(Dist(Coords2,Coords1) for Coords1, Coords2 in zip(targetCoords[:-1], targetCoords[1:])]
“Dist”是用户定义的函数,用于确定坐标对之间的距离。 This question 提供了一个如何轻松实现此功能的示例,而this question 提供了更精确的 Vincenty 公式的详细信息。
第 2 步:确定当前虚拟段
您想开始查看每个测量点,并比较它与虚拟线段的距离。对于每个点,您都需要检查是否仍在将其与正确的虚拟段进行比较。
因此,在确定每次距离之前,请检查您是否处于正确的路段。让我们试试这个:
targetSegment = 0
for point in measuredPoints:
while Dist(point, targetCoords[targetSegment+2]) < targetPointDistances[targetSegment+1]:
targetSegment += 1
对于每个点,我正在检查它与下一段终点的距离是否小于当前段的长度。如果这是真的,我开始将它与下一个虚拟段进行比较。 (额外的功劳:在任何情况下这是行不通的,或者不是最理想的吗?)
在您的示例图像中,这会在第一段中留下前 4 个测量点。第五个测量点距离第三个目标点比第二个目标点距离第三个目标点更近,所以我们前进到下一个虚拟段。
第 3 步:计算与虚拟线的距离
这似乎很简单——你已经链接到这个了!
只需使用targetCoords[targetSegment] 和targetCoords[targetSegment+1] 作为虚拟线的起点和终点。这可以是第 2 步中 for 循环的一部分!