Agradeço a Giles Gardam por sua resposta, mas trata apenas da longitude e não da latitude. Uma solução completa deve calcular o nível de zoom necessário para a latitude e o nível de zoom necessário para a longitude e, em seguida, tirar o menor (mais distante) dos dois.
Aqui está uma função que usa latitude e longitude:
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
Parâmetros:
O valor do parâmetro "bounds" deve ser um google.maps.LatLngBounds
objeto.
O valor do parâmetro "mapDim" deve ser um objeto com as propriedades "height" e "width" que representam a altura e a largura do elemento DOM que exibe o mapa. Você pode diminuir esses valores se quiser garantir o preenchimento. Ou seja, talvez você não queira que os marcadores de mapa dentro dos limites fiquem muito perto da borda do mapa.
Se você estiver usando a biblioteca jQuery, o mapDim
valor poderá ser obtido da seguinte maneira:
var $mapDiv = $('#mapElementId');
var mapDim = { height: $mapDiv.height(), width: $mapDiv.width() };
Se você estiver usando a biblioteca Prototype, o valor mapDim pode ser obtido da seguinte maneira:
var mapDim = $('mapElementId').getDimensions();
Valor de retorno:
O valor de retorno é o nível máximo de zoom que ainda exibirá os limites inteiros. Este valor estará entre 0
e o nível máximo de zoom, inclusive.
O nível máximo de zoom é 21. (Creio que eram apenas 19 para a API do Google Maps v2.)
Explicação:
O Google Maps usa uma projeção Mercator. Em uma projeção de Mercator, as linhas de longitude são igualmente espaçadas, mas as linhas de latitude não. A distância entre as linhas de latitude aumenta à medida que vão do equador aos pólos. De fato, a distância tende ao infinito quando atinge os pólos. Um mapa do Google Maps, no entanto, não mostra latitudes acima de aproximadamente 85 graus norte ou abaixo de -85 graus sul. ( referência ) (eu calculo o ponto de corte real em +/- 85,05112877980658 graus.)
Isso torna o cálculo das frações para os limites mais complicado para latitude do que para longitude. Eu usei uma fórmula da Wikipedia para calcular a fração de latitude. Suponho que isso corresponda à projeção usada pelo Google Maps. Afinal, a página de documentação do Google Maps que eu vinculo acima contém um link para a mesma página da Wikipedia.
Outras notas:
- Os níveis de zoom variam de 0 ao nível máximo de zoom. O nível de zoom 0 é o mapa totalmente diminuído. Níveis mais altos aumentam o zoom do mapa. ( referência )
- No nível de zoom 0, o mundo inteiro pode ser exibido em uma área com 256 x 256 pixels. ( referência )
- Para cada nível de zoom mais alto, o número de pixels necessários para exibir a mesma área dobra em largura e altura. ( referência )
- Mapas quebram na direção longitudinal, mas não na direção latitudinal.