Hackathon weekend

Say you’re a relatively young engineer and you’ve got a three day weekend. You’ve also got a metric buttload of work to do. What would you do? Would you:

  • Spend the weekend working to catch up?
  • Enjoy the long weekend by going somewhere?
  • Stay in and mess around with various technologies?

If you picked the last one, then you’re as pathetic as I am this weekend. What’s wrong with us?

Anyway, this weekend I should be working. Instead, I chose to take part in my own, personal hackathon. The project? Integrate some GPS data with Yahoo! Maps using the Yahoo! Maps AJAX API.

Enter the Garmin

When I started training last year for a marathon, I purchased a Garmin Forerunner 301. The Forerunner straps to your forearm and records GPS tracking points and your heart rate. When you’re done running, you can export the GPS data from the watch using the USB cable. The training software that comes with the Forerunner (Training Center) has an export feature. That will get you all of your training data as XML. For a long time, I’ve been wanting to take the data from the watch and lay it over a Yahoo! Map.

Parsing the Data

The data exported by the Garmin provides you with a lot of information. For each run, it provides the total duration of the run, the distance and a series of what it calls Trackpoints. Each Trackpoint is essentially a GPS reading and consists of the time (down to the second), latitude, longitude and altitude. Once you parse out the Trackpoints, you have everything you need to begin plotting the data.

To get the data to the browser, I have a PHP script that parses the XML and generates JSON. The browser requests the run list on startup (that’s what gives you the list of runs on the left side). When you click on a run, the browser makes a request to get all of the Trackpoints for the given run.

All you need now is a map.

Rendering the Data

Following the directions on the Yahoo! Developer Network site for using the maps API, it’s pretty simple to get a map to show up on the page. I added links for each of the runs in my exported XML file. When you click on the link, it triggers the rendering of the route.

Each Trackpoint is plotted on the map using an overlay. You could use simple markers, but your running route will just look like a long series of pushpins. Not exactly what I was going for. I use a pushpin at the start and end of each route, so they’re clearly indicated. For all points inbetween, I use an overlay with a custom, 6×6 image (all blue). This makes the route stand out pretty well against the map itself.

The data contains about one Trackpoint for every 3-4 seconds. That’s a lot of points. While Yahoo! Maps is capable of handling that many points, I figured it best to throttle back the number of points I was plotting. While it renders fine on my machine, I wasn’t really sure how it would do on a slower system. So I only plot every third point.

For convenience, when you select a run, the points are plotted on the map and then the map centers over the newly plotted route. This makes it a lot easier to find what was just plotted. Say you’ve currently got the map centered over Folsom, CA and the last run you clicked was in Sunnyvale, CA. Think you’ll ever find the points on your own? Not easily. I calculate the center by averaging the latitude and longitude from the points given. This doesn’t provide a perfect center, but it gets the job done well enough.

Issues

I did have a couple of issues along the way. At first the centering of the map wasn’t working at all. I clicked a run that was in Sunnyvale,CA and it centered the map over Los Banos, CA. As it turns out, I hadn’t accounted for drop outs of the GPS signal during my run. The export file still contains Trackpoints for those times (because it’s logging the time and heart rate), but my script was interpreting them as zero degrees latitude and zero degrees longitude, completely throwing off the averages and breaking the map centering.

I also have an issue with the “Start” and “End” pushpin labels on the map. First, the little conversation bubbles that are supposed to draw around the labels don’t resize with the content. I’m not sure if I should be doing something or if the maps JavaScript should be handling that for me. Second, many of my runs start and end at the same place. That makes it difficult to see one or the other label in some of the route plots.

I’m also using the Connection Manager library from the recently released Yahoo! UI Library. I have to say, I really didn’t enjoy it. It’s not terribly verbose when things are wrong. I somehow managed to have it call my callback function over and over. It seems to have come from a bug in my JavaScript, but why that should trigger the UI library to call my callback over and over is beyond me.

I also didn’t like installing the library. You download a ZIP file and then you have to put some of the JavaScript files in your web directory and link to them using script tags in your HTML page. It tells you to include the YAHOO.js file along with the connection manager specific JavaScript file. Problem is, the main ZIP file comes with 14 copies of YAHOO.js! They’re not even all identical, but they are very close. I did a check between two of them and the only differences were in the code comments. Seems silly that there’s 14 copies of the file included. If that’s really supposed to be a generally reusable bit of code, there should probably only be a single copy.

The Final Product

I’ve put up the finished product if you’re interested in looking at it. You can see it at http://beta.unclehulka.com/map/. I checked to see that it will run in my available browsers. That includes IE 6 and Firefox 1.5 on Windows XP.

When the page initially comes up, you should see a list of my runs on the left (shows the date and the distance) and a Yahoo! Map on the right. Clicking on one of the runs should cause the map to plot the points of the run and then center the map over the route. Subsequent clicking on runs will cause the map to clear the points of the current run, draw the points for the new run and recenter the map once again.

What’s Next?

Who knows. Maybe this is all I’ll do with it. I’ve been thinking about moving it over to the Google Maps API. I prefer Yahoo! Maps more, but Google’s API would make drawing the route a lot easier since they actually have functions to draw lines instead of just dropping a ton of points on the page to create the semblance of a line. Additionally, their satellite imagery would allow me to see where my offroad routes go. If you look at some of the runs in Sunnyvale, you’ll see I’m way off the beaten path in the marsh (click on the 8-17-2005 run). With Yahoo! Maps it’s difficult to tell where on earth I was running. But if you look at it on Google Maps, you can clearly see I’m out on some trails in the wildlife preserve.

2 Responses to “Hackathon weekend”

  1. Lars Says:

    Neat. If you had elevation data you could graph elevation over distanace and if you had time data you could compute you mph. Probably less interesting for running data where the variance isn’t very high. Since tackling road biking these things have become pretty interesting to me. If only I could decide on what equipement I should get to measure this stuff.

  2. Ryan Says:

    I actually have both pieces of data. It might be interesting to encode that data using different colors or something.

Leave a Reply