84

I'm switching from v2 to v3 google maps api and got a problem with gMap.getBounds() function.

I need to get the bounds of my map after its initialization.

Here is my javascript code:


var gMap;
$(document).ready(

    function() {

        var latlng = new google.maps.LatLng(55.755327, 37.622166);
        var myOptions = {
            zoom: 12,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        gMap = new google.maps.Map(document.getElementById("GoogleMapControl"), myOptions);

        alert(gMap.getBounds());
    }
);

So now it alerts me that gMap.getBounds() is undefined.

I've tried to get getBounds values in click event and it works fine for me, but I cannot get the same results in load map event.

Also getBounds works fine while document is loading in Google Maps API v2, but it fails in V3.

Could you please help me to solve this problem?

Philip Kirkbride
  • 21,381
  • 38
  • 125
  • 225
DolceVita
  • 2,090
  • 1
  • 23
  • 35

6 Answers6

139

In the early days of the v3 API, the getBounds() method required the map tiles to have finished loading for it to return correct results. However now it seems that you can listen to bounds_changed event, which is fired even before the tilesloaded event:

<!DOCTYPE html>
<html> 
<head> 
   <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
   <title>Google Maps v3 - getBounds is undefined</title> 
   <script src="http://maps.google.com/maps/api/js?sensor=false" 
           type="text/javascript"></script> 
</head> 
<body> 
   <div id="map" style="width: 500px; height: 350px;"></div> 

   <script type="text/javascript"> 
      var map = new google.maps.Map(document.getElementById("map"), {
         zoom: 12,
         center: new google.maps.LatLng(55.755327, 37.622166),
         mapTypeId: google.maps.MapTypeId.ROADMAP
      });

      google.maps.event.addListener(map, 'bounds_changed', function() {
         alert(map.getBounds());
      });
   </script> 
</body> 
</html>
Daniel Vassallo
  • 337,827
  • 72
  • 505
  • 443
  • this is very useful for me, i almost wasted 2 hours for this – arjuncc May 22 '12 at 06:36
  • This can be useful as well http://stackoverflow.com/questions/832692/how-can-i-check-whether-google-maps-is-fully-loaded – dav Jun 08 '14 at 04:27
  • 1
    For what it's worth, I've found that, on Android phones, getBounds is not available after the *first* call to bounds_changed, but is after subsequent ones. Changing it to tilesloaded fixed that (though made for some ugly refreshes). – Chris Rae Apr 04 '18 at 22:47
  • But a user can change the bounds programmatically and each time this happens, `bounds_changed` are gonna be triggered? Then it's no good. We need to detect the first time when `getBounds` gets available and that's it... Of course we can use `removeListener` inside `addListener`... – Alexander Mar 18 '23 at 16:36
21

It should be working, atleast according to the documentation for getBounds(). Nevertheless:

var gMap;
$(document).ready(function() {
    var latlng = new google.maps.LatLng(55.755327, 37.622166);
    var myOptions = {
        zoom: 12,
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    gMap = new google.maps.Map(document.getElementById("GoogleMapControl"), myOptions);
    google.maps.event.addListenerOnce(gMap, 'idle', function(){
        alert(this.getBounds());
    });
});

See it working here.

Salman A
  • 262,204
  • 82
  • 430
  • 521
  • This should be the accepted answer. idle is being called way earlier than having to wait for all the tiles to be loaded. – treznik Oct 25 '10 at 00:05
  • @treznik: How did you determine that the `idle` event is fired before the `tilesloaded` event? For me, the `tilesloaded` event constantly fires before the `idle` event. – Daniel Vassallo Oct 25 '10 at 00:18
  • This is the better solution if you only need the function to run once. – bbodenmiller Apr 27 '14 at 06:25
15

I was saying Salman's solution is better because the idle event is called earlier than the tilesloaded one, since it waits for all the tiles to be loaded. But on a closer look, it seems bounds_changed is called even earlier and it also makes more sense, since you're looking for the bounds, right? :)

So my solution would be:

google.maps.event.addListenerOnce(gMap, 'bounds_changed', function(){
    alert(this.getBounds());
});
Salman A
  • 262,204
  • 82
  • 430
  • 521
treznik
  • 7,955
  • 13
  • 47
  • 59
  • 1
    When this question was asked, `bounds_changed` would not have worked, as `getBounds()` required the tiles to be loaded. +1 for suggesting it. I'll update my answer. – Daniel Vassallo Oct 25 '10 at 00:22
11

In other comments here, it's adviced to use the "bounds_changed" event over "idle", which I agree with. Certainly under IE8 which triggers "idle" before "bounds_changed" on my dev machine at least, leaving me with a reference to null on getBounds.

The "bounds_changed" event however, will be triggered continuously when you'll drag the map. Therefor, if you want to use this event to start loading markers, it will be heavy on your webserver.

My multi browser solution to this problem:

google.maps.event.addListenerOnce(gmap, "bounds_changed", function(){
   loadMyMarkers();
   google.maps.event.addListener(gmap, "idle", loadMyMarkers);
});
Almer
  • 1,139
  • 1
  • 12
  • 14
1

Well, i'm not sure if i'm too late, but here's my solution using gmaps.js plugin:

map = new GMaps({...});

// bounds loaded? if not try again after 0.5 sec
var check_bounds = function(){

        var ok = true;

        if (map.getBounds() === undefined)
            ok = false;

        if (! ok) 
            setTimeout(check_bounds, 500);
        else {
             //ok to query bounds here
              var bounds = map.getBounds();
        }   
    }

    //call it
    check_bounds();
Fernando
  • 7,785
  • 6
  • 49
  • 81
1

Adding an answer for 2021.

Map.getBounds() may return undefined initially. The preferred workaround to this is to use the bounds_changed event. Typically, an undefined value will only happen in the initialization of the map and never again.

const map = new google.maps.Map(document.getElementById("map"), {
  zoom: 12,
  center: new google.maps.LatLng(55.755327, 37.622166),
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

map.addEventListener('bounds_changed', () => {
  console.log(map.getBounds());
});

https://developers.google.com/maps/documentation/javascript/reference/map#Map.bounds_changed

Justin Poehnelt
  • 2,992
  • 1
  • 19
  • 23