Дякую Джайлсу Гардаму за свою відповідь, але він стосується лише довготи, а не широти. Повне рішення повинно розраховувати рівень масштабу, необхідний для широти, і рівень масштабу, необхідний для довготи, а потім брати менший (далі) з двох.
Ось функція, яка використовує і широту, і довготу:
function getBoundsZoomLevel(bounds, mapDim) {
var WORLD_DIM = { height: 256, width: 256 };
var ZOOM_MAX = 21;
function latRad(lat) {
var sin = Math.sin(lat * Math.PI / 180);
var radX2 = Math.log((1 + sin) / (1 - sin)) / 2;
return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2;
}
function zoom(mapPx, worldPx, fraction) {
return Math.floor(Math.log(mapPx / worldPx / fraction) / Math.LN2);
}
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
var latFraction = (latRad(ne.lat()) - latRad(sw.lat())) / Math.PI;
var lngDiff = ne.lng() - sw.lng();
var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;
var latZoom = zoom(mapDim.height, WORLD_DIM.height, latFraction);
var lngZoom = zoom(mapDim.width, WORLD_DIM.width, lngFraction);
return Math.min(latZoom, lngZoom, ZOOM_MAX);
}
Demo on jsfiddle
Параметри:
Значення параметра "межа" має бути google.maps.LatLngBounds
об'єктом.
Значення параметра "mapDim" має бути об'єктом із властивостями "висота" та "ширина", які представляють висоту та ширину елемента DOM, який відображає карту. Ви можете зменшити ці значення, якщо хочете забезпечити прокладку. Тобто, можливо, ви не хочете, щоб маркери карт в межах були занадто близькими до краю карти.
Якщо ви використовуєте бібліотеку jQuery, mapDim
значення можна отримати таким чином:
var $mapDiv = $('#mapElementId');
var mapDim = { height: $mapDiv.height(), width: $mapDiv.width() };
Якщо ви використовуєте бібліотеку прототипів, значення mapDim можна отримати таким чином:
var mapDim = $('mapElementId').getDimensions();
Повернене значення:
Повернене значення - це максимальний рівень масштабування, який все одно відображатиме цілі межі. Це значення буде між 0
і максимальним рівнем збільшення, включно.
Максимальний рівень масштабування - 21. (Я вважаю, що для API Карт Google v2 було лише 19).
Пояснення:
Карти Google використовують проекцію Меркатора. У проекції Меркатора лінії довготи однаково розташовані, але лінії широти - ні. Відстань між лініями широти збільшується, коли вони йдуть від екватора до полюсів. Насправді відстань тяжіє до нескінченності, коли воно досягає полюсів. Однак на карті Карт Google не відображаються широти вище приблизно 85 градусів на північ або нижче приблизно -85 градусів на південь. ( довідка ) (я обчислюю фактичне скорочення при +/- 85.05112877980658 градусів.)
Це робить обчислення дробів для меж складнішими для широти, ніж для довготи. Я використовував формулу з Вікіпедії для обчислення частки широти. Я припускаю, що це відповідає проекції, яку використовує Google Maps. Зрештою, сторінка документації Google Maps, на яку я посилаюсь вище, містить посилання на ту саму сторінку Вікіпедії.
Інші примітки:
- Рівні масштабу варіюються від 0 до максимального рівня збільшення. Рівень масштабу 0 - це карта, повністю зменшена. Більш високі рівні збільшують масштаб карти. ( довідник )
- При рівні масштабу 0 весь світ може відображатися в області, що становить 256 х 256 пікселів. ( довідник )
- Для кожного більшого рівня збільшення кількість пікселів, необхідних для відображення однієї і тієї ж області, подвоюється як по ширині, так і по висоті. ( довідник )
- Карти загортаються в поздовжньому напрямку, але не в широтному напрямку.