Спасибо Giles Gardam за его ответ, но он касается только долготы, а не широты. Полное решение должно рассчитать уровень масштабирования, необходимый для широты, и уровень масштабирования, необходимый для долготы, а затем взять меньшее (дальше) из двух.
Вот функция, которая использует широту и долготу:
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);
}
Демонстрация на jsfiddle
Параметры:
Значением параметра "bounds" должен быть объект google.maps.LatLngBounds
.
Значением параметра «mapDim» должен быть объект со свойствами «height» и «width», которые представляют высоту и ширину элемента DOM, отображающего карту. Вы можете уменьшить эти значения, если хотите обеспечить заполнение. То есть вы не хотите, чтобы маркеры карты в пределах границ находились слишком близко к краю карты.
Если вы используете библиотеку jQuery, значение mapDim
можно получить следующим образом:
var $mapDiv = $('#mapElementId');
var mapDim = { height: $mapDiv.height(), width: $mapDiv.width() };
Если вы используете библиотеку Prototype, значение mapDim можно получить следующим образом:
var mapDim = $('mapElementId').getDimensions();
Возвращаемое значение:
Возвращаемое значение - это максимальный уровень масштабирования, который будет отображать все границы. Это значение будет между 0
и максимальным уровнем масштабирования включительно.
Максимальный уровень масштабирования составляет 21. (Я полагаю, что это был только 19 для Google Maps API v2.)
Пояснение:
Карты Google используют проекцию Меркатора. В проекции Меркатора линии долготы расположены на одинаковом расстоянии, а линии широты - нет. Расстояние между линиями широты увеличивается по мере их продвижения от экватора к полюсам. На самом деле расстояние стремится к бесконечности, когда достигает полюсов. Карта Google Карты, однако, не показывает широты выше приблизительно 85 градусов северной широты или ниже -85 градусов южной широты. ( ссылка ) (Я рассчитываю фактическую отсечку при +/- 85.05112877980658 градусах.)
Это усложняет вычисление дробей для границ по широте, а не по долготе. Я использовал формулу из Википедии для вычисления доли широты. Я предполагаю, что это соответствует проекции, используемой Google Maps. В конце концов, страница документации Google Карт, на которую я ссылаюсь выше, содержит ссылку на ту же страницу Википедии.
Другие примечания:
- Уровни масштабирования варьируются от 0 до максимального уровня масштабирования. Уровень масштабирования 0 - карта полностью уменьшена. Более высокие уровни увеличивают карту дальше. ( ссылка * +1050 *) * * тысяча пятьдесят-один
При уровне масштабирования 0 весь мир может отображаться в области размером 256 x 256 пикселей. ( ссылка * 1 054 *)
- Для каждого более высокого уровня масштабирования количество пикселей, необходимое для отображения одной и той же области, удваивается как по ширине, так и по высоте. (* * Ссылка тысяча пятьдесят семь * * тысяча пятьдесят-восемь)
- Карты переносятся в продольном направлении, но не в широтном направлении.