Спасибо Джайлзу Гардаму за его ответ, но он касается только долготы, а не широты. Полное решение должно рассчитать уровень масштабирования, необходимый для широты, и уровень масштабирования, необходимый для долготы, а затем взять меньшее (дальнее) из двух.
Вот функция, которая использует широту и долготу:
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
Параметры:
Значение параметра "bounds" должно быть google.maps.LatLngBounds
объектом.
Значение параметра «mapDim» должно быть объектом со свойствами «высота» и «ширина», которые представляют высоту и ширину элемента 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 Maps не показывает широту выше примерно 85 градусов северной широты или ниже примерно -85 градусов южной широты. (для справки ) (Я рассчитал фактическое значение отсечки на +/- 85,05112877980658 градусов.)
Это усложняет вычисление дробей для границ для широты, чем для долготы. Я использовал формулу из Википедии, чтобы вычислить долю широты. Я предполагаю, что это соответствует проекции, используемой Google Maps. В конце концов, страница документации Google Maps, на которую я ссылаюсь выше, содержит ссылку на ту же страницу Википедии.
Прочие примечания:
- Уровни масштабирования варьируются от 0 до максимального уровня масштабирования. Уровень масштабирования 0 - это полностью уменьшенная карта. Более высокие уровни увеличивают масштаб карты. ( ссылка )
- При уровне масштабирования 0 весь мир может отображаться в области размером 256 x 256 пикселей. ( ссылка )
- Для каждого более высокого уровня масштабирования количество пикселей, необходимых для отображения одной и той же области, удваивается как по ширине, так и по высоте. ( ссылка )
- Карты разворачиваются в продольном направлении, но не в широтном направлении.