Day: September 10, 2007

  • Google Maps GeoXml crash course

    Over the weekend I added KML/GeoRSS data loading via GGeoXml to some mapping software for work. I ran in to a couple of gotchas and a couple of things that I thought were really interesting, so I thought I’d share.

    Getting started

    GGeoXml and particularly clickable polylines are relatively new features, so we need to specify that we want to use beta features when we grab our google maps code:

    <script src="http://maps.google.com/maps?file=api&v=2.x&key=your_key_here" type="text/javascript"></script>

    The key here is v=2.x which specifies that we want some 2.x or somewhat bleeding edge features. Now that we’ve got that loaded up, we’ll want to define a couple of variables:

    var map;
    var geoXml;

    This set up two global variables that we’ll be using. While I’m not a big fan of polluting global namespaces, this will allow me to play with these variables via Firebug once the page has loaded. For non-sample production code you’ll want to properly namespace all of your work. Next we’ll grab some data using GGeoXml:

    geoXml = new GGeoXml("http://example.com/path/to/data.kml");

    This will grab data from the XML file. In my case it’s a list of things to do in and around Kansas City. Now that we have data in hand, let’s create a map and add this data as an overlay:

    if (GBrowserIsCompatible()) {
      map = new GMap2(document.getElementById("map_canvas")); 
      map.setCenter(new GLatLng(38.960543, -95.254383), 9);
      map.addControl(new GLargeMapControl());
      map.addControl(new GLargeMapControl());
      map.addOverlay(geoXml);
    } 

    This should be pretty familiar if you’ve ever worked with the Google Maps API. We’re creating a new map using the div map_canvas in the document. Then we set the center of the map and add a few controls. Once we’re done with that, we’re going to add the geoXml that we loaded via KML to the map. Here’s the complete basic example:

    KC Basics

    Let Google do the hard stuff

    You’ll notice that the basic map is centered manually and doesn’t really fill the whole viewport. GGeoXml has finished running, we can query it for useful information. For example, I can ask what its default center is from Firebug:

    >>> geoXml.getDefaultCenter();
    (39.076937, -94.601867) Uk=39.076937 La=-94.601867 x=-94.601867 y=39.076937

    Knowing that I could then set the center of the map as follows:

    map.setCenter(geoXml.getDefaultCenter());

    While this handles setting the center correctly, it doesn’t help me figure out what zoom level to set. Luckily there is another method on GGeoXml objects: gotoDefaultViewport(map). I can then call the following and have Google do all the hard work of figuring out what center and zoom to use to make sure all of the KML/GeoRSS content fits within the viewport:

    geoXml.gotoDefaultViewport(map);

    This allows us to let Google create bounding boxes, find centers and zoom levels, which while interesting exercises aren’t fun to do on a daily basis. There’s one gotcha here though: you can’t get information about a GGeoXml instance until it’s done loading.

    Are we there yet?

    When we call GGeoXml, we can optionally provide a callback function that will be called as soon as GGeoXml is done doing its thing and we can access it. First let’s create a function that centers and zooms so that the data is contained nicely within the viewport:

    var geoCallback = function()
    {
      geoXml.gotoDefaultViewport(map);
    }

    Next we have to modify our call to GGeoXml to include the callback:

    geoXml = new GGeoXml("http://example.com/path/to/data.kml", geoCallback);

    Here’s the final code that includes the callback:

    KC Final

    I hope that illustrates how much can be done with very little code. Definitely take advantage of the rich map annotating capabilities that Google’s My Maps offers and don’t be shy about including them in maps on your own site.