Google Maps Api v3 - getBounds jest niezdefiniowane

83

Przechodzę z v2 na v3 google maps api i mam problem z gMap.getBounds()funkcją.

Muszę poznać granice mojej mapy po jej inicjalizacji.

Oto mój kod javascript:


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());
    }
);

Więc teraz ostrzega mnie, że gMap.getBounds()jest niezdefiniowana.

Próbowałem uzyskać wartości getBounds w zdarzeniu kliknięcia i działa to dobrze, ale nie mogę uzyskać takich samych wyników w zdarzeniu ładowania mapy.

Również getBounds działa dobrze podczas ładowania dokumentu w Google Maps API v2, ale nie działa w V3.

Czy mógłbyś mi pomóc rozwiązać ten problem?

Słodkie życie
źródło

Odpowiedzi:

136

We wczesnych dniach interfejsu API w wersji 3 getBounds()metoda wymagała zakończenia ładowania kafelków mapy, aby zwracały prawidłowe wyniki. Jednak teraz wydaje się, że można posłuchać bounds_changedzdarzenia, które jest uruchamiane jeszcze przed tilesloadedwydarzeniem:

<!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
źródło
1
Właśnie tego potrzebuję! dzięki =). To rozwiązało mój problem.
DolceVita
to jest dla mnie bardzo przydatne, prawie zmarnowałem na to 2 godziny
arjuncc
Dziękuję Ci! Bardzo mi to pomogło
user15
Może to być również przydatne stackoverflow.com/questions/832692/ ...
dav
1
Warto zauważyć, że na telefonach z Androidem getBounds nie jest dostępne po pierwszym wywołaniu bounds_changed, ale jest po kolejnych. Zmiana na wczytane kafelki naprawiła ten problem (choć wprowadzono brzydkie odświeżenia).
Chris Rae
20

Powinno działać, przynajmniej zgodnie z dokumentacją getBounds (). Niemniej jednak:

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());
    });
});

Zobacz, jak działa tutaj .

Salman A
źródło
To powinna być akceptowana odpowiedź. idle jest wywoływane dużo wcześniej niż czekanie na załadowanie wszystkich kafelków.
treznik
@treznik: Jak ustaliliście, że idlezdarzenie zostało uruchomione przed tilesloadedwydarzeniem? Dla mnie tilesloadedimpreza stale strzela przed idlewydarzeniem.
Daniel Vassallo,
to jest dokładnie to, czego szukałem
arjuncc
Jest to lepsze rozwiązanie, jeśli chcesz, aby funkcja została uruchomiona tylko raz.
bbodenmiller
15

Mówiłem, że rozwiązanie Salmana jest lepsze, ponieważ idlezdarzenie jest wywoływane wcześniej niż to tilesloaded, ponieważ czeka na załadowanie wszystkich kafelków. Ale jeśli przyjrzeć się bliżej, wydaje się, że bounds_changednazywa się to jeszcze wcześniej i ma też większy sens, ponieważ szukasz granic, prawda? :)

Więc moim rozwiązaniem byłoby:

google.maps.event.addListenerOnce(gMap, 'bounds_changed', function(){
    alert(this.getBounds());
});
treznik
źródło
1
Gdy zadano to pytanie, bounds_changednie zadziałałoby, ponieważ getBounds()wymagało to załadowania płytek. +1 za zasugerowanie. Zaktualizuję odpowiedź.
Daniel Vassallo,
11

W innych komentarzach zaleca się używanie zdarzenia „bounds_changed” zamiast „idle”, z czym się zgadzam. Z pewnością pod IE8, który wyzwala "idle" przed "bounds_changed" przynajmniej na mojej maszynie deweloperskiej, pozostawiając mi odniesienie do null na getBounds.

Jednak zdarzenie „bounds_changed” będzie wyzwalane w sposób ciągły podczas przeciągania mapy. W związku z tym, jeśli chcesz użyć tego zdarzenia do rozpoczęcia ładowania znaczników, będzie to ciężkie dla twojego serwera internetowego.

Moje rozwiązanie tego problemu dla wielu przeglądarek:

google.maps.event.addListenerOnce(gmap, "bounds_changed", function(){
   loadMyMarkers();
   google.maps.event.addListener(gmap, "idle", loadMyMarkers);
});
Almer
źródło
1
To jest metoda, którą
stosuję
1

Cóż, nie jestem pewien, czy jestem za późno, ale oto moje rozwiązanie przy użyciu wtyczki gmaps.js :

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
źródło