简体   繁体   中英

Shorten this code that determines distance between two lat/longs in C#?

public static double Distance(LatLong from, LatLong to)
{
    double lat1 = from.Latitude * (Math.PI / 180.0);
    double lat2 = to.Latitude * (Math.PI / 180.0);

    return
        Math.Acos((Math.Sin(lat1) * Math.Sin(lat2)) +
        (Math.Cos(lat1) * Math.Cos(lat2) *
        Math.Cos((Math.PI / 180.0) * (to.Longitude - from.Longitude)))) * 3958.760;
}

Can you shorten this code any stretch? I'm just wondering ...

That's the standard spherical law of cosines formula. You won't get it any simpler than that. At best, you could clean up the code a little:

public static double Distance(LatLong from, LatLong to)
{
    double deg = Math.PI / 180.0;       // One degree in radians
    double lat1 = from.Latitude * deg;
    double lat2 = to.Latitude * deg;
    double dLng = (to.Longitude - from.Longitude) * deg;
    double R = 3958.760;

    return Math.Acos(Math.Sin(lat1) * Math.Sin(lat2) +
                     Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(dLng)) * R;
}

No, but I can offer a shorter, faster way, but far less accurate way to obtain relative distances:

public static double RelativeDistance(LatLong from, LatLong to)
{
  return (from.Latitude - to.Latitude) * (from.Latitude - to.Latitude) + (from.Longitude - to.Longitude) * (from.Longitude - to.Longitude);
}

This returns a value relative to the square of the distance in terms of the projection of coordinates unto a square 2D grid (as if the world were a 2:1 rectangle). It's so useless for real distances that I wouldn't even bother to take a square root to bring it back to being proportional to the projection (since the projection is silly), but what it can serve for is rapidly sorting by relative distances within such a small area (and far enough from the poles) that the gross inaccuracy doesn't matter much.

Hence, it won't help you calculate your fuel costs, but it will help you work out which pub is (probably) nearest. If you wanted to sort by relative distance to a given point, it could serve well and its speed be a boon. Outside of that use, it's pointless.

The formula looks like it is computing the distance along the surface of a sphere, and would thus be reasonably accurate even for points that were practically on opposite sides of the world. If the distances will be very close together, you could approximate it by projecting the points onto the surface of a cylinder (coaxial with the Earth) passing through one of the points; scale the cylinder so north/south and east/west distances on the cylinder match those on the Earth. This will simply require taking the cosine of one of the latitudes. Note that if the points are far enough apart that it matters which point's latitude you use, they are too far apart for this to be a good approximation, but for small distances this approach is quick and easy.

Note, btw, that something like a conical projection will be accurate over wider distances, but will also require more calculation; if one is going to that much trouble, one may as well use the 'right' calculations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM