Ich suche nach einer Möglichkeit, die Zoomstufe für bestimmte Grenzen mithilfe der Google Maps V3-API zu berechnen, ähnlich wie getBoundsZoomLevel()
in der V2-API.
Folgendes möchte ich tun:
// These are exact bounds previously captured from the map object
var sw = new google.maps.LatLng(42.763479, -84.338918);
var ne = new google.maps.LatLng(42.679488, -84.524313);
var bounds = new google.maps.LatLngBounds(sw, ne);
var zoom = // do some magic to calculate the zoom level
// Set the map to these exact bounds
map.setCenter(bounds.getCenter());
map.setZoom(zoom);
// NOTE: fitBounds() will not work
Leider kann ich die fitBounds()
Methode für meinen speziellen Anwendungsfall nicht verwenden . Es eignet sich gut zum Anpassen von Markierungen auf der Karte, aber nicht zum Festlegen exakter Grenzen. Hier ist ein Beispiel, warum ich die fitBounds()
Methode nicht verwenden kann.
map.fitBounds(map.getBounds()); // not what you expect
google-maps
google-maps-api-3
Nick Clark
quelle
quelle
fitBounds()
. In dieser Frage wird gefragt, was zu tun ist, wennfitBounds()
dies nicht ausreicht - entweder weil es überzoomt oder Sie nicht zoomen möchten (dh Sie möchten nur die Zoomstufe).Antworten:
Eine ähnliche Frage wurde in der Google-Gruppe gestellt: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/e6448fc197c3c892
Die Zoomstufen sind diskret, wobei sich die Skalierung in jedem Schritt verdoppelt. Im Allgemeinen können Sie die gewünschten Grenzen also nicht genau anpassen (es sei denn, Sie haben großes Glück mit der jeweiligen Kartengröße).
Ein weiteres Problem ist das Verhältnis zwischen den Seitenlängen, z. B. können Sie die Grenzen nicht genau an ein dünnes Rechteck innerhalb einer quadratischen Karte anpassen.
Es gibt keine einfache Antwort darauf, wie exakte Grenzen angepasst werden sollen, denn selbst wenn Sie bereit sind, die Größe des Map Div zu ändern, müssen Sie auswählen, auf welche Größe und welche Zoomstufe Sie sich ändern möchten (grob gesagt, machen Sie es größer oder kleiner) als es derzeit ist?).
Wenn Sie den Zoom wirklich berechnen müssen, anstatt ihn zu speichern, sollte dies den Trick tun:
Die Mercator-Projektion verzerrt den Breitengrad, aber jeder Längenunterschied entspricht immer dem gleichen Bruchteil der Breite der Karte (der Winkeldifferenz in Grad / 360). Bei Zoom Null beträgt die gesamte Weltkarte 256 x 256 Pixel, und durch Zoomen jeder Ebene werden sowohl Breite als auch Höhe verdoppelt. Nach einer kleinen Algebra können wir den Zoom wie folgt berechnen, vorausgesetzt, wir kennen die Breite der Karte in Pixel. Beachten Sie, dass wir sicherstellen müssen, dass der Winkel positiv ist, da sich der Längengrad dreht.
quelle
Vielen Dank an Giles Gardam für seine Antwort, die jedoch nur den Längen- und nicht den Breitengrad anspricht. Eine vollständige Lösung sollte die für den Breitengrad erforderliche Zoomstufe und die für den Längengrad erforderliche Zoomstufe berechnen und dann die kleinere (weiter außen liegende) der beiden herausnehmen.
Hier ist eine Funktion, die sowohl Breiten- als auch Längengrade verwendet:
Demo on jsfiddle
Parameter:
Der Parameterwert "Grenzen" sollte ein
google.maps.LatLngBounds
Objekt sein.Der Parameterwert "mapDim" sollte ein Objekt mit den Eigenschaften "height" und "width" sein, die die Höhe und Breite des DOM-Elements darstellen, das die Karte anzeigt. Sie können diese Werte verringern, wenn Sie das Auffüllen sicherstellen möchten. Das heißt, Sie möchten möglicherweise nicht, dass Kartenmarkierungen innerhalb der Grenzen zu nahe am Rand der Karte liegen.
Wenn Sie die jQuery-Bibliothek verwenden, kann der
mapDim
Wert wie folgt abgerufen werden:Wenn Sie die Prototype-Bibliothek verwenden, kann der mapDim-Wert wie folgt abgerufen werden:
Rückgabewert:
Der Rückgabewert ist die maximale Zoomstufe, bei der weiterhin die gesamten Grenzen angezeigt werden. Dieser Wert liegt zwischen
0
und einschließlich der maximalen Zoomstufe.Die maximale Zoomstufe beträgt 21. (Ich glaube, es waren nur 19 für Google Maps API v2.)
Erläuterung:
Google Maps verwendet eine Mercator-Projektion. In einer Mercator-Projektion sind die Längengrade gleich beabstandet, die Breitengrade jedoch nicht. Der Abstand zwischen den Breitengraden nimmt zu, wenn sie vom Äquator zu den Polen verlaufen. Tatsächlich tendiert die Entfernung gegen unendlich, wenn sie die Pole erreicht. Eine Google Maps-Karte zeigt jedoch keine Breiten über ungefähr 85 Grad Nord oder unter ungefähr -85 Grad Süd. ( Referenz ) (Ich berechne den tatsächlichen Grenzwert bei +/- 85.05112877980658 Grad.)
Dies macht die Berechnung der Brüche für die Grenzen für den Breitengrad komplizierter als für den Längengrad. Ich habe eine Formel aus Wikipedia verwendet , um den Breitengradanteil zu berechnen. Ich gehe davon aus, dass dies mit der von Google Maps verwendeten Projektion übereinstimmt. Schließlich enthält die oben verlinkte Google Maps-Dokumentationsseite einen Link zu derselben Wikipedia-Seite.
Weitere Hinweise:
quelle
fitBounds
müssen Sie die Karte erstellen und dann auf das Ereignis "bounds_changed" warten.map.getProjection()
würde einen Teil der Mathematik (und die Annahme über die Projektion) eliminieren, aber dies würde bedeuten, dass die Funktion erst aufgerufen werden könnte, nachdem die Karte erstellt und das Ereignis "projection_changed" ausgelöst wurde.Für Version 3 der API ist dies einfach und funktioniert:
und einige optionale Tricks:
quelle
maxZoom
verhindert jedoch , dass der Benutzer manuell zoomt. Mein Beispiel ändert den DefaultZoom nur und nur, wenn es notwendig ist.getBoundsZoomLevel
. Auf diese Weise wird beim Aufrufen von setZoom die gewünschte Zoomstufe animiert. Von dort aus ist es kein Problem, das panTo zu machen, und Sie erhalten eine wunderschöne Kartenanimation, die den Grenzen entsprichtHier eine Kotlin-Version der Funktion:
quelle
Vielen Dank, das hat mir sehr geholfen, den am besten geeigneten Zoomfaktor für die korrekte Anzeige einer Polylinie zu finden. Ich finde die maximalen und minimalen Koordinaten unter den Punkten, die ich verfolgen muss, und falls der Pfad sehr "vertikal" ist, habe ich nur einige Codezeilen hinzugefügt:
Tatsächlich ist der ideale Zoomfaktor Zoomfaktor 1.
quelle
var zoomfactor = Math.floor(Math.log(960 * 360 / angle / GLOBE_WIDTH) / Math.LN2)-1;
. Trotzdem sehr hilfreich.Da alle anderen Antworten Probleme mit den einen oder anderen Umständen (Kartenbreite / -höhe, Grenzbreite / -höhe usw.) für mich zu haben scheinen, dachte ich, ich würde meine Antwort hier einfügen ...
Hier gab es eine sehr nützliche Javascript-Datei: http://www.polyarc.us/adjust.js
Ich habe das als Basis dafür verwendet:
Sie können dies sicherlich bereinigen oder bei Bedarf minimieren, aber ich habe die Variablennamen lange beibehalten, um das Verständnis zu erleichtern.
Wenn Sie sich fragen, woher OFFSET stammt, ist 268435456 anscheinend die Hälfte des Erdumfangs in Pixel bei Zoomstufe 21 (laut http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google) -Karten ).
quelle
Valerio hat mit seiner Lösung fast recht, aber es gibt einen logischen Fehler.
Sie müssen zuerst prüfen, ob Winkel2 größer als Winkel ist, bevor Sie 360 bei einem Negativ hinzufügen.
Andernfalls haben Sie immer einen größeren Wert als den Winkel
Die richtige Lösung lautet also:
Delta ist da, weil ich eine größere Breite als Höhe habe.
quelle
map.getBounds()
ist keine momentane Operation, daher verwende ich in einem ähnlichen Fall Event Handler. Hier ist mein Beispiel in Coffeescriptquelle
Arbeitsbeispiel zum Finden eines durchschnittlichen Standardcenters mit React-Google-Maps auf
ES6
:quelle
Die Berechnung der Zoomstufe für die Längen von Giles Gardam funktioniert für mich gut. Wenn Sie den Zoomfaktor für den Breitengrad berechnen möchten, ist dies eine einfache Lösung, die einwandfrei funktioniert:
quelle