Wednesday, January 7, 2009

Getting mobile location on Windows Mobile 6

As part of my ongoing mapping project I wanted to be able to update my server with my location - the first step was to use the GPS built into my Windows Mobile 6.

I used the GPS Intermediate Driver to do this, and the code provided by the Windows Mobile 6 SDK.

The simplest code that can be written references the sample library provided by the SDK. My sub-80 line program to do this looks like this:

using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsMobile.Samples.Location;

namespace MobileLocate
{
 public partial class FormMain : Form
 {
  Gps gps = new Gps();
  GpsDeviceState device = null;
  GpsPosition position = null;

  public FormMain()
  {
   InitializeComponent();

   // updates from GPS need to be delgate to the UI thread
   EventHandler uiUpdatesOnApplicationThread = new EventHandler(UpdateUI);

   // handle device state updates
   gps.DeviceStateChanged += new DeviceStateChangedEventHandler(delegate(object sender, DeviceStateChangedEventArgs args)
   {
    device = args.DeviceState;

    Invoke(uiUpdatesOnApplicationThread);
   });

   // handle location updates
   gps.LocationChanged += new LocationChangedEventHandler(delegate(object sender, LocationChangedEventArgs args)
   {
    position = args.Position;

    Invoke(uiUpdatesOnApplicationThread);
   });

   gps.Open();
  }

  void UpdateUI(object sender, System.EventArgs args)
  {
   if (device != null)
    textBoxDev.Text = device.FriendlyName + " " + device.ServiceState + ", " + device.DeviceState;

   if (position != null)
   {
    if (position.LatitudeValid && position.LongitudeValid)
     textBoxLocation.Text = String.Format("{0}, {1}", position.Latitude, position.Longitude);

    if (position.SatellitesInSolutionValid &&
      position.SatellitesInViewValid &&
      position.SatelliteCountValid)
    {
     textBoxSats.Text = "Satellite Count:\n   " + position.GetSatellitesInSolution().Length + "/" +
       position.GetSatellitesInView().Length + " (" +
       position.SatelliteCount + ")\n";
    }
   }
  }

  private void FormMain_Closed(object sender, EventArgs e)
  {
   // ensures application closes cleanly
   if (gps.Opened)
    gps.Close();
  }
 }
}

I ran this just now, and stuck the co-ordinates into a map - and it works a treat!

I plan to extend this code to allow it to report into a central server (with a username/password) and then be able to show this on the map. This will form one of the overlays (more later on this) that can be incorporated onto a map - this means you could chose to have the location of a set of users appear on a map (they will have to be permissions on this, and maybe a "how precise" feature to mask exact location)

From the mobile viewpoint, it should be easy enough to use the vector maps to show a local map on the mobile phone as well. For the moment I may just add the ability for the system to tell you where you are (for example postcode in the UK using http://www.freethepostcode.org/ data), or just the nearest city or pub! ;-)

No comments: