<?xml version="1.0" encoding="UTF-8"?>
<essay xml:lang="en" version="5.0" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:gal="http://norman.walsh.name/rdf/gallery#" xmlns:foaf="http://xmlns.com/foaf/0.1/">
<info>
    
    
    
    
    
    
    
    
<title>GPX Google</title><biblioid class="uri">http://norman.walsh.name/2006/06/20/gpxGoogle</biblioid>
<volumenum>9</volumenum>
<issuenum>61</issuenum>
<pubdate>2006-06-20T01:45:22+02:00</pubdate>
<date>$Date: 2006-07-12 08:18:11 -0400 (Wed, 12 Jul 2006) $</date>
<author>
      <personname>
<firstname>Norman</firstname>
	<surname>Walsh</surname>
</personname>
    </author>
<copyright>
      <year>2006</year>
      <holder>Norman Walsh</holder>
    </copyright>
<abstract>
<para>This is the perl script that I use to build Google Maps of
my rides around Amherst. [Update: supports more variance in the GPX format.]
</para>
</abstract>
<dc:subject rdf:resource="http://norman.walsh.name/knows/taxonomy#Programming"/>
</info>

<para xml:id="p1">When I first published
<link xlink:href="/2006/05/25/amherstMA">Every street in Amherst</link>,
several people asked me how I was generating the map data.</para>

<para xml:id="p2">I expect other tools to do this exist,
but I thought it would be nice to share, so I cleaned mine up a bit. A
bit. It's still rough around the edges, but I'm not likely to improve
it further.</para>

<para xml:id="p3">My tool is
<link xlink:href="examples/gpxgoogle">gpxgoogle</link>. It reads one or
more <wikipedia>GPX</wikipedia> track files and produces an HTML
document that will display those tracks on a
<wikipedia page="Google_maps">Google Map</wikipedia>.</para>

<para xml:id="p4">You must configure <command>gpxgoogle</command> with a small
XML file in your home directory: <filename>~/.gpxgoogle</filename>:</para>

<programlisting>&lt;config&gt;
&lt;title&gt;Google Maps GPS Track&lt;/title&gt;
&lt;key&gt;YOUR GOOGLE MAPS KEY&lt;/key&gt;
&lt;width&gt;540px&lt;/width&gt;
&lt;height&gt;540px&lt;/height&gt;
&lt;units&gt;mi&lt;/units&gt;
&lt;colinear-threshold&gt;0.0001&lt;/colinear-threshold&gt;
&lt;icon&gt;var icon = new GIcon();
icon.image = "http://www.example.com/images/x.png";
icon.shadow = "http://www.example.com/images/xshadow.png";
icon.iconSize = new GSize(3, 3);
icon.shadowSize = new GSize(3, 3);
icon.iconAnchor = new GPoint(1, 1);
icon.infoWindowAnchor = new GPoint(2, 0);&lt;/icon&gt;
&lt;/config&gt;</programlisting>

<para xml:id="p5">The configuration parameters are:</para>

<variablelist>
<varlistentry>
<term>title</term>
<listitem>
<para xml:id="p6">This will be used as the title of the generated HTML page.
</para>
</listitem>
</varlistentry>

<varlistentry>
<term>key</term>
<listitem>
<para xml:id="p7">This is your Google Maps key.
</para>
</listitem>
</varlistentry>

<varlistentry>
<term>width</term>
<listitem>
<para xml:id="p8">The width of the map.
</para>
</listitem>
</varlistentry>

<varlistentry>
<term>height</term>
<listitem>
<para xml:id="p9">The height of the map.
</para>
</listitem>
</varlistentry>

<varlistentry>
<term>units</term>
<listitem>
<para xml:id="p10">The units that you wish to use for displayed track data. You can
specify “<literal>mi</literal>” (miles),
“<literal>km</literal>” (kilometers),
“<literal>ft</literal>” (feet), or
“<literal>m</literal>” (meters).
</para>
<para xml:id="p11">I've tried
<link xlink:href="http://en.wikipedia.org/wiki/Earth_radius">reasonably
hard</link> to make the calculations accurate, but of course they're not.
They don't account for irregularities in the terrain, inaccuracy in the
GPS, or the limitations of the floating point library.</para>
</listitem>
</varlistentry>

<varlistentry>
<term>colinear-threshold</term>
<listitem>
<para xml:id="p12">In an effort to reduce the number of points on the map,
<command>gpxgoogle</command> removes “colinear” points. These
calculations treat the map as completely flat and the latitudes and
longitudes as rectangular coordinates. This is wrong, of course, but
for the distances in a typical track, I don't think the errors are
significant.</para>
<para xml:id="p20">Anyway, if the discrepancy between the point that is
exactly colinear between two points and the actual position of the
point in between is less than this threshold, the middle point is
discarded. Empirically, a value of 0.0001 seems to work pretty well.
</para>
</listitem>
</varlistentry>

<varlistentry>
<term>icon</term>
<listitem>
<para xml:id="p13">The points along the track are identified with an icon. The
content of this element must be a fragment of Javascript that declares
a variable named “<literal>icon</literal>” and initializes it as
appropriate for a Google Maps <literal>GIcon</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>

<section xml:id="improvements">
<title>Obvious improvements and open questions</title>

<para xml:id="p14">As I said, I'm probably not going to do much more with
<command>gpxgoogle</command> in the short term. But when (or if),
I find the time, there are a few obvious improvements to be made.</para>

<orderedlist>
<listitem>
<para xml:id="p15">Support the configuration parameters as command
line options.</para>
</listitem>
<listitem>
<para xml:id="p16">It's pretty clear that for large numbers of points, the
techniques I'm using don't work well, they cause the Google Maps
Javascript to run too long. I don't know if there are better ways to
use the
<link xlink:href="http://www.google.com/apis/maps/">Google Maps API</link>.
</para>
</listitem>
<listitem>
<para xml:id="p18">It'd be nice to be able to generate Yahoo maps too.</para>
</listitem>
<listitem>
<para xml:id="p21">These maps don't work in PDF at all. Can anything be
done about that?</para>
</listitem>
</orderedlist>

<para xml:id="p19">If you decide to pursue any of these improvements,
or any others, please let me know. Whether you do or not, share and
enjoy!</para>

<para xml:id="p22">[Update 21 June 2006: Not using version 2 of the
Google Maps API was clearly short-sighted. Now updated. But not (yet)
using any of its new features.]</para>

<para xml:id="p23">[Update 12 July 2006: It appears that GPX tracks
don't always include a timestamp for each point, as I'd expected. That
caused a division by zero error, which I've now fixed.]</para>

</section>
</essay>

