0

我有我的位置的经度和纬度,并且我有一个位置列表,该列表作为沿道路的点列表(经度/纬度)排序。我如何找出我在哪两点之间?

如果我只搜索最近的两个点,我将在图片中以 P2 和 P3 结束。我想知道如何找出我在点 p1 和 p2 之间。

我将搜索的点列表将是包含纬度和经度的数据库行,因此指向如何构建 sql-query、linq-query 或伪代码的指针,所有指向我最佳解决方案的内容都是受欢迎的。我是地理定位和围绕它的数学的新手,所以把我当作新手。;)

(点列表将被排序,因此 P1 的 id 为 1,p2 的 id 为 2,依此类推。)

在此处输入图像描述

4

2 回答 2

1

请记住,您提出的建议可能会变得非常复杂(在同等条件下有很多点),因此提供准确的算法将需要(很多)更多的工作。处理更简单的情况(如您图片中的情况)并不难;您必须包括以下内容:

  • 将纬度/经度值转换为笛卡尔坐标(为了便于计算;尽管您甚至可以跳过这一步)。在此链接中,您可以在这方面获得一些灵感;它在 C# 中,但无论如何想法都很清楚。

  • “成对”遍历所有可用点并检查要分析的点 ( Mypos) 是否落在由它们形成的线中,处于中间位置。如下代码所示,这个计算非常简单,因此您不需要进行任何预过滤(之前寻找更接近的点)。

.

Dim point1() As Double = New Double() {0, 0} 'x,y
Dim point2() As Double = New Double() {0, 3}
Dim pointToCheck() As Double = New Double() {0.05, 2}

Dim similarityRatio As Double = 0.9
Dim minValSimilarDistance As Double = 0.001
Dim similarityDistance As Double = 0.5

Dim eq1 As Double = (point2(0) - point1(0)) * (pointToCheck(1) - point1(1))
Dim eq2 As Double = (point2(1) - point1(1)) * (pointToCheck(0) - point1(0))
Dim maxVal As Double = eq1
If (eq2 > eq1) Then maxVal = eq2

Dim inLine = False
Dim isInBetween As Boolean = False

If (eq1 = eq2 OrElse (maxVal > 0 AndAlso Math.Abs(eq1 - eq2) / maxVal <= (1 - similarityRatio))) Then
    inLine = True
ElseIf (eq1 <= minValSimilarDistance AndAlso eq2 <= similarityDistance) Then
    inLine = True
ElseIf (eq2 <= minValSimilarDistance AndAlso eq1 <= similarityDistance) Then
    inLine = True
End If

If (inLine) Then
    'pointToCheck part of the line formed by point1 and point2, but not necessarily between them
    Dim insideX As Boolean = False
    If (pointToCheck(0) >= point1(0) AndAlso pointToCheck(0) <= point2(0)) Then
        insideX = True
    Else If (pointToCheck(0) >= point2(0) AndAlso pointToCheck(0) <= point1(0)) Then
        insideX = True
    End If
    if(insideX) Then
        If (pointToCheck(1) >= point1(1) AndAlso pointToCheck(1) <= point2(1)) Then
            isInBetween = True
        ElseIf (pointToCheck(1) >= point2(1) AndAlso pointToCheck(1) <= point1(1)) Then
            isInBetween = True
        End If
    End If
End If

If (isInBetween) Then
    'pointToCheck is between point1 and point2
End If

如您所见,我已经包含了各种比率,允许您调整确切的条件(这些点很可能不会完全落在直线上)。similarityRatio说明“方程”或多或少相似(即,X 和 Y 值不完全符合直线但足够接近)。similarityRatio无法正确处理涉及零的情况(例如,相同的 X 或 Y),这就是minValSimilarDistance目的similarityDistance。您可以调整这些值或只是重新定义比率(关于点之间的 X/Y 变化,而不是关于“方程”)。

于 2013-09-19T08:50:29.510 回答
0

为清楚起见,Scala 中的等效解决方案:

def colinearAndInOrder(a: Point, b: Point, c: Point) = {

  lazy val colinear: Boolean =
    math.abs((a.lng - b.lng) * (a.lat - c.lat) - 
      (a.lng - c.lng) * (a.lat - b.lat)) <= 1e-9

  lazy val bounded: Boolean =
    ((a.lat < b.lat && b.lat < c.lat) || (a.lat > b.lat && b.lat > c.lat)) &&
      ((a.lng < b.lng && b.lng < c.lng) || (a.lng > b.lng && b.lng > c.lng))

  close(a,b) || close(b,c) || (colinear && bounded)
}

def close(a: Point, b: Point): Boolean = {
  math.abs(a.lat - b.lng) <= 1e-4 && math.abs(a.lat - b.lng) <= 1e-4
}
于 2015-05-27T23:21:26.233 回答