web-dev-qa-db-fra.com

Google Maps v3 - limite la zone d'affichage et le niveau de zoom

est-il possible de limiter Google map v3 à une zone donnée? Je souhaite autoriser l’affichage uniquement d’une zone (par exemple un pays) et interdire à l’utilisateur de glisser ailleurs. Aussi, je veux restreindre le niveau de zoom - par exemple. seulement entre les niveaux 6 et 9. Et je veux utiliser tous les types de carte de base.

Y'a-t-il une quelconque façon de réussir cela? 

J'ai eu un succès partiel en limitant le niveau de zoom en utilisant StyledMap, mais je n'y suis parvenu qu'en limitant ROADMAP.

Merci pour toute aide

91
Tomik

Vous pouvez écouter l'événement dragend et, si la carte est déplacée en dehors des limites autorisées, déplacez-la à l'intérieur. Vous pouvez définir vos limites autorisées dans un objet LatLngBounds , puis utiliser la méthode contains() pour vérifier si le nouveau centre lat/lng se trouve dans les limites.

Vous pouvez également limiter le niveau de zoom très facilement.

Prenons l'exemple suivant: Fiddle Demo

<!DOCTYPE html>
<html> 
<head> 
   <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
   <title>Google Maps JavaScript API v3 Example: Limit Panning and Zoom</title> 
   <script type="text/javascript" 
           src="http://maps.google.com/maps/api/js?sensor=false"></script>
</head> 
<body> 
   <div id="map" style="width: 400px; height: 300px;"></div> 

   <script type="text/javascript"> 

   // This is the minimum zoom level that we'll allow
   var minZoomLevel = 5;

   var map = new google.maps.Map(document.getElementById('map'), {
      zoom: minZoomLevel,
      center: new google.maps.LatLng(38.50, -90.50),
      mapTypeId: google.maps.MapTypeId.ROADMAP
   });

   // Bounds for North America
   var strictBounds = new google.maps.LatLngBounds(
     new google.maps.LatLng(28.70, -127.50), 
     new google.maps.LatLng(48.85, -55.90)
   );

   // Listen for the dragend event
   google.maps.event.addListener(map, 'dragend', function() {
     if (strictBounds.contains(map.getCenter())) return;

     // We're out of bounds - Move the map back within the bounds

     var c = map.getCenter(),
         x = c.lng(),
         y = c.lat(),
         maxX = strictBounds.getNorthEast().lng(),
         maxY = strictBounds.getNorthEast().lat(),
         minX = strictBounds.getSouthWest().lng(),
         minY = strictBounds.getSouthWest().lat();

     if (x < minX) x = minX;
     if (x > maxX) x = maxX;
     if (y < minY) y = minY;
     if (y > maxY) y = maxY;

     map.setCenter(new google.maps.LatLng(y, x));
   });

   // Limit the zoom level
   google.maps.event.addListener(map, 'zoom_changed', function() {
     if (map.getZoom() < minZoomLevel) map.setZoom(minZoomLevel);
   });

   </script> 
</body> 
</html>

Capture d'écran de l'exemple ci-dessus. L'utilisateur ne pourra pas traîner plus au sud ou à l'extrême est dans ce cas:

Google Maps JavaScript API v3 Example: Force stop map dragging

118
Daniel Vassallo

Le meilleur moyen de limiter le niveau de zoom serait d’utiliser les options minZoom/maxZoom plutôt que de réagir aux événements?

var opt = { minZoom: 6, maxZoom: 9 };
map.setOptions(opt);

Ou les options peuvent être spécifiées lors de l’initialisation de la carte, par exemple:

var map = new google.maps.Map(document.getElementById('map-canvas'), opt);

Voir: Référence de Google Maps JavaScript API V3

174
ChrisV

Pour limiter le zoom sur v.3 + . Dans vos paramètres de carte, ajoutez le niveau de zoom par défaut et minZoom ou maxZoom (ou les deux si nécessaire). si une limitation est requise. tous sont sensibles à la casse!

function initialize() {
   var mapOptions = {
      maxZoom:17,
      minZoom:15,
      zoom:15,
      ....
6
DEEP-SILVER

Meilleure façon de limiter la portée ... utilisée de la logique contient de l'affiche ci-dessus.

var dragStartCenter;

google.maps.event.addListener(map, 'dragstart', function(){
                                       dragStartCenter = map.getCenter();
                                         });

google.maps.event.addListener(this.googleMap, 'dragend', function(){
                            if (mapBounds.contains(map.getCenter())) return;
                    map.setCenter(this.dragStart);
                           });
3
Pat

Bonnes nouvelles. À partir de la version 3.35 de l'API JavaScript de Google Maps, lancée le 14 février 2019, vous pouvez utiliser la nouvelle option restriction afin de limiter la fenêtre d'affichage de la carte. 

Selon la documentation

Interface MapRestriction

Une restriction qui peut être appliquée à la carte. La fenêtre de la carte ne dépassera pas ces restrictions.

source: https://developers.google.com/maps/documentation/javascript/reference/3.35/map#MapRestriction

Donc, maintenant, vous ajoutez simplement une option de restriction lors d’une initialisation de carte et c’est cela. Regardez l'exemple suivant qui limite le viewport à la Suisse

var map;
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 46.818188, lng: 8.227512},
    minZoom: 7,
    maxZoom: 14,
    zoom: 7,
    restriction: {
      latLngBounds: {
        east: 10.49234,
        north: 47.808455,
        south: 45.81792,
        west: 5.95608
      },
      strictBounds: true
    },
  });
}
#map {
  height: 100%;
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&callback=initMap" async defer></script>

J'espère que ça aide!

2
xomena
myOptions = {
        center: myLatlng,
        minZoom: 6,
        maxZoom: 9,
        styles: customStyles,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
2
Anup

Ceci peut être utilisé pour recentrer la carte sur un emplacement spécifique. C'est ce dont j'avais besoin.

    var MapBounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(35.676263, 13.949096),
    new google.maps.LatLng(36.204391, 14.89038));

    google.maps.event.addListener(GoogleMap, 'dragend', function ()
    {
        if (MapBounds.contains(GoogleMap.getCenter()))
        {
            return;
        }
        else
        {
            GoogleMap.setCenter(new google.maps.LatLng(35.920242, 14.428825));
        }
    });
1
Jonathan Busuttil

Une solution est comme, si vous connaissez le lat/lng spécifique.

google.maps.event.addListener(map, 'idle', function() {

    map.setCenter(new google.maps.LatLng(latitude, longitude));
    map.setZoom(8);

});

Si vous n'avez pas de lat/lng spécifique

google.maps.event.addListener(map, 'idle', function() {

    map.setCenter(map.getCenter());
    map.setZoom(8);

});

ou

google.maps.event.addListener(map, 'idle', function() {

    var bounds = new google.maps.LatLngBounds();
    map.setCenter(bounds.getCenter());
    map.setZoom(8);

});
0
Jaison

Pour certaines raisons

if (strictBounds.contains(map.getCenter())) return;

n'a pas fonctionné pour moi (peut-être un problème de l'hémisphère sud). Je devais le changer pour:

    function checkBounds() {
        var c = map.getCenter(),
            x = c.lng(),
            y = c.lat(),
            maxX = strictBounds.getNorthEast().lng(),
            maxY = strictBounds.getNorthEast().lat(),
            minX = strictBounds.getSouthWest().lng(),
            minY = strictBounds.getSouthWest().lat();

        if(x < minX || x > maxX || y < minY || y > maxY) {
            if (x < minX) x = minX;
            if (x > maxX) x = maxX;
            if (y < minY) y = minY;
            if (y > maxY) y = maxY;
            map.setCenter(new google.maps.LatLng(y, x));
        }
    }

J'espère que ça va aider quelqu'un.

0
Mayko

Voici ma variante pour résoudre le problème de la limitation de la zone visible.

        google.maps.event.addListener(this.map, 'idle', function() {
            var minLat = strictBounds.getSouthWest().lat();
            var minLon = strictBounds.getSouthWest().lng();
            var maxLat = strictBounds.getNorthEast().lat();
            var maxLon = strictBounds.getNorthEast().lng();
            var cBounds  = self.map.getBounds();
            var cMinLat = cBounds.getSouthWest().lat();
            var cMinLon = cBounds.getSouthWest().lng();
            var cMaxLat = cBounds.getNorthEast().lat();
            var cMaxLon = cBounds.getNorthEast().lng();
            var centerLat = self.map.getCenter().lat();
            var centerLon = self.map.getCenter().lng();

            if((cMaxLat - cMinLat > maxLat - minLat) || (cMaxLon - cMinLon > maxLon - minLon))
            {   //We can't position the canvas to strict borders with a current zoom level
                self.map.setZoomLevel(self.map.getZoomLevel()+1);
                return;
            }
            if(cMinLat < minLat)
                var newCenterLat = minLat + ((cMaxLat-cMinLat) / 2);
            else if(cMaxLat > maxLat)
                var newCenterLat = maxLat - ((cMaxLat-cMinLat) / 2);
            else
                var newCenterLat = centerLat;
            if(cMinLon < minLon)
                var newCenterLon = minLon + ((cMaxLon-cMinLon) / 2);
            else if(cMaxLon > maxLon)
                var newCenterLon = maxLon - ((cMaxLon-cMinLon) / 2);
            else
                var newCenterLon = centerLon;

            if(newCenterLat != centerLat || newCenterLon != centerLon)
                self.map.setCenter(new google.maps.LatLng(newCenterLat, newCenterLon));
        });

strictBounds est un objet de type new google.maps.LatLngBounds(). self.gmap stocke un objet Google Map (new google.maps.Map()).

Cela fonctionne vraiment mais n'oubliez pas de prendre en compte les hémorroïdes avec les méridiens croisés et parallèles si vos limites les couvrent.

0

À partir de la mi-2016, il n'y a pas de moyen officiel de restreindre la zone visible. Cependant, la plupart des solutions ad hoc visant à limiter les limites comportent une faille car elles ne restreignent pas exactement les limites pour s’adapter à la vue Carte, mais uniquement si le centre de la carte se situe en dehors des limites spécifiées. Si vous souhaitez limiter les limites à superposer une image comme moi, cela peut entraîner un comportement similaire à celui illustré ci-dessous, dans lequel la carte sous-jacente est visible sous notre incrustation d'image:

 enter image description here

Pour résoudre ce problème, j'ai créé une bibliothèque library , qui limite avec succès les limites, de sorte que vous ne pouvez pas effectuer un panoramique sur la superposition.

Cependant, à l'instar des autres solutions existantes, le problème est "vibrant". Lorsque l'utilisateur effectue un panoramique suffisamment agressif sur la carte, après avoir relâché le bouton gauche de la souris, la carte continue de se déplacer d'elle-même, en ralentissant progressivement. Je ramène toujours la carte dans les limites, mais il en résulte une sorte de vibration. Cet effet de panoramique ne peut être arrêté avec aucun moyen fourni par l’API Js pour le moment. Il semble que tant que Google n'aura pas pris en charge quelque chose comme map.stopPanningAnimation (), nous ne pourrons pas créer une expérience fluide.

Exemple utilisant la bibliothèque mentionnée, l'expérience la plus douce et stricte que j'ai pu obtenir:

function initialise(){
  
  var myOptions = {
     zoom: 5,
     center: new google.maps.LatLng(0,0),
     mapTypeId: google.maps.MapTypeId.ROADMAP,
  };
  var map = new google.maps.Map(document.getElementById('map'), myOptions);
  
  addStrictBoundsImage(map);
}

function addStrictBoundsImage(map){
	var bounds = new google.maps.LatLngBounds(
		new google.maps.LatLng(62.281819, -150.287132),
		new google.maps.LatLng(62.400471, -150.005608));

	var image_src = 'https://developers.google.com/maps/documentation/' +
		'javascript/examples/full/images/talkeetna.png';

	var strict_bounds_image = new StrictBoundsImage(bounds, image_src, map);
}
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
      <script type="text/javascript">
        google.load("maps", "3",{other_params:"sensor=false"});
      </script>
<body style="margin:0px; padding:0px;" onload="initialise()">
	 <div id="map" style="height:400px; width:500px;"></div>
     <script  type="text/javascript"src="https://raw.githubusercontent.com/matej-pavla/StrictBoundsImage/master/StrictBoundsImage.js"></script>
</body>

La bibliothèque est également capable de calculer automatiquement la restriction de zoom minimale. Il limite ensuite le niveau de zoom à l'aide de l'attribut minZoom map.

J'espère que cela aidera quelqu'un qui veut une solution qui respecte pleinement les limites données et qui ne veut pas permettre un panoramique.

0
Matej P.