Skip to main content

Note: This post is part of a series and you can find the rest of the parts in the series index.

This is seriously some of the coolest stuff in .NET 4: System.Device.Location which gives you access to the Windows 7 sensor platform to build location aware applications. The two important classes to know are:

  • GeoCoordinateWatcher: Think of this as your GPS device. It gives you time and latitude and longitude.
  • CivicAddressResolver: This translates latitudes and longitude into addresses!

Usage

Usage of it is very easy. First we create a resolver and gps and then we tell the GPS to start. We assign an event to alert us when the position has changed and when we done we tell the GPS to stop.

static System.Device.Location.CivicAddressResolver resolver = new System.Device.Location.CivicAddressResolver();
static System.Device.Location.GeoCoordinateWatcher gps;

static void Main(string[] args)
{
    Console.Clear();
    Console.WriteLine("Press any key to quit");

    using (gps = new System.Device.Location.GeoCoordinateWatcher())
    {
        gps.PositionChanged += new EventHandler<System.Device.Location.GeoPositionChangedEventArgs<System.Device.Location.GeoCoordinate>>(gps_PositionChanged);
        
        gps.Start();                

        Console.ReadKey();

        gps.Stop();
    }
}

When the GPS position changes we write it to the screen as follows:

static void gps_PositionChanged(object sender, System.Device.Location.GeoPositionChangedEventArgs<System.Device.Location.GeoCoordinate> e)
{
    Console.Clear();
    Console.WriteLine("Last updated at: {0}", DateTime.Now);
    Console.WriteLine("Your location: {0}", e.Position.Location);
    Console.WriteLine("I think that is: {0}", NiceAddress(e.Position.Location));
    Console.WriteLine("Press any key to quit");
}

How do we get our address and display it nicely?

private static object NiceAddress(System.Device.Location.GeoCoordinate geoCoordinate)
{
    System.Device.Location.CivicAddress address = resolver.ResolveAddress(geoCoordinate);
    if (address.IsUnknown)
    {
        return "Unknown";
    }

    return string.Join("\n", address.FloorLevel, address.Building, address.AddressLine1, address.AddressLine2, address.City, address.StateProvince, address.CountryRegion, address.PostalCode);
}

And all this code produces the following:

image

Distances?

The GeoCoordinate class has a brilliant method called GetDistanceTo which returns the distance, in meters (Metric system FTW) between it and another GeoCoordinate. So for me to find the distance to the Lions Rugby Team home stadium I just do:

static void gps_PositionChanged(object sender, System.Device.Location.GeoPositionChangedEventArgs<System.Device.Location.GeoCoordinate> e)
{
    Console.Clear();
    Console.WriteLine("Last updated at: {0}", DateTime.Now);
    System.Device.Location.GeoCoordinate ellisPark = new System.Device.Location.GeoCoordinate(-26.1978417421848, 28.060884475708 );
    Console.WriteLine("It is {0}km to Ellis Park", e.Position.Location.GetDistanceTo(ellisPark) / 1000);
    Console.WriteLine("Press any key to quit");
}

Which gives:

image

Accuracy?

The accuracy can be controlled in settings, but a lot of it is up to your GPS receiver device. Unfortunately I do not have a proper hardware based GPS device, so I have used the excellent free software based Geosense for Windows, which you can see is accurate enough for most scenarios.

No sensor?

If you are on a version of Windows prior to 7, then the status of the GPS sensor will be set to Disabled.

If you are on Windows 7 without a GPS sensor then when you run it, you will be prompted for your default location information which Windows can try and use to find you.

image

Mobile?

As a bonus to using this, it is similar as the geolocation system in the new Windows Phone 7 platform! You can find out about geolocation in Windows Mobile 7 in Rudi’s blog post.