Month: September 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.

  • Accidental APIs: NFL edition

    NFL flash app powered by JSON

    These days whenever I find an interesting interactive/updating flash app I tend to fire up Firebug and see where the data is coming from. Quite often there’s an XML data feed somewhere that the flash app is being fed with. For example, you can get an XML feed of parking space availability or a list of airlines with gate information at Kansas City International Airport. As with many XML feeds designed for consumption with Flash, these feeds aren’t always well-formed but the data is there for the taking.

    I went on a similar quest after checking in on my Redskins at NFL.com. I was pleasantly suprised to find JSON driving the live game update instead of XML. There are three JSON feeds exposed on the live game update page.

    The first is the game-specific updates. This feed includes a score breakdown by quarter, who has possesion, time left, and the last few recent plays, along with a few other things that weren’t obvious at first glance.

    The second drives the league-wide scoreboard at the top of the page. This includes game date/time, the teams involved, what quarter they’re in, who has the ball, and what the score is. From time to time this feed will also include extra information such as a recent score change.

    The third feed includes information about weekly leaders in the NFL. This includes the top five passing, rushing, receiving, and scoring players this week. That sounds like great information to have programmatic access to if you’re in to fantasy football.

    It makes me happy to see big companies use XML and JSON feeds for their flash apps rather than a proprietary alternative. It’s also fun to see things like Prototype and Sciptaculous on a site like NFL.com. These feeds are rarely documented, but for the large part are self-documenting. Some of the subtitles in teh NFL feeds can most likely be determined by watching the feed and the flash display over time.

  • Google Maps adds clickability to GPolyline and GPolygon

    Google Maps: clickable poly!

    I’ve been waiting for this announcement Ever since Google introduced GGeoXml to its mapping API:

    In our latest release (2.88) of the API, we’ve added “click” events to GPolyline and GPolygon, much to the enthusiasm of developers in the forum.

    I knew it was just a matter of time since their internal apps have been supporting clickable GPolylines and GPolygons for some time now. Read the whole post for some fascinating information on how click detection works.

    What this boils down to (for me anyway) is that you can display information generated with Google’s MyMaps interface on your own site with the same fidelity as the original via KML and GGeoXml. Up until now you could load KML from MyMaps via GGeoXml but the GPolylines and GPololygons only displayed and were not clickable. This removes a huge roadblock and should allow for even more interesting mapping applications.

  • Crosswalk usability

    Crosswalk

    Today the City of Lawrence announced the operational status of a new crosswalk on 11th between New York and New Jersey. I’m a big fan of pedestrian safety, especially when it benefits kids on the way to school, but I was a little confused about the description of the new crosswalk and related signaling:

    The unique design consists of three lights (two reds and one yellow) configured like an inverted triangle. The signal remains dark until activated by a pedestrian pushing a button. The signal then flashes yellow for approximately six seconds followed by a steady yellow for approximately four seconds and followed by a double, steady red during the time pedestrians are receiving a “walk” signal. Once the pedestrian display changes to “Don’t Walk,” the motorist’s signal changes to alternating flashing red. During the flashing red, motorists may proceed through the crosswalk after stopping if the pedestrian has completed crossing.

    The operation of this crosswalk appears straightforward from the pedestrian point of view. Press button; wait for walk signal; walk across. Things are a bit more vague for motorists. Here are several questions I can think of with answers inferred from the press release and tri-fold pamphlet, along with some common sense:

    What do I do if someone is crossing in the crosswalk?
    Stop and wait for the person to finish crossing.
    What do I do if the bottom yellow light is flashing?
    This means that a pedestrian has just activated the signal. It’s probably best to slow to a stop and allow the person to cross.
    What do I do if the bottom yellow light is solid?
    A pedestrian activated the signal a few seconds ago and is waiting to cross. It’s probably best to slow to a stop and allow the person to cross.
    What do I do if the top two lights are red?
    The two red lights are equivalent to a stop sign or red light and you are required to stop at or before the line to let the pedestrian cross
    What do I do if the two red lights are alternating flashing red?

    If there is a pedestrian in the crosswalk you must either stop or continue to stop. If the pedestrian has cleared the crosswalk you may proceed.

    While I think that a crosswalk with lights to indicate it is in use is a great thing, some simplification could be done here. With all of the various light states above, the following always applies:

    What do I do if someone is crossing in the crosswalk?
    Stop and wait for the person to finish crossing.

    Perhaps it would be best to reduce the crosswalk to a binary state: either someone has pushed the button and the crosswalk is lit, or it is not in use and therefore not lit. This would reduce the four light states in to one single state and greatly simplifies what a driver needs to keep track of. If you would like to give the driver warning, use a solid red preceded by a solid yellow for a few seconds. This would closer emulate the traffic signal that drivers are used to obeying. I have seen other crosswalks that flash yellow and transition to solid yellow. Either of these solutions seem simpler and more effective than the High Intensity Activated crossWalK described above.