views:

73

answers:

1

I'm writing a Windows Phone 7 app that needs to be location aware. Specifically I want some (c#) code to run when the phone comes within a (fixed) range of a particular location, say 0.5 miles. I have all the lat / long data for the physical locations in memory. I will be using the Geo Coordinate Watcher class to get the devices current coordinates. Now the only trick is to calculate whether the user is in range of any of the locations.

Thanks!

Update: as promised here's the little C# function which uses the Spherical Law of Cosines method of calculating distances. Hope it can help someone else. Note: I'm writing a Windows Phone 7 app so used the GeoLocation class. If you're using "regular" c# then you can change the function to accept the two coordinate pairs the function needs.

    internal const double EarthsRadiusInKilometers = 6371;

    /// <summary>
    /// The simple spherical law of cosines formula 
    /// gives well-conditioned results down to 
    /// distances as small as around 1 metre. 
    /// </summary>
    /// <returns>Distance between points "as the crow flies" in kilometers</returns>
    /// <see cref="http://www.movable-type.co.uk/scripts/latlong.html"/&gt;
    private static double SpericalLawOfCosines(GeoCoordinate from, GeoCoordinate to)
    {
        return ( Math.Acos (
                Math.Sin(from.Latitude) * Math.Sin(to.Latitude) +
                Math.Cos(from.Latitude) * Math.Cos(to.Latitude) *
                Math.Cos(to.Longitude - from.Longitude)
            ) * EarthsRadiusInKilometers)
            .ToRadians();
    }

    /// <summary>
    /// To a radian double 
    /// </summary>
    public static double ToRadians(this double d)
    {
        return (Math.PI / 180) * d;
    }
+2  A: 

A quick search brought up this page with a formula for computing distance between two points on the earth. Quoted directly from the linked page:

Haversine formula:

R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c

(Note that angles need to be in radians to pass to trig functions).

Just plug in the lat/long values for your current location and another location and you should get d, which is the distance in km between those two points.

casablanca
This method is solid, just be sure to understand its limitations. It isn't exact by any means, and if you are in a mountainous region, then drastic elevation changes come into play as well. For most purposes though, this should be just fine.
Brad
Thanks guys. Disregarding elevation question for a minute, what are the limitations regarding accuracy? Are you saying that the finer grain I wanted to go the less accurate it is? i.e. a range of 50 miles is fairly accurate but a range of 50 meters is not very accurate?
will
It's a great circle calculation. The calculation itself has no error, your estimated position does. Your GPS receiver knows where you are +/- some amount (depending on the receiver, number of satellites, etc). Let's say, just for example, it's +/-25m. Well, if you're talking a distance of 50 miles, then percentage-wise it's not that far off. If you're talking a distance of 50m, then it's a very large amount.
ctacke
Great thanks for the clarification. I'll try to post the c# once I translate the above so other folks can get the benefit..
will