Archive for November, 2008

Useful App in 42 Minutes

While I worked at NewsGator for two years (2006 to 2008), I rode my bike in to or out of Boulder/Denver about 90% of the time.  Wow, that was a fun - great company, great people, and the ride was nice!  Since then I have been asked countless times about the best bike route from Boulder to Denver.  I’ve tried to describe the route, but honestly it’s a bit convoluted and hard to convey verbally.

I tried to plot the route by hand in Google maps using their tools but it was a big pain in the ass.  Ever try doing something like that?  It is brutal.  Well, I have a meeting in Denver tomorrow, will ride my bike in, and got a bright idea this evening.  Why not use my phone, which has GPS, and write an application to breadcrumb the route and then post the data to some mapping service.

There was one catch; I was only going to give myself one hour to do it.  I could have probably found an app to do it for me, but that would be no fun.  So I started coding it up at 9 pm tonight - beats watching tv or going to hapa w/ danny, heather, and micah, ok scratch that one maybe.
The first choice was the technology stack.  I chose Microsoft for several reasons:
1.  My phone is a WinMobile
2.  I code all day in either Ruby or Java so change is good
3.  The MSFT/.NET stack is actually quite excellent - if you think not, you either haven’t tried or are not open minded
4.  MSFT gets little love in the Web 2.0 world, so I am here to spread some love :)
So, my objective was simple.  Record GPS data on my mobile, output to a .gpx file, and import into maps.live.com.  The undertaking was a success, I think, and I finished at 9:42.  It only took 42 minutes - sweet.  The app is ready, the bike is ready… I will post the results tomorrow some time.

So, here is what I did:

1.  Created a new Windows Mobile 6 project in Visual Studio 2005 - some code below and project files here

2.  Added a label to give me some feedback and three menu options to the main form (Start, Stop, and Exit) - start to get the GPS going and stop to close the GPS and write out the data

3.  Here is the first cool trick that made this oh so easy.  Studio has a great tool for generating classes from XML schema definition files.  So, I grabbed the schema file http://www.topografix.com/GPX/1/1/gpx.xsd and voila in 2 seconds had a fully blown out managed class based on the schema.  How sweet is that? Here is what you do:
a.  Using the Visual Studio 2005 Command Prompt I ran the following in my projects root directory - xsd gps.xsd /classes /language:cs /namespace:gpx
b.  Added the class to my project - sweetness

4.  Then added a reference to the GPS Intermediate Driver, managed wrapper.  The Windows Mobile 5 SDK and the Windows MObile 6 SDK ship with sample code that provides a managed wrapper around that native GPS and can be found in C:\Program Files\Windows Mobile 6 SDK\Samples\Smartphone\CS\GPS or C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Samples\Cs\Gps (on my machine anyway)

5.  Then wrote just a handful of lines of code to make it all work (see code below):
a.  Read the GPS data on a reasonable interval - all the hard work is done in the managed assembly, thanks
b.  Hydrate the GPX class instance (from step 3) - again all the hard work was done by the xsd tool all I did was stuff in some data
c.  Stop reading GPS data and write out the gpx file - all the hard work done by xml serializer and the xsd tool.  This is just too easy.

6.  Upload the gpx file from your mobile to live.com - all the hard work is done by maps.live.com
a.  http://maps.live.com - Collections | Open your collections | Import
b.  That’s all!

So, in under an hour I was able to build a useful application (for me anyway)… this is clearly not indicative of my coding skills bit of the great tools (in this case the .NET framework and live.com) that we developers have at our disposal today.

Like I said, I’ll update when I gen a map tomorrow.
Happy coding.

——————->>>>>>>> CODE STUFF
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;
using Microsoft.WindowsMobile.Samples.Location;

namespace GPS
{
public partial class FrmGPS : Form
{
private EventHandler updateDeviceHandler;
private EventHandler updateDataHandler;
GpsDeviceState device = null;
GpsPosition position = null;
Gps gps = new Gps();
List waypoints = new List();
DateTime lastCapture = System.DateTime.MinValue;
int iterator = 0;

public FrmGPS()
{
InitializeComponent();
}

private void FrmGPS_Load(object sender, EventArgs e)
{
updateDataHandler = new EventHandler(UpdateData);
updateDeviceHandler = new EventHandler(UpdateDevice);

gps.DeviceStateChanged += new DeviceStateChangedEventHandler(gps_DeviceStateChanged);
gps.LocationChanged += new LocationChangedEventHandler(gps_LocationChanged);
}

private void mnuStartGPS_Click(object sender, EventArgs e)
{
try
{
if (!gps.Opened)
{
lblStatus.Text = string.Empty;
gps.Open();
}
}
catch (Exception ex)
{
Cursor.Current = Cursors.Default;
MessageBox.Show(ex.Message + “\r\n\r\nMake sure you have the GPS intermediate driver enabled.”,
“GPS Failed”,
MessageBoxButtons.OK,
MessageBoxIcon.Hand,
MessageBoxDefaultButton.Button1);
}
}

private void mnuStopGPS_Click(object sender, EventArgs e)
{
try
{
if (MessageBox.Show(”You sure you want to stop acquiring GPS data?”, “Stop”, MessageBoxButtons.YesNo, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1) == DialogResult.Yes)
{
if (gps.Opened)
{
lblStatus.Text = “GPS device closed.”;
gps.Close();
}

XmlSerializer serializer = new XmlSerializer(typeof(gpx.wptType));
TextWriter writer = new StreamWriter(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), “kcbigring.gpx”));
gpx.gpxType data = new gpx.gpxType();
data.wpt = new gpx.wptType[waypoints.Count];
int i = 0;
foreach (gpx.wptType wp in waypoints)
{
data.wpt[i] = wp;
i++;
}
serializer.Serialize(writer, data);
writer.Close();
}
}
catch (Exception ex)
{
Cursor.Current = Cursors.Default;
MessageBox.Show(ex.Message,
“GPS Failed”,
MessageBoxButtons.OK,
MessageBoxIcon.Hand,
MessageBoxDefaultButton.Button1);
}
}

protected void gps_LocationChanged(object sender, LocationChangedEventArgs args)
{
position = args.Position;

// call the UpdateData method via the updateDataHandler so that we
// update the UI on the UI thread
Invoke(updateDataHandler);

}

void gps_DeviceStateChanged(object sender, DeviceStateChangedEventArgs args)
{
device = args.DeviceState;
Invoke(updateDeviceHandler);
}

void UpdateDevice(object sender, System.EventArgs args)
{
if (device != null)
{
lblStatus.Text = device.FriendlyName + ” acquiring signal…”;
}
}

void UpdateData(object sender, System.EventArgs args)
{
if (position != null)
{
if (position.LatitudeValid && position.LongitudeValid)
{
string tempLat = position.Latitude.ToString();
string tempLon = position.Longitude.ToString();

// Write some data?
TimeSpan span = DateTime.Now - lastCapture;
if (span.TotalSeconds > 4)
{
lblStatus.Text = iterator.ToString() + “: ” + tempLat + ” ” + tempLon;
lastCapture = DateTime.Now;
gpx.wptType wp = new gpx.wptType();
wp.lat = System.Convert.ToDecimal(tempLat);
wp.lon = System.Convert.ToDecimal(tempLon);
wp.time = System.DateTime.Now;
wp.name = iterator.ToString();
waypoints.Add(wp);
iterator++;
}
}
}
}
}
}

November 13th, 2008


Lijit Search

Categories

Links

Feeds

Calendar

November 2008
M T W T F S S
« Oct   Dec »
 12
3456789
10111213141516
17181920212223
24252627282930

Posts by Month

Posts by Category