Distance of wgs point from a wgs defined line segment

c#, geographic-distance, wgs84

Solution

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

Problem

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.

Original source

Related problems