Estou procurando uma maneira de calcular o nível de zoom para um determinado limite usando a API V3 do Google Maps, semelhante à getBoundsZoomLevel()
API V2.
Aqui está o que eu quero fazer:
// 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
Infelizmente, não posso usar o fitBounds()
método para meu caso de uso específico. Ele funciona bem para ajustar marcadores no mapa, mas não funciona bem para definir limites exatos. Aqui está um exemplo de por que não posso usar o fitBounds()
método
map.fitBounds(map.getBounds()); // not what you expect
google-maps
google-maps-api-3
Nick Clark
fonte
fonte
fitBounds()
. Esta pergunta pergunta o que fazer quandofitBounds()
é insuficiente - ou porque o zoom é excessivo ou você não deseja aumentar o zoom (ou seja, você deseja apenas o nível de zoom).Respostas:
Uma pergunta semelhante foi feita no grupo do Google: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/e6448fc197c3c892
Os níveis de zoom são discretos, com a escala dobrando em cada etapa. Portanto, em geral, você não pode ajustar exatamente os limites que deseja (a menos que tenha muita sorte com o tamanho do mapa).
Outra questão é a relação entre os comprimentos laterais, por exemplo, você não pode ajustar os limites exatamente a um retângulo fino dentro de um mapa quadrado.
Não há uma resposta fácil sobre como ajustar limites exatos, porque, mesmo se você estiver disposto a alterar o tamanho da div do mapa, terá que escolher para qual tamanho e nível de zoom correspondente será alterado (grosso modo, você o torna maior ou menor) do que é atualmente?).
Se você realmente precisar calcular o zoom, em vez de armazená-lo, faça o seguinte:
A projeção de Mercator distorce a latitude, mas qualquer diferença de longitude sempre representa a mesma fração da largura do mapa (a diferença de ângulo em graus / 360). No zoom zero, o mapa do mundo inteiro tem 256x256 pixels e o zoom de cada nível dobra a largura e a altura. Então, depois de um pouco de álgebra, podemos calcular o zoom da seguinte forma, desde que saibamos a largura do mapa em pixels. Observe que, como a longitude gira em torno, precisamos garantir que o ângulo seja positivo.
fonte
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:
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:Se você estiver usando a biblioteca Prototype, o valor mapDim pode ser obtido da seguinte maneira:
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:
fonte
fitBounds
, você precisa criar o mapa e aguardar o evento "bounds_changed".map.getProjection()
eliminaria parte da matemática (e a suposição sobre a projeção), mas significaria que a função não poderia ser chamada até que o mapa fosse criado e o evento "projection_changed" fosse acionado.Para a versão 3 da API, isso é simples e funcional:
e alguns truques opcionais:
fonte
maxZoom
impedirá que o usuário faça zoom manual . Meu exemplo altera apenas o DefaultZoom e somente se for necessário.getBoundsZoomLevel
. Dessa forma, quando você chama setZoom, ele anima para o nível de zoom desejado. De lá, ele não é um problema para fazer o panTo e você acaba com uma bela animação mapa que se encaixa nos limitesAqui está uma versão da função Kotlin:
fonte
Obrigado, isso me ajudou muito a encontrar o fator de zoom mais adequado para exibir corretamente uma polilinha. Encontro as coordenadas máxima e mínima entre os pontos que tenho que rastrear e, caso o caminho seja muito "vertical", apenas adicionei algumas linhas de código:
Na verdade, o fator de zoom ideal é o fator de zoom-1.
fonte
var zoomfactor = Math.floor(Math.log(960 * 360 / angle / GLOBE_WIDTH) / Math.LN2)-1;
. Ainda assim, muito útil.Como todas as outras respostas parecem ter problemas para mim com um ou outro conjunto de circunstâncias (largura / altura do mapa, largura / altura dos limites etc.), imaginei que colocaria minha resposta aqui ...
Havia um arquivo javascript muito útil aqui: http://www.polyarc.us/adjust.js
Eu usei isso como base para isso:
Você pode certamente limpar ou reduzi-lo, se necessário, mas mantive os nomes das variáveis por muito tempo, na tentativa de facilitar o entendimento.
Se você está se perguntando de onde veio o OFFSET, aparentemente 268435456 é metade da circunferência da Terra em pixels no nível de zoom 21 (de acordo com http://www.appelsiini.net/2008/11/11/introduction-to-marker-clustering-with-google -maps ).
fonte
Valério está quase certo com sua solução, mas há algum erro lógico.
você deve primeiro verificar se o ângulo2 é maior que o ângulo, antes de adicionar 360 em negativo.
caso contrário, você sempre terá um valor maior que o ângulo
Portanto, a solução correta é:
Delta está lá, porque eu tenho uma largura maior que a altura.
fonte
map.getBounds()
não é uma operação momentânea, então eu uso em um manipulador de eventos de caso semelhante. Aqui está o meu exemplo no Coffeescriptfonte
Exemplo de trabalho para encontrar o centro padrão médio com react-google-maps em
ES6
:fonte
O cálculo do nível de zoom para as longitudes de Giles Gardam funciona bem para mim. Se você deseja calcular o fator de zoom para latitude, esta é uma solução fácil que funciona bem:
fonte