Verwenden von setZoom () nach Verwendung von fitBounds () mit Google Maps API V3

79

Ich verwende fitBounds (), um die Zoomstufe auf meiner Karte festzulegen. Dazu gehören auch alle derzeit angezeigten Markierungen. Wenn jedoch nur eine Markierung sichtbar ist, beträgt die Zoomstufe 100% (... welche Zoomstufe 20, glaube ich ...). Ich möchte jedoch nicht, dass es so weit hineingezoomt wird, damit der Benutzer die Position des Markers anpassen kann, ohne herauszoomen zu müssen.

Ich habe folgenden Code:

var marker = this.map.createMarker(view.latlng, this.markerNumber);
this.map.bounds.extend(view.latlng);
this.map.map.setCenter(this.map.bounds.getCenter());
this.map.map.fitBounds(this.map.bounds);
if (this.markerNumber === 1) {
  this.map.map.setZoom(16);
}
this.markerNumber++;

Dabei wurde this.map.bounds zuvor definiert als:

this.map.bounds = new google.maps.LatLngBounds();

Das Problem, das ich habe, ist jedoch, dass die Zeile this.map.map.setZoom(16);nicht funktioniert, wenn ich sie verwende this.map.map.fitBounds(this.map.bounds);. Ich weiß jedoch, dass die Codezeile korrekt ist, da setZoom () beim Kommentieren der Zeile fitBound () auf magische Weise funktioniert.

Irgendwelche Ideen, wie ich das lösen kann? Ich denke darüber nach, eine maxZoom-Stufe als Alternative einzustellen, wenn dies nicht funktioniert.

Andrew De Andrade
quelle
Die .map.map ist absichtlich dort oder liegt ein Fehler vor. Wenn möglich, laden Sie eine Testseite hoch und geben Sie einen Link an, damit wir das Problem leichter erkennen können.
Argiropoulos Stavros
Ich habe das gleiche Problem. Würde gerne eine Lösung kennen.
Herman Schaaf
.map.map war absichtlich da. Das erste bezog sich auf mein Kartenobjekt und das zweite auf das Google-Kartenobjekt. Ich habe dieses Problem seitdem aus meinem Code entfernt.
Andrew De Andrade
siehe stackoverflow.com/questions/2437683/…
Mawg sagt, Monica am

Antworten:

112

Okay, ich habe es herausgefunden. Anscheinend geschieht fitbounds () asynchron, sodass Sie auf ein bounds_changedEreignis warten müssen, bevor die Einstellung des Zooms funktioniert.

map = this.map.map;

map.fitBounds(this.map.bounds);
zoomChangeBoundsListener = 
    google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
        if (this.getZoom()){
            this.setZoom(16);
        }
});
setTimeout(function(){google.maps.event.removeListener(zoomChangeBoundsListener)}, 2000);

Update : In der Antwort von @ Nequin finden Sie addListenerOnceeine bessere Lösung, für die keine Zeitüberschreitung erforderlich ist.

Herman Schaaf
quelle
10
Gute Lösung, hat auch bei mir funktioniert. Obwohl Sie hätten tun können, addListenerOnce()was den removeListener()Anruf abschaffen würde .
Mike Purcell
2
Zusätzlich zur Verwendung von addListenerOnce würde ich die Verwendung von setTimeout empfehlen, um den Listener zu entfernen. Ich hatte einen Fall, in dem sich die Grenzen nicht änderten, weil die Markierungen nahe beieinander lagen. Mit diesem Code kann der Benutzer (mindestens einmal) nicht zoomen.
h0tw1r3
@ MikePurcell & h0tw1r3: Ich habe den Code bearbeitet, um Ihre Vorschläge hinzuzufügen, danke! Habe es nicht getestet, also hoffe ich habe keine dummen Fehler gemacht.
Herman Schaaf
@Herman ..... Danke Hermann, ich habe ungefähr 3 Stunden an diesem Problem festgehalten ... Danke nochmal ...
Usman
1
Ich musste den removeListener in die AddListener-Rückruffunktion einfügen. Andernfalls würde die Ausführung den Listener entfernen, noch bevor er aufgerufen wird.
Arman Bimatov
106
google.maps.event.addListenerOnce(yourMap, 'bounds_changed', function(event) {
  if (this.getZoom() > 15) {
    this.setZoom(15);
  }
});

Diese Lösung funktioniert besser ... anstatt auf eine Zeitüberschreitung zu warten, um den Listener zu entfernen. Rufen Sie dies direkt vor der Verwendung auf fitBounds(ich glaube, dass das Anrufen danach auch funktioniert).

Nequin
quelle
4
Gute Lösung. Könnte es besser machen, google.maps.event.addListenerOnceindem Sie den Listener verwenden, anstatt ihn hinzuzufügen und dann zu entfernen.
Chuck w
3
Ich habe mir erlaubt, die zu verwendende Antwort zu bearbeiten addListenerOnce.
Mathias Bynens
1
Diese Lösung funktioniert bei mir nicht. this.getZoom () ist im Rückruf immer undefiniert und this.setZoom () hat keine Auswirkung.
Horace
Perfekte, beste Antwort
00-BBB
Denken Sie daran , die Probleme mit dieser Ich würde stattdessen den Verweis auf die an den Ereignishandler übergeben Karte verwenden, wie folgt aus : if (yourMap.getZoom() > 15) { ... }. Es scheint, dass @horace Probleme damit hatte und dies bezieht sich wahrscheinlich auf die aktuelle Klasse, in der die Implementierung durchgeführt wird, oder auf die google.maps.eventInstanz. Vermeiden Sie dies, wenn Sie einfach den übergebenen Verweis auf Ihre Karte verwenden möchten.
Sparker73
16

Ich fand den zusätzlichen Zoom etwas verwirrend. Wenn Sie die Option maxZoom festlegen, bevor Sie fitBounds aufrufen (und sie dann im Rückruf deaktivieren), können Sie dies vermeiden:

map.setOptions({
    maxZoom: 10
});

map.setCenter(new google.maps.LatLng(-89, -179)); // make sure it changes so the idle listener gets called back

map.fitBounds(bounds);

var listener = google.maps.event.addListenerOnce(map, "idle", function()
{
    map.setOptions({
        maxZoom: 999
    });
});
Emery Lapinski
quelle
Eine viel bessere Lösung, da das Einstellen des Zooms nach dem Ändern der Grenzen (wie in den anderen Antworten vorgeschlagen) nicht reibungslos ist und tatsächlich sehr hässlich ist.
Pedro Estevao
2

Ich habe eine einfache und schmutzige Lösung.
Verwenden Sie If else ...

var marker = this.map.createMarker(view.latlng, this.markerNumber);
this.map.bounds.extend(view.latlng);
this.map.map.setCenter(this.map.bounds.getCenter()); 
if (this.markerNumber === 1) {
  this.map.map.setZoom(16);
} else {
   this.map.map.fitBounds(this.map.bounds);
}       
this.markerNumber++;
Vishwanath
quelle
1
Aber wissen Sie, warum die beiden nicht zusammenarbeiten? Ich verstehe nicht, warum diese nicht kompatibel sind, wenn sie seriell aufgerufen werden.
Andrew De Andrade
1

Ich habe der Funktion nur eine Zeile hinzugefügt addBounds(position)und sie wurde behoben, wie Folgendes zeigt:

    addBounds: function(position) {
        this.get('bounds', new google.maps.LatLngBounds()).extend(this._latLng(position));
        this.get('map').fitBounds(this.get('bounds'));
        this.get('map').setZoom(16);//line added
        return this;
    },
Mirek Komárek
quelle
0

Alle Lösungen mit Ereignis-Listenern haben bei mir nicht funktioniert (this.getZoom () ist im Rückruf immer undefiniert und this.setZoom () hat keine Auswirkung).

Ich habe mir diese Lösung ausgedacht, die gut funktioniert hat:

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);
horace
quelle