Linkedin Profile
Tags:
programming
seattle
things that bug me
wall art

9/2008
8/2008
7/2008
6/2008
5/2008
4/2008
3/2008
2/2008
1/2008
12/2007
11/2007
10/2007
9/2007
8/2007
7/2007
6/2007
5/2007
4/2007
3/2007
2/2007
1/2007
12/2006
11/2006
10/2006
9/2006
8/2006
7/2006
6/2006
5/2006
4/2006
3/2006
2/2006
1/2006
12/2005
11/2005
10/2005
9/2005
8/2005
7/2005
6/2005
5/2005
4/2005
3/2005
2/2005
1/2005
12/2004
11/2004
10/2004
9/2004
8/2004
7/2004
6/2004
5/2004
4/2004
3/2004
2/2004
1/2004
12/2003
11/2003

GPS
2007-01-28

Last week, in a bout of gadget lust, I bought Streets & Trips 2007, which includes a little USB GPS locator.

GPS device

Not long after plugging it in I started to wonder if it was possible to pull GPS data directly off the device myself (rather than using Street and Trips), and so a hacking project was born. I decided to get my GPS location, somehow reverse geo-code it and publish my location to my weblog using a web service. Since my GPS device will only sometimes be plugged in, I decided to write a service that would pull my GPS location every few minutes and save it to disk. Likewise since my laptop will not always be connected to the internet, the same service would periodically try the geo-coding and publishing steps.

Getting data from the device was remarkably simple. A few internet searches revealed that GPS devices use the NMEA protocol, and that the device can be treated as a serial port, allowing me to start pulling data with a few lines of C# code like this:

	port = new SerialPort();
	port.PortName = "COM4";
	port.BaudRate = 4800;
	port.Parity = Parity.None;
	port.StopBits = StopBits.One;
	port.DataBits = 8;
	port.Open(); 
	int bufferSize = 256;
	byte[] data = new byte[bufferSize];
	port.Read(data, 0, bufferSize);

The NMEA data that is read into the buffer is an asci-encoded string formatted like so:

55 $GPGSA,A,3,16,07,06,21,10,18,,,,,,,2.4,1.3,2.0*39 $GPRMC,215238.000,A,4737.2885,N,12219.4668,W,0.19,350.69,270107,,,A*74 $GPGGA,215239.000,4737.2884,N,12219.4668,W,1,06,1.3,95.1,M,-17.3,M,,0000*55 $GPGSA,A,3,16,07,06,21,10,18,,,,,,,2.4,1.3,2.0*39 $

The GPRMC and GPGGA sections both contain latitude (47.37 N) and longitude (122.19 W), and the GPGGA also has altitude (95.1 M). Rather than worry about parsing this myself, I purloined some NMEA parsing code from this excellent sample by Scott Hanselman on MSDN's Coding4Fun.

With my coordinates retrieved, my attention now turned to reverse geo-coding them to find a place name. I had hoped that local.live.com would have an API, but I settled for the REST service provided by www.geonames.org. It accepts latitude and longitude as part of a HTTP get request like http://ws.geonames.org/findNearbyPlaceName?lat=47.3&lng=9, and returns location data as XML:

Location data

Now with coordinates and a place name, all that remained was to push this up to a SOAP service on my own blog that saves the location and time to a local database, and then add the most recent entry to the sidebar of my blog. And now you know where I am.

Tags: programming

Back to weblog