web-dev-qa-db-fra.com

FitBounds de Google Maps v3 () Zoom trop proche pour un seul marqueur

Est-il possible de définir un niveau de zoom maximal pour fitBounds()? Mon problème est que, lorsque la carte n’est alimentée qu’à un seul endroit, elle effectue un zoom aussi important que possible, ce qui la met hors contexte et la rend inutile. Peut-être que je prends la mauvaise approche?

Merci d'avance!

78
Codey W

J'aime la solution de mrt (surtout quand vous ne savez pas combien de points vous allez cartographier ou ajuster), sauf que le marqueur est jeté pour qu'il ne soit plus au centre de la carte. Je l'ai simplement étendu d'un point supplémentaire, en soustrayant 0,01 aux points de latitude et de longitude, afin de garder le marqueur au centre. Fonctionne très bien, merci, mrt!

// Pan & Zoom map to show all markers
function fitToMarkers(markers) {

    var bounds = new google.maps.LatLngBounds();

    // Create bounds from markers
    for( var index in markers ) {
        var latlng = markers[index].getPosition();
        bounds.extend(latlng);
    }

    // Don't zoom in too far on only one marker
    if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
       var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
       var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - 0.01, bounds.getNorthEast().lng() - 0.01);
       bounds.extend(extendPoint1);
       bounds.extend(extendPoint2);
    }

    map.fitBounds(bounds);

    // Adjusting zoom here doesn't work :/

}
118
Ryan

Vous pouvez configurer votre carte avec maxZoom dans la MapOptions (api-reference) comme ça: 

var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });

Cela empêcherait la carte d’agrandir davantage lors de l’utilisation de fitBounds() et supprimerait même les niveaux de zoom du contrôle de zoom.

30
Flygenring

Une autre solution consiste à développer les limites si vous les détectez trop petites avant d'exécuter fitBounds ():

var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like
// ...
if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
   var extendPoint = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
   bounds.extend(extendPoint);
}
map.fitBounds(bounds);
28
mrt
var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });

L'utilisation de l'option MaxZoom fonctionne mieux pour ne pas zoomer sur les marques que vous avez.

17
markvaneijk

Une fois que vous avez ajouté toutes les limites réelles, ajoutez ces lignes

var offset = 0.002;     
var center = bounds.getCenter();                            
bounds.extend(new google.maps.LatLng(center.lat() + offset, center.lng() + offset));
bounds.extend(new google.maps.LatLng(center.lat() - offset, center.lng() - offset));

il obtient le centre des limites réelles puis ajoute deux points supplémentaires un au nord-est et un au sud-ouest du centre

Ceci définit efficacement le zoom minimum, modifie la valeur du décalage pour augmenter ou diminuer le zoom

12
PWHIT

S'il s'agit d'un seul emplacement, vous pouvez utiliser setCenter () et setZoom () à la place.

12
CrazyEnigma

tu peux utiliser

map.setOptions({
    maxZoom: [what u want],
    minZoom: [what u want]
});

de cette manière, vous définissez les propriétés de la carte après l’initialisation de la carte. Vous pouvez les définir autant de fois que vous le souhaitez.

bonne chance, rarutu

9
Wowzaaa

Pour empêcher la carte d’agrandir au maximum, j’ajoute cette ligne de code:

var zoomOverride = map.getZoom();
        if(zoomOverride > 15) {
        zoomOverride = 15;
        }
      map.setZoom(zoomOverride);

Juste après cette ligne:

map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

N'hésitez pas à modifier le niveau de zoom en fonction du niveau auquel vous ne souhaitez pas que la carte effectue un zoom arrière. 

Si vous avez des problèmes ou des questions, laissez-moi un commentaire sur l'article que j'ai écrit à ce sujet sur http://icode4you.net/creating-your-own-store-locator-map-how-to-prevent- the-map-from-zooming-in-too-close-on-a-single-marker

7
TheLibzter

J'aime beaucoup la solution de MRT et elle fonctionne parfaitement si vous n’avez toujours qu’un seul objectif. Cependant, j’ai trouvé que si le cadre de sélection n’était pas basé sur un point mais que les points étaient très proches les uns des autres, la carte risquerait quand même d’être agrandie.

Voici un moyen de vérifier d’abord si les points se trouvent à une distance définie l’un de l’autre, puis, s’ils sont inférieurs à cette distance minimale, étendez les limites de cette distance minimale:

var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like

// ...

var minDistance = 0.002;
var sumA = bounds.getNorthEast().lng() - bounds.getSouthWest().lng();
var sumB = bounds.getNorthEast().lat() - bounds.getSouthWest().lat();

if((sumA < minDistance && sumA > -minDistance) 
&& (sumB < minDistance && sumB > -minDistance)){
var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + minDistance, bounds.getNorthEast().lng() + minDistance);
    var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - minDistance, bounds.getNorthEast().lng() - minDistance);
    bounds.extend(extendPoint1);
    bounds.extend(extendPoint2);
}

J'espère que cela aide quelqu'un!

5
Pakage

Cela vous donne un contrôle direct sur le zoom maximum autorisé sur l'ajustement des limites. 

var fitToMarkers = function(map, markers, maxZoom) {
    if (typeof maxZoom == 'undefined') maxZoom = 15;

    google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
        if (this.getZoom() > maxZoom) {
            this.setZoom(maxZoom);
        }
    });

    var bounds = new google.maps.LatLngBounds();
    for (var m = 0; m < markers.length; m++) {
        var marker = markers[m];
        var latlng = marker.getPosition();
        bounds.extend(latlng);
    }

    map.fitBounds(bounds);
};
3
clime

Quant à moi, je le résous en créant un événement inactif après fitBounds. Fonctionne parfaitement. Devinez que c'est l'une des solutions les plus propres ici

var locations = [['loc', lat, lng], ['loc', lat, lng]];
.....
for (i = 0; i < locations.length; i++) { 
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10
  });
  .... create markers, etc.
}
....
map.fitBounds(bounds);  
google.maps.event.addListenerOnce(map, 'idle', function() {
  if (locations.length == 1) {
    map.setZoom(11);
  }
});
2

J'ai résolu ce problème, car Google Maps V3 est piloté par les événements:

vous pouvez demander à l'API de ramener le zoom à une valeur appropriée lorsque l'événement zoom_changed déclenche:

var initial = true
google.maps.event.addListener(map, "zoom_changed", function() {
    if (intial == true){
       if (map.getZoom() > 11) {
         map.setZoom(11);
         intial = false;
       }
    }
}); 

Je me suis servi de intial pour que la carte ne zoome pas trop lorsque le fit fit, si tout allait bien, tout événement de zoom supérieur à 11 serait impossible pour l’utilisateur. 

2
tuned

Sa déjà répondu ici Google Maps v3: Enforcing min. niveau de zoom lors de l'utilisation de fitBounds cela fonctionne comme prévu :) donc maintenant, si après ajustement, le zoom est inférieur à 13, alors vous pouvez définir un nouveau zoom que vous préférez

0

Après avoir appelé la méthode fitBounds(), essayez de configurer à nouveau le niveau de zoom. Cela forcera la carte à être à ce niveau de zoom tout en étant centrée au bon endroit. 

0
moneshchary

J'ai soulution basé sur la limitation du zoom max lors de l'ajustement des limites. Fonctionne pour moi (testé sur Win 7 - IE 9, FF 13, Chrome 19):

// When fitting bounds:
var bounds = new google.maps.LatLngBounds();
// ...
// extend bounds as you like
// ..

// now set global variable when fitting bounds
window.fittingBounds = true;
map.fitBounds(bounds);
window.fittingBounds = false;


// attach this event listener after map init
google.maps.event.addListener(map, 'zoom_changed', function() {
    // set max zoom only when fitting bounds
    if (window.fittingBounds && map.getZoom() > 16) {
        this.setZoom(16);
    }
});
0
muffir

Et .. en voici un autre.
Même idée que mrt et Ryan, mais

  • fonctionne également si la taille des bornes n'est pas exactement égale à zéro (*)
  • empêche la distorsion près des pôles
  • utilise getCenter () au lieu de getNorthEast ()

(*) Remarque: Si la boîte est déjà suffisamment grande, l'ajout de ces deux points supplémentaires n'aura aucun effet. Donc, nous n'avons pas besoin de vérification supplémentaire.

function calcBounds(markers) {
  // bounds that contain all markers
  var bounds = new google.maps.LatLngBounds();
  // Using an underscore _.each(). Feel free to replace with standard for()
  _.each(markers, function(marker) {
    bounds.extend(marker.getPosition());
  });
  // prevent lat/lng distortion at the poles
  var lng0 = bounds.getNorthEast().lng();
  var lng1 = bounds.getSouthWest().lng();
  if (lng0 * lng1 < 0) {
    // Take the cos at the equator.
    var cos = 1;
  }
  else {
    var cos0 = Math.cos(lng0);
    var cos1 = Math.cos(lng1);
    // Prevent division by zero if the marker is exactly at the pole.
    var cos_safe = Math.max(cos0, cos1, 0.0001);
  }
  var cos0 = Math.cos(bounds.getNorthEast.lng() * Math.PI / 180);
  var cos1 = Math.cos(bounds.getSouthWest.lng() * Math.PI / 180);
  // "radius" in either direction.
  // 0.0006 seems to be an ok value for a typical city.
  // Feel free to make this value a function argument.
  var rLat = 0.0006;
  var rLng = rLat / cos_safe;
  // expand the bounds to a minimum width and height
  var center = bounds.getCenter();
  var p0 = new google.maps.LatLng(center.lat() - rLat, center.lng() - rLng);
  var p1 = new google.maps.LatLng(lat.center() + rLat, center.lng() + rLng);
  bounds.extend(p0);
  bounds.extend(p1);
  return bounds;
}

EDIT: Je ne sais pas exactement si mon ratio est correctement calculé, étant donné que nous avons une projection de Mercator. Je pourrais rééditer cela ..

0
donquixote