GMaps: Dynamic loading of the API

Google Maps provides two ways to load its API. One is static, the simplest one that looks like this:

<script  type="text/javascript"
  src="http://maps.google.commaps?file=api&amp;v=2&amp;sensor=false&amp;key=ABCDEF..."></script>
<script type="text/javascript">
  var map = new GMap2(document.getElementById("map"));
  map.setCenter(new GLatLng(33.52392, -111.90884), 12);
  var myOverlay = new MyOverlay();
  map.addOverlay(myOverlay);
  ...
</script>
<body onunload="GUnload()">

The second one, dynamic, requires a bit more work:

<script type="text/javascript" 
  src="http://www.google.com/jsapi?key=ABCDEF..."></script>
<script type="text/javascript">
  google.load("maps", 2, {other_params:"sensor=false"});
  google.setOnLoadCallback(function() {
    var map = new google.maps.Map2(document.getElementById("map"));
    map.setCenter(new google.maps.LatLng(33.52392, -111.90884), 12);
    var myOverlay = new MyOverlay();
    map.addOverlay(myOverlay);
    ...
  });
</script>
...
<body>

Notice that there are several changes:

1. the source of the API script changed to http://www.google.com/jsapi?key=ABCDEF...; the version and sensor parameters are not present
2. the module to load, the version, and other parameters are specified in google.load call: google.load("maps", 2, {other_params:"sensor=false"});
3. the callback function that is called when the module is loaded is specified with google.setOnLoadCallback() call
4. onunload is no longer needed

The interface is documented here and instructions are easy to follow. In addition to asynchronous loading, the new method also provides a new namespace, google.maps, to be used instead of the old G* namespace. For example, GMap2 is replaced with google.maps.Map2, GOverlay with google.maps.Overlay and G_MAP_MAP_PANE with google.maps.MAP_MAP_PANE.

One of the pitfalls that I encountered was that comparing to static loading, dynamic loading is done asynchronously and all the code that needs to run after the API is loaded has to be run from the callback function specified in setOnLoadCallback().

What I initially attempted to do didn't work:

google.load("maps", 2, {other_params:"sensor=false"});
function myOverlay () {}
myOverlay.prototype = new google.maps.Overlay();
myOverlay.prototype.initialize .....
.. all other code to add to myOverlay
google.setOnLoadCallback(function() {
  var map = new google.maps.Map2(document.getElementById("map"));
  map.setCenter(new google.maps.LatLng(33.52392, -111.90884), 12);
  var myOverlay = new MyOverlay();
  map.addOverlay(myOverlay);
 ...
});

Notice that new google.maps.Overlay() code is executed right after google.load() call, but likely before the API code is actually loaded and you get something like "google.maps.Overlay is not a constructor".

Simply moving the code into the callback still doesn't work:

google.load("maps", 2, {other_params:"sensor=false"});
google.setOnLoadCallback(function() {
  var map = new google.maps.Map2(document.getElementById("map"));
  map.setCenter(new google.maps.LatLng(33.52392, -111.90884), 12);
  var myOverlay = new MyOverlay();
  map.addOverlay(myOverlay);
  ...
  function myOverlay () {}
  myOverlay.prototype = new google.maps.Overlay();
  myOverlay.prototype.initialize .....
  .. all other code to add to myOverlay
});

This still gives an error, albeit a different one this time: "a.initialize is not a function". This happens because the prototype initialization code -- myOverlay.prototype = new google.maps.Overlay(); -- happens after the class is being used.

Moving map.addOverlay(myOverlay); after the prototype is initialized makes things work. Here is a complete example that shows how this all works together. It is based on google's own example that displays a rectangle overlay; I changed the loading method to use AJAX and updated all G* methods to use the new namespace.

Leave a comment

what will you say?
(required)
(required)

About

I am Paul Kulchenko.
I live in Kirkland, WA with my wife and three kids.
I do consulting as a software developer.
I study robotics and artificial intelligence.
I write books and open-source software.
I teach introductory computer science.
I develop a slick Lua IDE and debugger.

Recommended

Close