Google Maps v3 - ограничить видимую область и уровень масштабирования

Можно ли ограничить Google map v3 определенной областью? Я хочу разрешить отображение только некоторой области (например, страны) и запретить пользователю перемещаться в другом месте. Также я хочу ограничить уровень масштабирования - например, только между уровнями 6 и 9. И я хочу использовать все типы базовой карты.

Есть ли способ достичь этого?

У меня был частичный успех с ограничением уровня масштабирования с помощью StyledMap, но мне удалось только ограничить ROADMAP, поэтому я не смог ограничить масштабирование других базовых типов.

Спасибо за любую помощь

Ответ 1

Вы можете прослушать событие dragend, и если карта перетаскивается за пределы разрешенных границ, переместите ее обратно внутрь. Вы можете определить свои разрешенные границы в объекте LatLngBounds, а затем использовать метод contains(), чтобы проверить, находится ли новый центр lat/lng внутри границы.

Вы также можете очень легко ограничить уровень масштабирования.

Рассмотрим следующий пример: 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>

Снимок экрана из приведенного выше примера. В этом случае пользователь не сможет перетащить дальше на юг или на восток:

Google Maps JavaScript API v3 Example: Force stop map dragging

Ответ 2

Лучшим способом ограничения уровня масштабирования может быть использование опций minZoom/maxZoom, а не реагирование на события?

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

Или параметры могут быть указаны во время инициализации карты, например:

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

Смотрите: Справочник по API JavaScript API Google Maps

Ответ 3

Хорошие новости. Начиная с версии 3.35 API Карт JavaScript, которая была запущена 14 февраля 2019 года, вы можете использовать новую опцию restriction, чтобы ограничить область просмотра карты.

Согласно документации

MapRestriction interface

Ограничение, которое может быть применено к карте. Область просмотра карты не будет превышать эти ограничения.

Источник: https://developers.google.com/maps/documentation/javascript/reference/map#MapRestriction

Итак, теперь вы просто добавляете опцию ограничения во время инициализации карты и все. Посмотрите на следующий пример, который ограничивает область просмотра для Швейцарии

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>

Ответ 4

Чтобы ограничить масштабирование v.3 +. в настройках вашей карты добавьте уровень масштабирования по умолчанию и minZoom или maxZoom (или оба, если необходимо) уровни масштабирования от 0 до 19. Вы должны объявить уровень глухого увеличения, если требуется ограничение. все чувствительны к регистру!

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

Ответ 5

Гораздо лучший способ ограничить диапазон... используется логика с плакатом сверху.

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);
                           });

Ответ 6

Это можно использовать для перенаправления карты в определенное место. Это то, что мне нужно.

    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));
        }
    });

Ответ 7

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

Ответ 8

Здесь мой вариант решения проблемы ограничения видимой области.

        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 является объектом типа new google.maps.LatLngBounds(). self.gmap хранит объект Google Map (new google.maps.Map()).

Это действительно работает, но не только забывайте учитывать геморрой с пересечением 0-го меридиана и параллелей, если ваши границы покрывают их.

Ответ 9

По какой-то причине

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

не работал у меня (возможно, проблема южного полушария). Мне пришлось изменить его на:

    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));
        }
    }

Надеюсь, что это поможет кому-то.

Ответ 10

Одно решение похоже: если вы знаете конкретный lat/lng.

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

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

});

Если у вас нет специального lat/lng

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

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

});

или

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

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

});

Ответ 11

По состоянию на середину 2016 года нет официального способа ограничения области видимости. Однако большинство специальных решений для ограничения границ имеют недостаток, поскольку, поскольку они не ограничивают границы точно, чтобы соответствовать представлению карты, они ограничивают это только в том случае, если центр карты выходит за пределы указанных границ. Если вы хотите ограничить границы наложением изображения, подобного мне, это может привести к поведению, показанному ниже, где подледная карта видна под нашим наложением изображения:

введите описание изображения здесь

Чтобы решить эту проблему, я создал библиотеку которая успешно ограничивает границы, поэтому вы не можете выходить из наложения.

Однако, как и другие существующие решения, он имеет "вибрирующую" проблему. Когда пользователь набирает карту достаточно агрессивно, после отпускания левой кнопки мыши карта по-прежнему продолжает панорамирование сама по себе, постепенно замедляя ее. Я всегда возвращаю карту обратно в границы, но это приводит к вибрации. Этот эффект панорамирования не может быть остановлен никакими средствами, предоставляемыми Js API на данный момент. Похоже, что до тех пор, пока Google не добавит поддержку чего-то вроде map.stopPanningAnimation(), мы не сможем создать гладкий опыт.

Пример использования указанной библиотеки - самый гладкий личный опыт, который я смог получить:

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>

Ответ 12

Это может быть полезно.

  var myOptions = {
      center: new google.maps.LatLng($lat,$lang),
      zoom: 7,
      disableDefaultUI: true,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };

Уровень масштабирования можно настроить в соответствии с требованиями.