2009-06-16 13 views
7

Próbuję uzyskać granice mapy po zmianie powiększenia, , ale zdarzenie zoom_changed odpala przed ponownie przeliczono granice. Tak więc w procedurze zoom_changed otrzymujesz poprzednie granice, a nie nowe granice.Uzyskanie granicy mapy google v3 po zmianie powiększenia

Czy jest jakiś sposób uzyskania prawidłowych granic przy zmianie zoomu?

Odpowiedz

3

Z API documentation:

Jeśli próbuje wykryć zmiany w rzutni, należy użyć specyficznego bounds_changed imprezę zamiast składnika zoom_changed i center_changed wydarzeń. Ponieważ interfejs API Map Google uruchamia te ostatnie zdarzenia niezależnie, funkcja get_bounds() może nie zgłaszać użytecznych wyników do czasu zmiany autorytatywnego widoku. Jeśli chcesz uzyskać get_bounds() po takim wydarzeniu, należy zamiast tego posłuchać zdarzenia bounds_changed.

+0

użycie zdarzenia bounds_changed zamiast zoom_changed w tym przypadku jest nonsensem. Będzie strzelał przy każdej okazji, gdy zmieni się granice, ale interesują go tylko przypadki, gdy zmieniony jest zoom. – TMS

+1

@ tomas-t Nie zgadzam się, że obsługa zdarzenia bounds_changed jest "nonsensem". Jeśli przekraczasz granicę po zmianie powiększenia, czy nie możesz sprawdzić funkcji getZoom w ramce obsługi bounds_change? Opublikowana przeze mnie dokumentacja uzasadnia zachowanie (błąd dotyczący krawędzi), ale obejście tego problemu wydaje mi się dość proste. – RedBlueThing

+0

oczywiście możesz, ale dla rzeczy, którą OP chce obsługiwać zdarzenie bounds_changed zamiast zoom_changed jest niepotrzebna przesada, ponieważ zdarzenie uruchomi się nawet podczas przesuwania itp. Spójrz na obejście w mojej odpowiedzi. – TMS

17

To jest bug proszę gwiazdę tego problemu, jeśli jesteś zainteresowany.

Jest brzydki obejście go:

google.maps.event.addListener(map, 'zoom_changed', function() { 
    google.maps.event.addListenerOnce(map, 'bounds_changed', function (e) { 
      my_zoom_handler(); // do your job here 
    }); 
}); 
+0

+1 Zgadzam się, że to błąd, a interfejs API nie jest intuicyjny w tym przypadku. Byłoby miło, gdyby zoom_change został wysłany po obliczeniu nowych granic. – RedBlueThing

+0

Ten kod nie będzie działał, jeśli zdarzenie 'bounds_changed' pojawi się przed zdarzeniem zoom. "Maps API uruchamia te ostatnie zdarzenia niezależnie". – mgPePe

+0

Świetne rozwiązanie. Zmieniłem wewnętrzny detektor zdarzeń na ''idle'' zamiast'' bounds_changed'', ponieważ zdarzenie 'bounds_changed'' jest wyzwalane podczas animacji. Sądzę, że PO chciał, aby to się zaczęło. – Todd

2

Aby powiązać bounds_changed i pracy z markerami/mapy rzeczy po zoom użyj:

google.maps.event.addListener(map, 'zoom_changed', function() { 
    this.zoomChanged = true; 
}); 

google.maps.event.addListener(map,"bounds_changed",function() { 
    if (this.zoomChanged) { 
     this.zoomChanged = false; 
     // DO YOUR STUFF 
    } 
}); 
0

miałem ten sam problem. Oto, w końcu udało mi się rozwiązać kilka problemów, które miałem z innymi rozwiązaniami.

* Właściwie wymusza granic niezależnie od tego, czy chcesz korzystać z myszki lub klawiszy strzałek

* nie zatrzymuje się blisko brzegu, jeśli przytrzymać klawisze strzałek, ze względu na przyspieszenie patelni powodując jej „przeregulowanie” THE Krawędź w jednym kroku, więc zamiast tego zatrzymuje się na krótko (spróbuj przytrzymać klawisz strzałki w jednym kierunku, aż uderzysz o krawędź, a następnie zwolnij i naciśnij ponownie, a przy niektórych rozwiązaniach będzie przewijać tylko trochę więcej)

* Nie "odbija się", gdy uderzy w krawędź

* Prawidłowo wymusza ograniczenia w przypadku zmiany powiększenia

EDYCJA: OK, więc działa po zmianie powiększenia za pomocą kółka przewijania, ale nie przy użyciu regulatora zoomu. Pozwól mi trochę się pobawić, a zobaczę, czy mogę sprawić, że to działa ...

EDIT 2: Okazało się, problem polegał na tym, że usunąłem kontrolę panoramy. Dopóki kontrola pan jest obecna, działa to dobrze, zarówno za pomocą pokrętła jak i regulatora zoomu.

EDYCJA 3: Nie ... to nie było to. Zaktualizowałem kod, aby obsłużyć sterowanie powiększeniem.

// bounds of the desired area 
var allowedBounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(-64, -64), 
        new google.maps.LatLng(64, 64) 
        ); 

var zoomChanged = false; 

google.maps.event.addListener(map, 'center_changed', function() { 
    var mapBounds = map.getBounds(); 

    if(mapBounds.getNorthEast().lat() > allowedBounds.getNorthEast().lat()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat() - 
              (mapBounds.getNorthEast().lat() - 
              allowedBounds.getNorthEast().lat()), 
              map.getCenter().lng(), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getNorthEast().lng() > allowedBounds.getNorthEast().lng()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() - 
              (mapBounds.getNorthEast().lng() - 
              allowedBounds.getNorthEast().lng()), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getSouthWest().lat() < allowedBounds.getSouthWest().lat()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat() + 
              (allowedBounds.getSouthWest().lat() - 
              mapBounds.getSouthWest().lat()), 
              map.getCenter().lng(), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getSouthWest().lng() < allowedBounds.getSouthWest().lng()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() + 
              (allowedBounds.getSouthWest().lng() - 
              mapBounds.getSouthWest().lng()), true); 
    map.panTo(newCenter); 
    return; 
    } 
}, this); 

google.maps.event.addListener(map, 'zoom_changed', function() { 
    zoomChanged = true; 
}, this); 

google.maps.event.addListener(map, 'bounds_changed', function() { 
    if(zoomChanged) { 
    var mapBounds = map.getBounds(); 

    if(mapBounds.getNorthEast().lat() > allowedBounds.getNorthEast().lat()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat() - 
              (mapBounds.getNorthEast().lat() - 
              allowedBounds.getNorthEast().lat()), 
              map.getCenter().lng(), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getNorthEast().lng() > allowedBounds.getNorthEast().lng()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() - 
              (mapBounds.getNorthEast().lng() - 
              allowedBounds.getNorthEast().lng()), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getSouthWest().lat() < allowedBounds.getSouthWest().lat()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat() + 
              (allowedBounds.getSouthWest().lat() - 
              mapBounds.getSouthWest().lat()), 
              map.getCenter().lng(), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getSouthWest().lng() < allowedBounds.getSouthWest().lng()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() + 
              (allowedBounds.getSouthWest().lng() - 
              mapBounds.getSouthWest().lng()), true); 
     map.panTo(newCenter); 
     return; 
    } 

    zoomChanged = false; 
    } 
}, this); 
+0

Dzięki takiemu podejściu otrzymuję błędy "za dużo rekursji". Jeśli zamiast tego po prostu wysłucham zdarzenia bounds_changed (ignorując center_changed i zoom_changed), ten błąd zniknie. Z drugiej strony, ruchy nie są w 100% doskonałe, ponieważ wciąż istnieje pewne odbicie. –

+0

@ JoseGómez wydaje się, że problem dotyczy Google Chrome, spróbuj go w Firefoksie. Zajmę się tym dalej, aby sprawdzić, czy mogę rozwiązać problem. Zobacz to pytanie: http://stackoverflow.com/questions/15671480/uncaught-rangeerror-maximum-call-stack-size-exceeded-google-maps-when-i-try-to- – qwertymodo

+0

@ JoseGómez Rozwiązałem problem przez ustawienie v = 3 w ciągu zapytania dla skryptu API to linia. tj. '' – qwertymodo

Powiązane problemy