In my Android app, I need to calculate the distance from a point (the device's location, which is a lat/lon coordinate) to a line (defined by two lat/lon coordinates), and get the result in meters.
I've taken a look at this page and the Java-code there, but I realize that I can't use that code (at least not with the lat/lon coordinates) because it will give me the distance/difference in degrees between the point and the line, and not in meters, and if I'm guessing right, it isn't possible to convert the difference in degrees to meters, right?
Therefore, I wonder how I can do this in another way, to get the distance in meters between a line and a point, both defined with lat/lon values.
EDIT: I took another aproach to the problem. Now I instead have a method which finds the point on the line which is closest to the device location.
This formula doesn't work exactly as intended when feeding it with lat/lon coorinates however. When the device location is on the line, it points right, but as the device movest away from the line, the error just gets bigger and bigger, until it stops at the end of the line.
Here is the function (based on the code in the first alternative of this answer):
/**
* Get the closest point on a line.
*
* @param a The first point of the line.
* @param b The second point of the line.
* @param p The point to start at.
*
* @return The point at the line a->b which is closest to the point p.
*/
public static Location closestPointOnLine(Location a, Location b, Location p)
{
// Store the vector a->p
Vector a_to_p = new Vector(a, p);
// Store the vector a->b
Vector a_to_b = new Vector(a, b);
// Find the square magnitude of a->b
double squareMagnitude = square(a_to_b.x) + square(a_to_b.y);
// Calculate the dot product of a->p and a->b
double atp_dot_atb = a_to_p.x * a_to_b.x + a_to_p.y * a_to_b.y;
// Calculate the normalized distance from a to the closest point
double t = clamp(atp_dot_atb / squareMagnitude, 0d, 1d);
// Create a new Location to store the result values in
Location location = new Location(LocationManager.PASSIVE_PROVIDER);
// Set the result coordinate values
location.setLatitude(a.getLatitude() + a_to_b.x * t);
location.setLongitude(a.getLongitude() + a_to_b.y * t);
// Return the location
return location;
}
The Vector
class is just a class which holds two double
values and represent a vector.
The clamp(double v, double min, double max)
method clamps a value (v
) between a minimum (min
) and a maximum (max
) value, in this case 0 and 1.
The square(double v)
method calculates the square of a value (simply v * v
).
I would be happy if someone could help me with either modifying this code a bit to return a correct point for WGS84/lat-lon coordinates, or suggest another way of doing it.
The result point should be as accurate as possible, lets say, less than 5 meters error.
Best Answer
you can't really convert convert distances in degrees into meters as the size of a degree varies as you approach the poles. convert your locations into a projected coordinate system, then calculate your distances.