Je cherche un moyen de calculer le niveau de zoom pour une limite donnée à l'aide de l'API Google Maps V3, similaire à getBoundsZoomLevel()
l'API V2.
Voici ce que je veux faire:
// 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
Malheureusement, je ne peux pas utiliser la fitBounds()
méthode pour mon cas d'utilisation particulier. Cela fonctionne bien pour ajuster les marqueurs sur la carte, mais cela ne fonctionne pas bien pour définir des limites exactes. Voici un exemple des raisons pour lesquelles je ne peux pas utiliser la fitBounds()
méthode.
map.fitBounds(map.getBounds()); // not what you expect
google-maps
google-maps-api-3
Nick Clark
la source
la source
fitBounds()
. Cette question demande ce qu'il faut faire lorsque celafitBounds()
est insuffisant - soit parce que vous effectuez un zoom avant ou que vous ne voulez pas zoomer (c'est-à-dire que vous voulez juste le niveau de zoom).Réponses:
Une question similaire a été posée sur le groupe Google: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/e6448fc197c3c892
Les niveaux de zoom sont discrets, l'échelle doublant à chaque étape. Donc, en général, vous ne pouvez pas ajuster les limites que vous voulez exactement (sauf si vous êtes très chanceux avec la taille de la carte particulière).
Un autre problème est le rapport entre les longueurs de côté, par exemple vous ne pouvez pas ajuster les limites exactement à un rectangle fin à l'intérieur d'une carte carrée.
Il n'y a pas de réponse facile pour savoir comment ajuster les limites exactes, car même si vous êtes prêt à modifier la taille du div de la carte, vous devez choisir la taille et le niveau de zoom correspondant auquel vous changez (grosso modo, l'agrandissez-vous ou le réduisez-vous qu'il ne l'est actuellement?).
Si vous avez vraiment besoin de calculer le zoom, plutôt que de le stocker, cela devrait faire l'affaire:
La projection Mercator déforme la latitude, mais toute différence de longitude représente toujours la même fraction de la largeur de la carte (la différence d'angle en degrés / 360). Au zoom zéro, la carte du monde entier mesure 256x256 pixels et le zoom à chaque niveau double à la fois la largeur et la hauteur. Ainsi, après un peu d'algèbre, nous pouvons calculer le zoom comme suit, à condition de connaître la largeur de la carte en pixels. Notez que parce que la longitude s'enroule, nous devons nous assurer que l'angle est positif.
la source
Merci à Giles Gardam pour sa réponse, mais elle ne concerne que la longitude et non la latitude. Une solution complète devrait calculer le niveau de zoom nécessaire pour la latitude et le niveau de zoom nécessaire pour la longitude, puis prendre le plus petit (le plus éloigné) des deux.
Voici une fonction qui utilise à la fois la latitude et la longitude:
Demo on jsfiddle
Paramètres:
La valeur du paramètre «limites» doit être un
google.maps.LatLngBounds
objet.La valeur du paramètre "mapDim" doit être un objet avec des propriétés "height" et "width" qui représentent la hauteur et la largeur de l'élément DOM qui affiche la carte. Vous souhaiterez peut-être diminuer ces valeurs si vous souhaitez garantir un remplissage. Autrement dit, vous ne voudrez peut-être pas que les marqueurs de carte dans les limites soient trop proches du bord de la carte.
Si vous utilisez la bibliothèque jQuery, la
mapDim
valeur peut être obtenue comme suit:Si vous utilisez la bibliothèque Prototype, la valeur mapDim peut être obtenue comme suit:
Valeur de retour:
La valeur de retour est le niveau de zoom maximum qui affichera toujours toutes les limites. Cette valeur sera comprise entre
0
et le niveau de zoom maximum, inclus.Le niveau de zoom maximal est de 21. (je crois qu'il n'était que de 19 pour l'API Google Maps v2.)
Explication:
Google Maps utilise une projection Mercator. Dans une projection Mercator, les lignes de longitude sont également espacées, mais les lignes de latitude ne le sont pas. La distance entre les lignes de latitude augmente au fur et à mesure qu'elles vont de l'équateur aux pôles. En fait, la distance tend vers l'infini lorsqu'elle atteint les pôles. Une carte Google Maps, cependant, n'indique pas les latitudes au-dessus d'environ 85 degrés nord ou en dessous d'environ -85 degrés sud. ( référence ) (Je calcule le seuil réel à +/- 85,05112877980658 degrés.)
Cela rend le calcul des fractions pour les limites plus compliqué pour la latitude que pour la longitude. J'ai utilisé une formule de Wikipedia pour calculer la fraction de latitude. Je suppose que cela correspond à la projection utilisée par Google Maps. Après tout, la page de documentation Google Maps vers laquelle je renvoie ci-dessus contient un lien vers la même page Wikipédia.
Autres notes:
la source
fitBounds
, vous devez créer la carte, puis attendre l'événement "bounds_changed".map.getProjection()
éliminerait une partie du calcul (et l'hypothèse sur la projection), mais cela signifierait que la fonction ne pourrait pas être appelée tant que la carte n'a pas été créée et que l'événement "projection_changed" s'est déclenché.Pour la version 3 de l'API, c'est simple et fonctionnel:
et quelques astuces optionnelles:
la source
maxZoom
empêchera l'utilisateur de zoomer manuellement . Mon exemple ne modifie le DefaultZoom que si cela est nécessaire.getBoundsZoomLevel
. de cette façon, lorsque vous appelez setZoom, il s'anime au niveau de zoom souhaité. à partir de là, ce n'est pas un problème de faire le panoramique et vous vous retrouvez avec une belle animation cartographique qui correspond aux limitesVoici une version Kotlin de la fonction:
la source
Merci, cela m'a beaucoup aidé à trouver le facteur de zoom le plus approprié pour afficher correctement une polyligne. Je trouve les coordonnées maximum et minimum parmi les points que je dois suivre et, dans le cas où le chemin est très "vertical", je viens d'ajouter quelques lignes de code:
En fait, le facteur de zoom idéal est le zoomfactor-1.
la source
var zoomfactor = Math.floor(Math.log(960 * 360 / angle / GLOBE_WIDTH) / Math.LN2)-1;
. Encore, très utile.Étant donné que toutes les autres réponses semblent avoir des problèmes pour moi avec l'une ou l'autre des circonstances (largeur / hauteur de la carte, largeur / hauteur des limites, etc.), j'ai pensé que je mettrais ma réponse ici ...
Il y avait un fichier javascript très utile ici: http://www.polyarc.us/adjust.js
Je l'ai utilisé comme base pour ceci:
Vous pouvez certainement le nettoyer ou le réduire si nécessaire, mais j'ai gardé les noms de variables longtemps pour essayer de le rendre plus facile à comprendre.
Si vous vous demandez d'où vient OFFSET, apparemment 268435456 est la moitié de la circonférence de la Terre en pixels au niveau de zoom 21 (selon http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google -maps ).
la source
Valerio a presque raison avec sa solution, mais il y a une erreur logique.
vous devez d'abord vérifier si l'angle2 est plus grand que l'angle, avant d'ajouter 360 à un négatif.
sinon vous avez toujours une valeur plus grande que l'angle
La bonne solution est donc:
Delta est là, parce que j'ai une largeur plus grande que la hauteur.
la source
map.getBounds()
n'est pas une opération momentanée, donc j'utilise dans le même cas un gestionnaire d'événements. Voici mon exemple dans Coffeescriptla source
Exemple de travail pour trouver un centre par défaut moyen avec react-google-maps sur
ES6
:la source
Le calcul du niveau de zoom pour les longitudes de Giles Gardam fonctionne très bien pour moi. Si vous souhaitez calculer le facteur de zoom pour la latitude, c'est une solution simple qui fonctionne bien:
la source