Google지도 v3-보기 가능 영역 및 확대 / 축소 수준 제한


97

Google지도 v3를 특정 지역으로 제한 할 수 있습니까? 일부 영역 (예 : 국가) 만 표시하고 사용자가 다른 곳으로 슬라이드하는 것을 허용하고 싶습니다. 또한 확대 / 축소 수준을 제한하고 싶습니다. 예를 들어 수준 6과 9 사이에서만 가능합니다. 그리고 모든 기본지도 유형을 사용하고 싶습니다.

이것을 달성하는 방법이 있습니까?

StyledMap을 사용하여 확대 / 축소 수준을 제한하는 데 부분적인 성공을 거두었지만 ROADMAP 제한만으로 성공했으며 다른 기본 유형에 대한 확대 / 축소를 이런 방식으로 제한 할 수 없었습니다.

도움을 주셔서 감사합니다

답변:


119

dragend이벤트를 수신 할 수 있으며 지도가 허용 된 경계를 벗어나면 다시 안으로 이동합니다. LatLngBounds개체 에서 허용 된 경계를 정의한 다음 contains()메서드를 사용 하여 새 위도 / 경도 중심이 경계 내에 있는지 확인할 수 있습니다.

확대 / 축소 수준을 매우 쉽게 제한 할 수도 있습니다.

다음 예를 고려하십시오. 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 예제 :지도 드래그 강제 중지


2
결정이 깨끗해 보이지 않습니다. 왜 if (x < minX) x = minX;그리고 if (x > maxX) x = maxX;서로를 배제하지 않습니까? 중심 좌표는 아니지만 minX / maxX 및 maxX / maxY 좌표에 캔버스를 중앙에 배치하는 이유는 무엇입니까?
Alexander Palamarchuk

1
dragend이벤트 대신 draggable: false에 맵 인스턴스에서 사용할 수 있습니다 ( 작업 예제 )
machineaddict 2014-09-24

"zoom_changed"이벤트를 사용하여 사용자를 제한하는 것은 좋은 기술이 아닙니다. 처음에는 항상 최소 수준을 넘어서 코드를 사용하기 때문에 최소 확대 / 축소를 다시 설정하면 화면이 흔들립니다.
Jitendra Pancholi 2015

zillow.com/homes/for_sale/days_sort/를 확인하십시오 . 그들은 올바른 방법으로 해냈지만 방법은 확실하지 않습니다.
Jitendra Pancholi

1
center_changed대신 이벤트로 변경하면 완벽하게 작동했습니다 dragend.
Johan B

182

확대 / 축소 수준을 제한하는 더 좋은 방법 은 이벤트에 반응하는 대신 minZoom/ maxZoom옵션 을 사용하는 것입니다.

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

또는 맵 초기화 중에 옵션을 지정할 수 있습니다. 예 :

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

참조 : Google Maps JavaScript API V3 참조


3
이제 이것은 확실히 확대 / 축소 수준을 제한하는 가장 좋은 방법입니다. 게시물을 작성할 때이 기능은 Maps API v3에 없었습니다. 고맙게도 그들은 API를 계속 개선하고 있습니다.
Tomik 2011 년

2
이것은 완벽하게 작동하며 줌에 대한 최선의 대답입니다.
paullb

3
이것은 선택된 답만 보는 사람들을위한 답으로 표시되어야합니다.
ErJab

9
확대 / 축소 수준을 설정해도 패닝에는 영향을주지 않습니다.
simpatico

1
확실히 가장 좋은 방법
ChrisRich 2014

16

좋은 소식. 2019 년 2 월 14 일에 출시 된 Maps JavaScript API 버전 3.35부터 새 restriction옵션을 사용 하여지도의 뷰포트를 제한 할 수 있습니다 .

문서에 따르면

MapRestriction 인터페이스

지도에 적용 할 수있는 제한입니다. 지도의 뷰포트는 이러한 제한을 초과하지 않습니다.

출처 : 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>

이게 도움이 되길 바란다!


링크가 작동하지 않습니다. 다음은이 주제에 대한 새로운 항목입니다. 예 : developers-dot-devsite-v2-prod.appspot.com/maps/documentation/… DOCS : developers-dot-devsite-v2-prod.appspot.com/maps/documentation/ …
Adam

1
고정 문서 링크.
xomena

감사합니다.이 코드는 작동했습니다. 즉, 줌을 minZoom 및 maxZoom으로 가능한 한 수준으로 만 제한하는 경우입니다. 이 작업이 의도 한대로 작동하려면 각 확대 / 축소 수준에 대해 서로 다른 남쪽, 서쪽, 북쪽, 동쪽을 설정해야하는 것 같습니다. 각 확대 / 축소 수준에 대해 다른 제한 설정을 갖는 것이 좋을 것입니다. 나는 최대 축소 수준으로 가서 거기에서 좌표를 정의하여 확대 한 다음 이동하면 경계를 벗어날 수 있습니다.
Kim Steinhaug

6

v.3 +에서 확대 / 축소를 제한하려면. 지도 설정에서 기본 확대 / 축소 수준을 추가하고 minZoom 또는 maxZoom (또는 필요한 경우 둘 다) 확대 / 축소 수준은 0 ~ 19입니다. 제한이 필요한 경우 청각 장애인 확대 / 축소 수준을 선언해야합니다. 모두 대소 문자를 구분합니다!

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

3

범위를 제한하는 훨씬 더 좋은 방법은 포스터 위의 포함 논리를 사용했습니다.

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

두 번째 청취자 this.googleMap대신 추가 하는 이유는 무엇 map입니까? 또한 안 dragStartdragStartCenter? 마지막으로 무엇 mapBounds입니까?
hobbes3 2012

2
확실히하는 일은 사용자가 한 번의 드래그 동작으로 멀리 드래그하는 것을 중지하는 것입니다. 그들은 여전히 ​​많은 작은 드래그를 만들어서 어디에서나 끝날 수 있습니다.
James

1

이는지도를 특정 위치로 다시 중심을 맞추는 데 사용할 수 있습니다. 내가 필요했던 것입니다.

    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
myOptions = {
        center: myLatlng,
        minZoom: 6,
        maxZoom: 9,
        styles: customStyles,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

1
이것은 질문에 대한 답이 아닙니다.
Kit Sunde 2015-10-14

0

보기 가능 영역의 제한 문제를 해결하기위한 제 변형이 있습니다.

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

strictBoundsnew google.maps.LatLngBounds()유형 의 객체입니다 . self.gmapGoogle지도 개체 ( new google.maps.Map())를 저장합니다 .

그것은 실제로 작동하지만 경계가 그들을 덮는 경우 0 번째 자오선과 평행선을 교차하는 치질을 고려하는 것을 잊지 마십시오.


수락 됨 Daniel Vassallo의 알고리즘이 제대로 작동하지 않습니다. 여기에는 몇 가지 주요 차이점이 있습니다.
Alexander Palamarchuk 2012 년

0

몇 가지 이유

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

누군가를 도울 수 있기를 바랍니다.


0

한 가지 해결책은 특정 위도 / 경도를 아는 경우와 같습니다.

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

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

});

특정 위도 / 경도가없는 경우

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

});

0

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>

라이브러리는 또한 최소 확대 / 축소 제한을 자동으로 계산할 수 있습니다. 그런 다음 minZoom지도의 속성을 사용하여 확대 / 축소 수준을 제한 합니다.

바라건대 이것은 주어진 경계를 완전히 존중하고 그 경계에서 패닝을 허용하지 않는 솔루션을 원하는 사람에게 도움이되기를 바랍니다.


-4

이것은 도움이 될 수 있습니다.

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

확대 / 축소 수준은 요구 사항에 따라 사용자 지정할 수 있습니다.


이것은 확대 / 축소 수준을 범위로 제한하는 것에 대한 원래 질문을 해결하지 않고 기본 확대 / 축소 수준을 e.g. only between levels 6 and 9설정하고 약간 과잉 인 기본 UI (예 : / )를 제거합니다 . +-
Alastair
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.