C# wgs点到wgs定义线段的距离

C# wgs点到wgs定义线段的距离,c#,wgs84,geographic-distance,C#,Wgs84,Geographic Distance,我搜索了一下,但找不到完整的答案。 如果可能的话,用C#。 我需要一个WGS点和一个WGS点之间的最短距离定义一个球体上的线段(确切地说是地球) 编辑:也许一个插图会有帮助 请注意,这是一个理想的例子。”“点”可以是球体表面的任何位置,也可以是线段的起点和终点。显然,我不是在寻找通过球体的距离。数学不是我的强项,所以我不懂标准化或笛卡尔。也许我还应该注意,路径AB是可能的最短路径,距离?也是可能的最短路径。如果您的点位于由线段端点定义的道路内,并且与直线垂直,则应该这样做 如果点位于该道路之外

我搜索了一下,但找不到完整的答案。 如果可能的话,用C#。 我需要一个WGS点和一个WGS点之间的最短距离定义一个球体上的线段(确切地说是地球)

编辑:也许一个插图会有帮助


请注意,这是一个理想的例子。”“点”可以是球体表面的任何位置,也可以是线段的起点和终点。显然,我不是在寻找通过球体的距离。数学不是我的强项,所以我不懂标准化或笛卡尔。也许我还应该注意,路径AB是可能的最短路径,距离?也是可能的最短路径。

如果您的点位于由线段端点定义的道路内,并且与直线垂直,则应该这样做


如果点位于该道路之外,则计算从点到线段两端的距离,取较小值。

可以使用余弦球面定律:

您必须使用地球半径进行计算:

地球半径公里=6371

以下是我在openstreetmap.org上对OsmMercator.java的贡献:

/**
 * Gets the distance using Spherical law of cosines.
 *
 * @param la1 the Latitude in degrees
 * @param lo1 the Longitude in degrees
 * @param la2 the Latitude from 2nd coordinate in degrees
 * @param lo2 the Longitude from 2nd coordinate in degrees
 * @return the distance
 */
public static double getDistance(double la1, double lo1, double la2, double lo2) {
    double aStartLat = Math.toRadians(la1);
    double aStartLong = Math.toRadians(lo1);
    double aEndLat =Math.toRadians(la2);
    double aEndLong = Math.toRadians(lo2);

    double distance = Math.acos(Math.sin(aStartLat) * Math.sin(aEndLat)
            + Math.cos(aStartLat) * Math.cos(aEndLat)
            * Math.cos(aEndLong - aStartLong));

    return (EARTH_RADIUS_KM * distance);
}
你所需要做的就是用点积找到最近的点,并将其与距离方程一起使用

下面是一个最接近的例子:

double[] nearestPointSegment (double[] a, double[] b, double[] c)
{
   double[] t= nearestPointGreatCircle(a,b,c);
   if (onSegment(a,b,t))
     return t;
   return (distance(a,c) < distance(b,c)) ? a : c;
}
double[]nearestPointSegment(double[]a、double[]b、double[]c)
{
双[]t=最接近的点大圆(a,b,c);
if(第(a、b、t)段)
返回t;
返回(距离(a,c)<距离(b,c))?a:c;
}
请记住,单位尚未明确声明。当处理空间中的点时,有多种确定位置的方法。最重要的是你必须把你的单位固定在一个一致的类型上

在处理地球上的位置时,我主要使用lat/long坐标和矢量表示大小/方向。有几种已知类型可用于矢量和地球位置。其中包括:

  • 地心地球固定(ECEF)坐标系
  • 东北向下(内德)
  • 大地坐标系
对于你的例子,我可以考虑坚持大地测量。

现在,把这些放在一起,您可能会有一些伪代码,如下所示:

Where a Vector is made up of Geodetic coordinates:
class Vector {
 double x=0.0; //latitude
 double y=0.0; //longitude
 double h=0.0; //height
...
}

public Vector closestPoint(Vector lineStartA, Vector lineEndB, final Vector thePoint ) {
    Vector w = thePoint.subtract(lineStartA);
    double proj = w.dot(lineEndB);
    // endpoint 0 is closest point
    if ( proj <= 0.0f )
        return lineStartA;
    else
    {
        //Vector square 
        double vsq = lineEndB.dot(lineEndB);
        // endpoint 1 is closest point
        if ( proj >= vsq )
            return lineStartA.add(lineEndB);
        else
            return lineStartA.add(lineEndB.multiply(proj/vsq));
    }
}      

double DistanceInKilometres(Vector lineStartA, Vector lineEndB, Vector thePoint) {
  Vector cp=closestPoint(lineStartA, lineEndB, thePoint);
  return getDistance(cp.x, cp.y, thePoint.x, thePoint.y);
}
其中矢量由大地坐标组成:
类向量{
双x=0.0;//纬度
双y=0.0;//经度
双h=0.0;//高度
...
}
公共矢量闭合点(矢量线起点TA、矢量线终点B、最终矢量点){
向量w=点减法(直线起点);
双项目=w.dot(lineEndB);
//端点0是最近的点
如果(proj=vsq)
返回lineStartA.add(lineEndB);
其他的
返回lineStartA.add(lineEndB.multiply(proj/vsq));
}
}      
双距离里程计(矢量线起点TA、矢量线终点B、矢量点){
向量cp=闭合点(直线起点TA、直线终点B、点);
返回getDistance(cp.x,cp.y,thePoint.x,thePoint.y);
}

我感到惊讶的是,竟然没有人链接到可能的解决方案?相关或重复:@Nate Kohl,当我说“我找不到完整的答案”时,这就是我的意思。学习这些东西可能是个好主意。简单的网络搜索应该会得到大量关于这个主题的信息,这还不够精确。“它是否撒谎”是相对的。它永远不会完全(或在非常罕见的情况下)“在”走廊上。即使是这样,我也不知道如何在球体上计算它,这就是问题所在。对于第二部分,仅当点经度或纬度与线段端点经度或纬度相同时,才正确。恐怕你误解了我的问题。我相信你误解了我的答案。第二部分与轴向对准无关。如果点和线必须在轴上对齐,那么距离几乎是无用的。我现在明白了。“走廊”实际上是一条东西走廊,最北端是我的“线点a”,最南端是我的“线点B”。同样,正如回答中所说,“相同的解决方案是否适用于地理点”?如何知道它是否在走廊内?一个更简单的方法是使用答案中的方法,然后计算两个端点距离。。以三个中较小的一个为例。但最简单的解决方案是Nate Kohl在评论中提到的@内特:我鼓励你把这个评论变成一个答案。我会在悬赏结束前测试这个。斯利,忙着工作。我不能给出我的dot产品代码,因为它来自我们的内部库。然而,网上有很多合适的例子。我想我有一本过去研究的书签。我查一下。为您添加了伪代码。这将把它结合在一起。“在线段上”将只是将最北端和最南端的点与该点的纬度相匹配?哪种方法?最近点?您使用的输入值是什么?
Where a Vector is made up of Geodetic coordinates:
class Vector {
 double x=0.0; //latitude
 double y=0.0; //longitude
 double h=0.0; //height
...
}

public Vector closestPoint(Vector lineStartA, Vector lineEndB, final Vector thePoint ) {
    Vector w = thePoint.subtract(lineStartA);
    double proj = w.dot(lineEndB);
    // endpoint 0 is closest point
    if ( proj <= 0.0f )
        return lineStartA;
    else
    {
        //Vector square 
        double vsq = lineEndB.dot(lineEndB);
        // endpoint 1 is closest point
        if ( proj >= vsq )
            return lineStartA.add(lineEndB);
        else
            return lineStartA.add(lineEndB.multiply(proj/vsq));
    }
}      

double DistanceInKilometres(Vector lineStartA, Vector lineEndB, Vector thePoint) {
  Vector cp=closestPoint(lineStartA, lineEndB, thePoint);
  return getDistance(cp.x, cp.y, thePoint.x, thePoint.y);
}