Szukam sposobu na obliczenie poziomu powiększenia dla zadanych granic za pomocą Google Maps V3 API, podobnie jak getBoundsZoomLevel()
w V2 API.
Oto, co chcę zrobić:
// 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
Niestety nie mogę użyć tej fitBounds()
metody w moim konkretnym przypadku użycia. Działa dobrze przy dopasowywaniu znaczników na mapie, ale nie sprawdza się dobrze przy ustawianiu dokładnych granic. Oto przykład, dlaczego nie mogę użyć tej fitBounds()
metody.
map.fitBounds(map.getBounds()); // not what you expect
google-maps
google-maps-api-3
Nick Clark
źródło
źródło
fitBounds()
. To pytanie dotyczy tego, co zrobić, gdyfitBounds()
jest niewystarczające - albo dlatego, że powiększa lub nie chcesz powiększać (tj. Chcesz tylko poziom powiększenia).Odpowiedzi:
Podobne pytanie zostało zadane na grupie Google: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/e6448fc197c3c892
Poziomy powiększenia są dyskretne, a skala podwaja się w każdym kroku. Więc ogólnie nie możesz dokładnie dopasować granic, które chcesz (chyba że masz szczęście z określonym rozmiarem mapy).
Inną kwestią jest stosunek długości boków, np. Nie można dopasować granic dokładnie do cienkiego prostokąta wewnątrz kwadratowej mapy.
Nie ma łatwej odpowiedzi na to, jak dopasować dokładne granice, ponieważ nawet jeśli chcesz zmienić rozmiar div mapy, musisz wybrać rozmiar i odpowiedni poziom powiększenia, na który się zmieniasz (z grubsza mówiąc, czy zwiększysz czy zmniejszysz niż jest obecnie?).
Jeśli naprawdę potrzebujesz obliczyć powiększenie, zamiast go przechowywać, powinno to załatwić sprawę:
Odwzorowanie Mercatora powoduje wypaczenie szerokości geograficznej, ale każda różnica długości geograficznej zawsze reprezentuje ten sam ułamek szerokości mapy (różnica kątów w stopniach / 360). Przy zerowym powiększeniu cała mapa świata ma 256x256 pikseli, a powiększanie każdego poziomu podwaja szerokość i wysokość. Więc po małej algebrze możemy obliczyć powiększenie w następujący sposób, pod warunkiem, że znamy szerokość mapy w pikselach. Zwróć uwagę, że ponieważ długość geograficzna zawija się wokół, musimy upewnić się, że kąt jest dodatni.
źródło
Dziękuję Gilesowi Gardamowi za jego odpowiedź, ale dotyczy tylko długości geograficznej, a nie szerokości geograficznej. Kompletne rozwiązanie powinno obliczyć poziom powiększenia wymagany dla szerokości geograficznej i poziom powiększenia wymagany dla długości geograficznej, a następnie wziąć mniejszy (dalej) z tych dwóch.
Oto funkcja, która używa zarówno szerokości, jak i długości geograficznej:
Demo on jsfiddle
Parametry:
Wartość parametru „bounds” powinna wynosić a
google.maps.LatLngBounds
obiektem.Wartość parametru „mapDim” powinna być obiektem z właściwościami „height” i „width”, które reprezentują wysokość i szerokość elementu DOM wyświetlającego mapę. Możesz chcieć zmniejszyć te wartości, jeśli chcesz zapewnić dopełnienie. Oznacza to, że możesz nie chcieć, aby znaczniki mapy w granicach znajdowały się zbyt blisko krawędzi mapy.
Jeśli korzystasz z biblioteki jQuery,
mapDim
wartość można uzyskać w następujący sposób:Jeśli używasz biblioteki Prototype, wartość mapDim można uzyskać w następujący sposób:
Wartość zwracana:
Wartość zwracana to maksymalny poziom powiększenia, który nadal będzie wyświetlał całe granice. Ta wartość będzie wynosić między
0
od maksymalnego poziomu powiększenia włącznie.Maksymalny poziom powiększenia to 21. (myślę, że było to tylko 19 dla Google Maps API v2.)
Wyjaśnienie:
Mapy Google używają odwzorowania Mercator. W rzucie Mercatora linie długości geograficznej są równomiernie rozmieszczone, ale linie szerokości geograficznej nie. Odległość między liniami szerokości geograficznej zwiększa się w miarę przechodzenia od równika do biegunów. W rzeczywistości odległość zbliża się do nieskończoności, gdy dociera do biegunów. Mapa Google Maps nie pokazuje jednak szerokości geograficznych powyżej około 85 stopni na północ ani poniżej około -85 stopni na południe. ( odniesienie ) (Obliczam faktyczną wartość odcięcia przy +/- 85,05112877980658 stopni.)
To sprawia, że obliczanie ułamków dla granic jest bardziej skomplikowane dla szerokości geograficznej niż dla długości geograficznej. Użyłem wzoru z Wikipedii, aby obliczyć ułamek szerokości geograficznej. Zakładam, że jest to zgodne z projekcją używaną przez Google Maps. W końcu strona dokumentacji Google Maps, do której odsyłam powyżej, zawiera link do tej samej strony Wikipedii.
Inne notatki:
źródło
fitBounds
musisz utworzyć mapę, a następnie poczekać na zdarzenie „bounds_changed”.map.getProjection()
wyeliminowałoby część matematyki (i założenie dotyczące odwzorowania), ale oznaczałoby to, że funkcja nie mogłaby zostać wywołana przed utworzeniem mapy i wywołaniem zdarzenia „projection_changed”.W przypadku wersji 3 interfejsu API jest to proste i działa:
i kilka opcjonalnych sztuczek:
źródło
maxZoom
uniemożliwi użytkownikowi ręczne powiększanie. Mój przykład zmienia tylko DefaultZoom i tylko wtedy, gdy jest to konieczne.getBoundsZoomLevel
. w ten sposób wywołanie setZoom powoduje animację do żądanego poziomu powiększenia. stamtąd nie ma problemu z zrobieniem panTo i kończy się piękną animacją mapy, która pasuje do granicTutaj wersja Kotlin funkcji:
źródło
Dzięki, to bardzo pomogło mi w znalezieniu najbardziej odpowiedniego współczynnika powiększenia, aby poprawnie wyświetlić polilinię. Maksymalne i minimalne współrzędne znajduję wśród punktów, które muszę śledzić i na wypadek, gdyby ścieżka była bardzo „pionowa”, dodałem tylko kilka wierszy kodu:
W rzeczywistości idealnym współczynnikiem powiększenia jest współczynnik zoom-1.
źródło
var zoomfactor = Math.floor(Math.log(960 * 360 / angle / GLOBE_WIDTH) / Math.LN2)-1;
. Wciąż bardzo pomocny.Ponieważ wszystkie inne odpowiedzi wydają się mieć dla mnie problemy z jednym lub innym zestawem okoliczności (szerokość / wysokość mapy, szerokość / wysokość granic itp.), Pomyślałem, że umieściłem swoją odpowiedź tutaj ...
Znajdował się tutaj bardzo przydatny plik javascript: http://www.polyarc.us/adjust.js
Użyłem tego jako podstawy do tego:
Z pewnością możesz to wyczyścić lub zminimalizować w razie potrzeby, ale zachowałem nazwy zmiennych przez długi czas, aby ułatwić zrozumienie.
Jeśli zastanawiasz się, skąd się wziął OFFSET, najwyraźniej 268435456 to połowa obwodu Ziemi w pikselach na poziomie powiększenia 21 (zgodnie z http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google -mapy ).
źródło
Valerio ma prawie rację ze swoim rozwiązaniem, ale jest jakiś logiczny błąd.
musisz najpierw sprawdzić, czy kąt2 jest większy niż kąt, zanim dodasz 360 na minusie.
w przeciwnym razie zawsze masz większą wartość niż kąt
Tak więc prawidłowe rozwiązanie to:
Delta jest tam, ponieważ mam większą szerokość niż wysokość.
źródło
map.getBounds()
nie jest operacją chwilową, więc używam w podobnym przypadku obsługi zdarzeń. Oto mój przykład w Coffeescriptźródło
Przykład pracy, aby znaleźć średnie domyślne centrum z reaktywnymi mapami google na
ES6
:źródło
Obliczanie poziomu powiększenia dla długości geograficznych Gilesa Gardama działa dobrze dla mnie. Jeśli chcesz obliczyć współczynnik powiększenia dla szerokości geograficznej, jest to łatwe rozwiązanie, które działa dobrze:
źródło