I started working on some samples for showing Native Extensions for Silverlight (NESL) on Windows 7 and needed some sensors to play with to showcase the NESL sensor support.

Unfortunately the HP EliteBook 8540w has bubkes for sensors pre-installed on it. Sad that a box with an amblient light sensor doesn't supply a Windows 7 Sensor for use by programmers. Personal rant withheld there.

So I went sensor hunting for something a little more fun than the Virtual Light Sensor from the Windows SDK I'd beaten to death during Windows 7 launch.

One of the sensors I dug up was GeoSense by Rafael Rivera. If you listen to @thurott's Windows Weekly podcast, this is the same Rafael you'll hear mentioned a great deal.

GeoSense is a geo/ ip type location driver that triangulates your geo location off your IP address. Its free but you can't distribute it without talking to Rafael for a commercial deal. That being said, you could probably have your users install the driver themselves if you had to.

Setting it up was a breeze.

- Run the exe to install the driver.
- Go into control panel Sensors area Control Panel\All Control Panel Items\Location and Other Sensors and enable the driver by checking on it.
- At that point I downloaded their gmaps (ick) sample that was sensor enabled and gave it a run.
- Worked like a champ, coming close but not exactly right on top of my house.

Rigging It Up Yourself
So let's write some code to take advantage of the location sensor in Windows 7. With .NET Framework 4.0 the System.Devices.Location.GeoCoordinateWatcher class makes hooking into a geo sensor to get a latitude and longtiude extremely easy. We can also use the CivicAddressResolver to get an approximate street address from the latitude and longitude. All we have to do is instantiate the watcher, get the data, and process. A walkthrough is below.

Steps:
- Create a new Visual Studio 2010 WPF Windows Application. I named mine CSLocationSensor.
- Modify the MainWindow.xaml's grid to have a TextBlock in it

<Grid>
<TextBlock x:Name="textBlockResults" />
</Grid>

- Markup the code as follows. We're also going to use the CivicAddressResolver to get back and approximate street address.

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ResolveAddressSync();
        }
        void ResolveAddressSync()
        {
            System.Text.StringBuilder output = new System.Text.StringBuilder(1024);

            GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
            watcher.MovementThreshold = 1.0; // set to one meter
            watcher.TryStart(false, TimeSpan.FromMilliseconds(1000));

            CivicAddressResolver resolver = new CivicAddressResolver();
            if (watcher.Position.Location.IsUnknown == false)
            {
                output.AppendLine(string.Format("watcher.Position.Location\nlat: {0}\nlon: {1}\n", watcher.Position.Location.Latitude, watcher.Position.Location.Longitude));

                CivicAddress address = resolver.ResolveAddress(watcher.Position.Location);

                if (!address.IsUnknown)
                {
                    output.AppendLine(
                        string.Format("CivicAddress:\nAddressLine1: {0}\nAddressLine2: {1}\nCity: {2}\nState: {3}\nPostalCode: {4}",
                        address.AddressLine1, address.AddressLine2, address.City, address.StateProvince, address.PostalCode));
                }
                else
                {
                    output.AppendLine( "Address unknown" );
                }
            }
            textBlockResults.Text = output.ToString();
            System.Diagnostics.Trace.WriteLine(output.ToString());
        }
    }

- Compile and run, you should get output similar to the following. Well, not too similar. Not sure there's alot of .NET programmers at my latitude and longitude. Although if you're in my neck of the woods let me know.

watcher.Position.Location
lat: 27.8508701
lon: -82.6360557

CivicAddress:
AddressLine1: 201
AddressLine2: 87th Ave N
City: St Petersburg
State: Florida
PostalCode: 33702


GeoSense was a great location driver, and .NET makes it very easy to wire into your programs. The usefulness is obvious for Win7 location based applications.

Watch this blog, in one of my next articles I'll show you how to use it in OOB Silverlight Apps using Native Extensions for Silverlight (NESL).

Note: If you think you have some other sensor drivers I don't know about, let me know. Always on the hunt for more.