Distance of wgs point from a wgs defined line segment

落爺英雄遲暮 提交于 2019-12-09 14:00:29

问题


I searched but I could not find a complete answer. In C# if at all possible. I need the shortest distance between a WGS point and a WGS point defined line segment on a sphere (Earth exactly).

float DistanceInKilometres(PointF LineStartA, PointF LineEndB, PointF ThePoint)

EDIT: Perhaps an illustration would help

Please note that this is an ideal example. 'The point' could be anywhere on the surface of the sphere, the segment start-end, too. Obviously, I'm not looking for the distance through the sphere. Math isn't my stronger side, so I don't understand normalize or to cartesian. Maybe I should also note that path AB, is the shortest possible, and Distance?, is the shortest possible too.


回答1:


You can use the spherical law of cosines:

  • http://en.wikipedia.org/wiki/Spherical_law_of_cosines
  • http://mathworld.wolfram.com/SphericalSegment.html
  • http://mathworld.wolfram.com/SphericalTrigonometry.html

You will have to use the earth's radius for calculations:

EARTH_RADIUS_KM = 6371;

Here, from my contributions to OsmMercator.java, from openstreetmap.org:

/**
 * 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);
}

All you need to do is find the closest point with dot product and use that with the distance equation.

Here's the closest point example:

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;
}
  • How to calculate distance from a point to a line segment, on a sphere?
  • http://en.wikipedia.org/wiki/Great-circle_distance

Keep in mind the units haven't been explicitly declared. When dealing with points in space there're are a variety of ways to determine position. The main thing is you have to nail down your units to a consistent type.

When working with position on the earth, I mainly use lat/long coordinates and vectors for magnitude/direction. There're are several known types to use for vectors and earth's position. Among them are the following:

  • Earth-centered earth-fixed (ECEF) coordinate system
  • North-East-Down (NED)
  • Geodetic coordinate system

For your example, I might consider sticking to Geodetic.

Now, bringing this together, you might have some pseudo code which looks like this:

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);
}



回答2:


If your point lies within a corridor that is defined by the end points of your line segment, and perpendicular to the line, then this answer should do.

If your point lies outside that corridor then compute the distance from your point to each end of the line segment and take the smaller.



来源:https://stackoverflow.com/questions/10045544/distance-of-wgs-point-from-a-wgs-defined-line-segment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!