Latest posts

Cartography with Javascript

I have a nickname in the Erskine office. Well, I have several. One of the less offensive ones is “the maps guy”, largely on account of how many map interfaces I’ve worked on over the past few months.

The nickname carries with it little weight of knowledge, just the certainty that if a client asks about map visualisations, Matt will say “hey, aren’t you the maps guy, mate?”

It has, however, led to some interesting and enjoyable discoveries of late, two of which I will detail in this post.

Google Maps with KML (via geoxml3)

Phil Howell and I very recently planned, designed and developed a large data-driven application with an interface that mapped tabular and graphical data to geographical areas. Users are able to navigate between these areas on a Google Maps layer with all the expected overlays and interactions in a standard map interface.

The geographical data we were given to render was KML, which is an XML-formatted document primarily used with Google Earth. Initially, we were very happy with this, as version three of the Google Maps API has native support for rendering KML overlays. We soon discovered that the support is, in fact, immature at best.

The API is capable of parsing the KML and rendering it as an overlay, but interfacing with the overlays in order to add event listeners and alter parameters or attributes (read: do anything useful, whatsoever) is basically impossible, since the API renders the KML as a single overlay and will only listen for “click” events. Additionally, the KML file you pass to the API must be web-facing and is cached heavily by Google, which makes prototyping and testing an absolute pain.

In order to overcome this and build a usable interface, we looked to see what extensions were available, and came across geoxml3, a client-side KML parser for Google Maps. What geoxml3 does, in a nutshell, is read the KML and render it as standard poly overlays which can accept all the standard events and parameters that are unavailable to the native KML rendering.

geoxml3-driven map

The implementation is quite simple, you need only to instantiate a geoxml3 object, pass it a few parameters, and call a parse method which accepts a single or array of local KML files. The real power, however, comes when you write a success callback which has access to all the rendered document’s overlays. In there you can stick all your lovely event listeners for maximum interaction design.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 var geoxml_parser = new geoXML3.parser({
 map: map_interface, // Google Maps object
 zoom: true, // Zoom in on KML boundaries on render
 singleInfoWindow: true, // Display only one infowindow
 processStyles: true, // Honour KML styles
 afterParse: interactions // Callback for interactions
 });

 // Callback function
 function interactions(doc) {

 // Loop through each polygon
 $.each(doc[0].gpolygons, function(index, value) {

    // Add listener
    google.maps.event.addListener(this, "mouseover", function() {
        // Change some attributes of this layer
        this.setOptions({fillOpacity: 0.75, strokeColor: "#FFFFFF", zIndex: 1});
    });

 });

 }

 geoxml_parser.parse("/static/kml/states.kml"); // Parse KML

And so your dull, flat map suddenly turns into something more familiar to your users. Hooray!

Backwards-compatible SVGs (via svgweb)

A much higher-profile project is the svgweb library, which adds support for SVG for almost all major desktop browsers (hell, even IE6) by rendering the SVG as Flash for non-compatible user agents.

In this case, we had to provide an interactive map interface showing a high-level overview of the United States. We decided to use a freely available SVG document and overlay data and interactions on it via Javascript. The advantage of this over a custom Google Maps interface is speed of both client-side rendering and development.

With the SVG properly embedded using the library (using conditionals to target incompatible browsers), you merely write your listeners and interactions inside an SVGLoad window event.

One caveat of working with SVG documents at present is that the jQuery library does not currently support traversal of the SVG DOM, which means cracking out some vanilla Javascript, which isn’t a problem since the library includes backports of some features missing in non-compliant browsers (including support of addEventListener). There’s always the MDN if you need a refresher, anyway.

Native KML-based map

The crazy thing is you haven’t written any hacks or browser sniffing code (other than the conditional in your document to embed in the correct fashion), and your SVG will just work in every browser, complete with all your Javascript interactions. It’s pure black magic. And this is before you even press zoom in your browser eighteen times to inspect your razor-sharp vector. Fantastic.

I thoroughly recommend having a look through the various demos in the svgweb documentation, if only just to see how simple but powerful it is.

So those are just two of the things we’ve discovered recently that have made our working lives much easier. Have you come across any similar libraries, frameworks or plugins for simplifying the development of map interfaces?

Erskine Design
Published in: