GPS Meets Google Maps

From EggeWiki

I received a Garmin Forerunner 201 GPS for my birthday this year. This GPS gives you real time pedometer information while your running. However, it's also a fully functional GPS. One of it's features is that you can download it's data and export it into XML format. So shortly after getting it, I had to see what kind of hacks I could think up.

I've been reading a lot lately on Slashdot about hacking Google Maps. One example is displaying crime information in Chicago. While housing maps show you current real estate properties. So I decided I should write a hack which puts my runs onto a Google map.

Since the Garmin software can export to XML and the Google maps accept XML data, I figured this would only take a little xslt to get working. After a little work, I did get it to work. Here's an example:

mygmaps

Now, for the curious, I'll post how I did it.

Since I figured all I wanted to do was do an xslt transfortion, I though the 'ant' build tool would make this pretty easy. Here's my ant script:

<project name="Garmin" default="transform" basedir=".">
	<description>
        Convert Garmin Forerunner 201 XML to Google Maps XML format
    </description>
	<property file="build.properties" />
	<target name="transform">
		<xslt basedir="${source.dir}" destdir="output" style="GarminToGoogle.xsl"
			includes="*.xml" extension=".xml">
			<!-- mapper type="glob" from="*source.xml" to="*google.xml"/-->
		</xslt>
	</target>
	<target name="publish">
	    <ftp server="${ftp.server}" userid="${ftp.user}" password="${ftp.password}"
		remotedir="${ftp.remotedirectory}">
	    <fileset dir="output"/>
        </ftp>
	</target>
</project>

Getting Ant to run can be a bit of a hassle the first time. For this script, you'll need the Jakarta Commons Net, a Java SDK, and of course Ant.

Next after a little bit of research I came up with this xslt file:

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:garmin="http://www.garmin.com/xmlschemas/ForerunnerLogbook"
 version="1.0">

<xsl:output method="xml" indent="yes" encoding="iso-8859-1" />
<xsl:strip-space elements="*"/>

<xsl:template match="/">
<page>
  <title>Brian Egge Jog</title>
  <query>Brian Egge Jog</query>
  <center lat="40.71637" lng="-74.04572" />
  <span lat="0.017998" lng="0.027586" />
  <overlay panelStyle="http://maps.google.com/mapfiles/localpanel.xsl">
    <xsl:for-each
     select="garmin:History/garmin:Run/garmin:Track/garmin:Trackpoint">
    <location infoStyle="http://maps.google.com/mapfiles/localinfo.xsl" id="{garmin:Time}">
      <point lat="{garmin:Position/garmin:Latitude}" lng="{garmin:Position/garmin:Longitude}" />
      <icon image="http://maps.google.com/mapfiles/markerA.png" class="local" />
	    <info>
		    <title xml:space="preserve"><xsl:apply-templates select="garmin:Time"/></title>
	    </info>
    </location>
    </xsl:for-each>
  </overlay>
</page>

</xsl:template>
</xsl:stylesheet>

So I transformed my running data and uploaded it to my website. Unfortunately, it does not seem that Google Maps allows you to specify your own XML file directly anymore. Fortunately, I found a site which does: mygmaps.com. So I combined the scripts hosted on that site, with my XML file, and Google's map data.

I had to hand edit my source XML file a bit, so it would only select one run. Also, I hard coded my 'center' in the xslt file. When I think about transforming XML, the first tool that comes to mind is XSLT. Unfortunately it may not be the best tool for the job. It has goobs of limitations, and requires a lot of framework to do a little work. If I do more work on this project, I'll have to load the XML into an app, and then spit out a new XML file. This would allow me to calculate a center, and to filter some of the data points. I think XSLT remains best suited for transforming XML into HTML.

The best part of Google Maps is being able to view the satellite images. I can get a pretty good feel for how accurate the GPS is, but seeing where it shows that I ran.

Maybe my next project should be to put the data into Nasa's World Wind.