Sunday, June 15, 2008

Google Maps - A Better Way To Get Content To Overlay The Map

A while back, I posted a solution to the question: How do I get content on top of a Google Map? In the last few days, I've found there to be a more Google Like, and perhaps more Kosher, approach.

To get stuff on top of a map, you should use either a Custom Control or a Custom Overlay. Use a control if you want your content to be on top of all the Google map elements (like icons and the info box), and use an overlay if you want your content to intermix with the map elements. Overlays are also nice because they are easily associated with a latitude and longitude, and will do The Right Thing when you drag the map around (mainly, move with the map). Controls are don't move around when you drag the map.

It turns out, creating a custom overlay and control isn't particularly hard - they both reduce to creating your content dynamically as an HTML node, and then adding it into the map's DOM. Sounds tricky, even looks kinda tricky, until you see an example.

As an example, here's an HtmlControl I whipped up that takes in an arbitrary HTML node and turns it into a map control:


function makeHtmlControl(content) {
    function HtmlControl(content) {
        this.content = content;
    }
    
    HtmlControl.prototype = new GControl();
    
    HtmlControl.prototype.initialize = function(map) {
        map.getContainer().appendChild(this.content);
        return this.content;
    }
    
    HtmlControl.prototype.getDefaultPosition = function() {
        return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 7));
    }
    
    HtmlControl.prototype.printable = function() { return false; }
    
    HtmlControl.prototype.selectable = function() { return false; }

    return new HtmlControl(content);
}

It's used like so:

  var someButton= new makeHtmlControl($E('a',
                        {href: '#', 
                         onclick: function() {...}}, 
                        "Click Me!"));
  map.addControl(someButton,
                 new GControlPosition(G_ANCHOR_TOP_RIGHT, 
                                      new GSize(10, 10));

In the above case, $E(...) references a library I use to create DOM nodes in a compact fashion. In this case, it's just making an a tag.

It's definitely worth getting to know how to use both custom overlays and controls. I think they are one of the keys to making your maps have innovative and imaginative behavior.

No comments:

Post a Comment