Ich habe eine Reihe von Punkten, die ich auf einer eingebetteten Google Map (API v3) zeichnen möchte. Ich möchte, dass die Grenzen alle Punkte berücksichtigen, es sei denn, die Zoomstufe ist zu niedrig (dh zu stark herausgezoomt). Mein Ansatz war wie folgt:
var bounds = new google.maps.LatLngBounds();
// extend bounds with each point
gmap.fitBounds(bounds);
gmap.setZoom( Math.max(6, gmap.getZoom()) );
Das funktioniert nicht. Die letzte Zeile "gmap.setZoom ()" ändert die Zoomstufe der Karte nicht, wenn sie direkt nach fitBounds aufgerufen wird.
Gibt es eine Möglichkeit, die Zoomstufe einer Grenze zu ermitteln, ohne sie auf die Karte anzuwenden? Andere Ideen, um dies zu lösen?
Antworten:
Bearbeiten : Siehe Matt Diamonds Kommentar unten.
Verstanden! Versuche dies:
Passen Sie an Ihre Bedürfnisse an.
quelle
Ich habe ein ähnliches Problem in einer meiner Apps gelöst. Ich war ein wenig verwirrt über Ihre Beschreibung des Problems, aber ich denke, Sie haben das gleiche Ziel, das ich hatte ...
In meiner App wollte ich eine oder mehrere Markierungen zeichnen und sicherstellen, dass auf der Karte alle angezeigt werden. Das Problem war, wenn ich mich ausschließlich auf die fitBounds-Methode verlassen würde, würde die Zoomstufe maximal sein, wenn es einen einzelnen Punkt gäbe - das war nicht gut.
Die Lösung bestand darin, fitBounds zu verwenden, wenn viele Punkte vorhanden waren, und setCenter + setZoom, wenn nur ein Punkt vorhanden war.
quelle
Ich bin mehrmals auf diese Seite gekommen, um die Antwort zu erhalten, und obwohl alle vorhandenen Antworten sehr hilfreich waren, haben sie mein Problem nicht genau gelöst.
Grundsätzlich stellte ich fest, dass das Ereignis 'zoom_changed' die Benutzeroberfläche der Karte daran hinderte, zu "überspringen", was passierte, als ich auf das Ereignis "idle" wartete.
Hoffe das hilft jemandem!
quelle
fitBounds()
wenn Siezoom_changed
bounds_changed
, dazoom_changed
es nicht ausgelöst werden muss, wennfitBounds
die Zoomstufe beibehalten wird. Mein Versuch jsfiddle.net/rHeMp/10 bestätigt das nicht, aber man sollte sich nicht auf undefiniertes Verhalten verlassen.Ich habe dies gerade behoben, indem ich maxZoom im Voraus eingestellt und anschließend entfernt habe. Beispielsweise:
quelle
Wenn ich mich nicht irre, gehe ich davon aus, dass alle Ihre Punkte auf der Karte mit der höchstmöglichen Zoomstufe sichtbar sein sollen. Ich habe dies erreicht, indem ich die Zoomstufe der Karte auf 16 initialisiert habe (nicht sicher, ob es die höchstmögliche Zoomstufe in V3 ist).
Danach habe ich die Grenzen gesetzt:
Ergebnis: Erfolg!
quelle
Ich benutze:
Dies verwendet die kleinere von 24 und die erforderliche Zoomstufe gemäß Ihrem Code, ändert jedoch wahrscheinlich den Zoom trotzdem und kümmert sich nicht darum, wie viel Sie herausgezoomt haben.
quelle
Bitte versuchen Sie dies:
quelle
Ich hatte das gleiche Problem und konnte es mit dem folgenden Code lösen. Dieses listener (
google.maps.addListenerOnce()
) -Ereignis wird nur einmal ausgelöst, unmittelbar nachdemmap.fitBounds()
es ausgeführt wurde. Es besteht also keine Notwendigkeitidle
.Zunächst wird die entsprechende Zoomstufe festgelegt, und der Benutzer kann über die anfängliche Zoomstufe hinaus vergrößern und verkleinern, da der Ereignis-Listener abgelaufen ist. Wenn beispielsweise nur
google.maps.addListener()
aufgerufen wurde, kann der Benutzer die angegebene Zoomstufe (in dem Fall 4) niemals überschreiten. Seit der Implementierunggoogle.maps.addListenerOnce()
kann der Benutzer auf jede von ihm gewählte Stufe zoomen.quelle
Hatte das gleiche Problem, musste viele Markierungen auf die Karte passen. Dies löste meinen Fall:
bounds.extend(objLatLng)
).Fitbounds ausführen, nachdem die Karte abgeschlossen ist:
quelle
Ich habe eine Lösung gefunden, die die Prüfung vor dem Anruf durchführt,
fitBounds
damit Sie nicht hinein- und plötzlich herauszoomenSie müssen ein wenig mit der Variablen minLatSpan herumspielen, um sie an die gewünschte Stelle zu bringen. Dies hängt sowohl von der Zoomstufe als auch von den Abmessungen des Kartenbereichs ab.
Sie können auch den Längengrad anstelle des Breitengrads verwenden
quelle
Ich habe viele falsche oder zu komplizierte Lösungen gesehen und mich daher entschlossen, eine funktionierende, elegante Lösung zu veröffentlichen .
Der Grund, warum Sie
setZoom()
nicht wie erwartet funktionieren, ist, dassfitBounds()
es asynchron ist. Es gibt also keine Garantie dafür, dass der Zoom sofort aktualisiert wird, aber Ihr Aufruf,setZoom()
sich darauf zu verlassen.Was Sie in Betracht ziehen könnten, ist das Festlegen der
minZoom
Kartenoption vor dem AufrufenfitBounds()
und das anschließende Löschen nach Abschluss des Vorgangs (damit Benutzer bei Bedarf weiterhin manuell herauszoomen können):Wenn Sie außerdem den maximalen Zoom einschränken möchten, können Sie denselben Trick mit der
maxZoom
Eigenschaft anwenden .Siehe die MapOptions-Dokumente .
quelle
Ich verwende dies, um sicherzustellen, dass die Zoomstufe eine festgelegte Stufe nicht überschreitet, damit ich weiß, dass Satellitenbilder verfügbar sind.
Fügen Sie dem
zoom_changed
Ereignis einen Listener hinzu . Dies hat den zusätzlichen Vorteil, dass die Zoomsteuerung auch auf der Benutzeroberfläche gesteuert wird.Nur ausführen,
setZoom
wenn Sie müssen, daher ist eineif
Anweisung gegenüberMath.max
oder vorzuziehenMath.min
So verhindern Sie, dass Sie zu weit herauszoomen:
quelle
In dieser Funktion müssen Sie Metadaten dynamisch hinzufügen, um den Geometrietyp nur zu speichern, da die Funktion eine beliebige Geometrie akzeptiert.
"fitGeometries" ist eine JSON-Funktion, die ein Kartenobjekt erweitert.
"geometries" ist ein generisches Javascript-Array, kein MVCArray ().
quelle
Diese Arbeit ist für mich mit API v3, aber mit festem Zoom:
quelle
Wie ich, wenn Sie nicht bereit sind, mit Zuhörern zu spielen, ist dies eine einfache Lösung, die ich mir ausgedacht habe: Fügen Sie eine Methode auf der Karte hinzu, die genau Ihren Anforderungen entspricht, wie diese:
Dann können Sie anrufen,
map.fitLmtdBounds(bounds)
anstattmap.fitBounds(bounds)
die Grenzen unter dem definierten Zoombereich festzulegen ... odermap.fitLmtdBounds(bounds,3,5)
den Zoombereich zu überschreiben.quelle
Bitte versuchen Sie dies.
Wenn dies für Sie hilfreich sein wird.
Alles Gute
quelle
Nach der Berechnung der Grenzen können Sie den Abstand zwischen der oberen linken und der unteren rechten Ecke überprüfen. Dann können Sie die Zoomstufe verstehen, indem Sie die Entfernung testen (wenn die Entfernung zu weit ist, wäre die Zoomstufe niedrig). Dann können Sie auswählen, ob Sie die Setbound-Methode oder setZoom verwenden möchten.
quelle
Ich schlage es nicht gerne vor, aber wenn Sie es versuchen müssen - rufen Sie zuerst an
gmap.fitBounds(bounds);
Erstellen Sie dann einen neuen Thread / eine neue AsyncTask, lassen Sie ihn etwa 20-50 ms lang schlafen und rufen Sie dann auf
gmap.setZoom( Math.max(6, gmap.getZoom()) );
aus dem UI-Thread (verwenden Sie einen Handler oder den
onPostExecute
Methode für AsyncTask).Ich weiß nicht, ob es funktioniert, nur ein Vorschlag. Ansonsten müssten Sie die Zoomstufe aus Ihren Punkten selbst berechnen, prüfen, ob sie zu niedrig ist, sie korrigieren und dann einfach anrufen
gmap.setZoom(correctedZoom)
quelle
Wenn 'bounds_changed' nicht richtig ausgelöst wird (manchmal scheint Google die Koordinaten nicht perfekt zu akzeptieren), sollten Sie stattdessen 'center_changed' verwenden.
Das Ereignis 'center_changed' wird bei jedem Aufruf von fitBounds () ausgelöst, obwohl es sofort und nicht unbedingt nach dem Verschieben der Karte ausgeführt wird.
Im Normalfall ist 'idle' immer noch der beste Ereignis-Listener, aber dies kann einigen Leuten helfen, die mit ihren fitBounds () -Aufrufen auf seltsame Probleme stoßen.
Siehe Google Maps FitBounds Callback
quelle
Um eine andere Lösung zu finden, stellte ich fest, dass der Ansatz "Auf bounds_changed-Ereignis warten und dann neuen Zoom festlegen" für mich nicht zuverlässig funktionierte. Ich glaube, ich habe manchmal angerufen,
fitBounds
bevor die Karte vollständig initialisiert wurde, und die Initialisierung verursachte ein Ereignis bounds_changed, das den Listener verbrauchte, bevorfitBounds
die Grenzen und die Zoomstufe geändert wurden. Am Ende hatte ich diesen Code, der bisher zu funktionieren scheint:quelle
Für mich war die einfachste Lösung:
quelle
quelle
Alles was ich getan habe ist:
Und es funktioniert mit der V3-API.
quelle