Thursday, December 29, 2011

Gotcha of the Day: Google Maps setCenter(...) Doesn't Work

One of my favorite tricks using the Google Maps API is to create one or more little maps that are in sync with a larger map on the page.

You can do something like:

// Assume that bigMap is setup already, and smallMapDiv is an HTML node ready
// for us to add our smallMap to

// Show a marker on the bigmap
var m = new google.maps.Marker({position: bigMap.getCenter(), 
                                animation: google.maps.Animation.DROP,
                                map: bigMap,
                                draggable: true});

// Now create a small map that stays in sync with the marker's position
var ops = { center: m.getPosition(),
            zoom: bigMap.getZoom(),
            mapTypeId: google.maps.MapTypeId.ROADMAP };
var smallMap = new google.maps.Map(smallMapDiv, ops);

// Keep 'em in sync
google.maps.event.addListener(m, 'position_changed', function() { smallMap.setCenter(m.getPosition()); });
google.maps.event.addListener(bigMap, 'zoom_changed', function() { smallMap.setZoom(bigMap.getZoom()); });

The above code was essentially working for me, with one major issue. The marker's position (m) wasn't causing driving smallMap's centering. That is, the smallMap was not a zoomed in view of m.

After fiddling around, I learned that smallMap wasn't randomly misplaced. Instead of m.getPosition() setting the center of the map, it was driving the top left hand corner of the map. That is, smallMap synchronized with bigMap, but what should have been dead center of the map, was corresponding to the top left.

After further analysis, I did indeed figure out the problem: when I created smallMap and added it to smallMapDiv, smallMapDiv had yet to be added to the page's DOM. The result was that smallMap apparently didn't know the dimensions of the area it had to work with so setCenter(...) couldn't function.

Telling smallMap to recalculate its dimensions turns out to be painless. I just needed to arrange for the following code to be invoked once smallMapDiv was actually added to the page.

google.maps.event.trigger(smallMap, 'resize');

With that line of code, my little map and big map played quite nice with each other.

1 comment:

  1. Thank you SO SO much ! I had this bug for quite a while, and thanks to you I solved it !