Google Maps v3 - giới hạn khu vực có thể xem và mức thu phóng


97

có thể giới hạn Google map v3 trong một khu vực nhất định không? Tôi muốn chỉ cho phép hiển thị một số khu vực (ví dụ: một quốc gia) và không cho phép người dùng trượt sang nơi khác. Ngoài ra, tôi muốn giới hạn mức thu phóng - ví dụ chỉ giữa mức 6 và 9. Và tôi muốn sử dụng tất cả các loại bản đồ cơ sở.

Có bất kì cách nào để đạt được điều này không?

Tôi đã thành công một phần với việc hạn chế mức thu phóng bằng cách sử dụng Bản đồ kiểu, nhưng tôi chỉ thành công với việc hạn chế ROADMAP, tôi không thể giới hạn thu phóng trên các kiểu cơ bản khác theo cách này.

Cảm ơn vì bất kì sự giúp đỡ

Câu trả lời:


119

Bạn có thể lắng nghe dragendsự kiện và nếu bản đồ bị kéo ra ngoài giới hạn cho phép, hãy di chuyển nó trở lại bên trong. Bạn có thể xác định các giới hạn được phép của mình trong một LatLngBoundsđối tượng và sau đó sử dụng contains()phương pháp này để kiểm tra xem trung tâm vĩ độ / lng mới có nằm trong giới hạn hay không.

Bạn cũng có thể giới hạn mức thu phóng rất dễ dàng.

Hãy xem xét ví dụ sau: 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>

Ảnh chụp màn hình từ ví dụ trên. Người dùng sẽ không thể kéo xa hơn về phía nam hoặc xa về phía đông trong trường hợp này:

Google Maps JavaScript API v3 Ví dụ: Buộc dừng kéo bản đồ


2
Quyết định có vẻ không trong sạch. Tại sao if (x < minX) x = minX;if (x > maxX) x = maxX;không loại trừ nhau? Tại sao bạn căn giữa canvas trên các tọa độ minX / maxX và maxX / maxY mặc dù chúng không phải là tọa độ của tâm?
Alexander Palamarchuk

1
Thay vì dragendsự kiện mà bạn có thể sử dụng draggable: falsetrên dụ bản đồ ( ví dụ làm việc )
machineaddict

Đây không phải là một kỹ thuật tốt khi sử dụng sự kiện "zoom_changed" để hạn chế người dùng. Bởi vì lần đầu tiên nó sẽ luôn vượt quá mức tối thiểu và sau đó sử dụng mã của bạn, bạn đang đặt lại mức thu phóng tối thiểu để làm lật màn hình.
Jitendra Pancholi

kiểm tra zillow.com/homes/for_sale/days_sort/… Họ đã thực hiện theo đúng cách chưa, không chắc chắn như thế nào.
Jitendra Pancholi

1
Điều này làm việc hoàn hảo cho tôi nếu tôi thay đổi thành center_changedsự kiện thay vì dragend.
Johan B

182

Cách tốt hơn để hạn chế mức thu phóng có thể là sử dụng minZoom/ maxZoomtùy chọn thay vì phản ứng với các sự kiện?

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

Hoặc các tùy chọn có thể được chỉ định trong quá trình khởi tạo bản đồ, ví dụ:

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

Xem: Tham chiếu API V3 của Google Maps JavaScript


3
Bây giờ đây chắc chắn là cách tốt nhất để hạn chế mức thu phóng. Khi tôi viết bài, tính năng này không có trong API Maps v3. Rất may, họ tiếp tục cải thiện API.
Tomik

2
Điều này hoạt động hoàn hảo, đây sẽ là câu trả lời tốt nhất cho zoom.
paullb

3
Đây nên được đánh dấu là câu trả lời cho những người chỉ nhìn vào câu trả lời đã chọn.
ErJab

9
cài đặt mức thu phóng không ảnh hưởng đến việc di chuyển.
simpatico

1
Chắc chắn là cách tốt nhất để đi
ChrisRich

16

Tin tốt. Bắt đầu từ phiên bản 3.35 của API JavaScript của Maps, được khởi chạy vào ngày 14 tháng 2 năm 2019, bạn có thể sử dụng restrictiontùy chọn mới để giới hạn chế độ xem của bản đồ.

Theo tài liệu

Giao diện MapRestrict

Một hạn chế có thể được áp dụng cho Bản đồ. Khung nhìn của bản đồ sẽ không vượt quá những hạn chế này.

nguồn: https://developers.google.com/maps/documentation/javascript/reference/map#MapRestrict

Vì vậy, bây giờ bạn chỉ cần thêm tùy chọn hạn chế trong quá trình khởi tạo bản đồ và nó. Hãy xem ví dụ sau giới hạn chế độ xem ở Thụy Sĩ

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>

Tôi hi vọng cái này giúp được!


Liên kết không hoạt động. Những Here're mới về chủ đề này: VÍ DỤ: developers-dot-devsite-v2-prod.appspot.com/maps/documentation/... DOCS: developers-dot-devsite-v2-prod.appspot.com/maps/documentation/ …
Adam

1
Liên kết tài liệu cố định.
xomena

Cảm ơn bạn, loại mã này đã hoạt động. Đó là, nếu bạn giới hạn zoom chỉ ở 1 mức có thể với minZoom và maxZoom. Có vẻ như bạn cần đặt các hướng nam, tây, noth, đông khác nhau cho mỗi mức thu phóng nếu điều này hoạt động như dự định. Sẽ rất tuyệt nếu có một cài đặt hạn chế khác nhau cho mỗi mức thu phóng. Tôi đã đi đến mức thu nhỏ tối đa của mình và xác định các tọa độ từ đó, do đó có thể di chuyển ra khỏi giới hạn nếu bạn phóng to và sau đó xoay.
Kim Steinhaug

6

Để giới hạn thu phóng trên v.3 +. trong cài đặt bản đồ của bạn, hãy thêm mức thu phóng mặc định và mức thu phóng minZoom hoặc maxZoom (hoặc cả hai nếu được yêu cầu) là 0 đến 19. Bạn phải khai báo mức thu phóng deafult nếu cần giới hạn. tất cả đều phân biệt chữ hoa chữ thường!

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

3

Cách tốt hơn nhiều để giới hạn phạm vi ... sử dụng logic chứa từ áp phích trên.

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

Tại sao bạn thêm this.googleMapthay vì mapcho người nghe thứ hai? Cũng không dragStartnên dragStartCenter? Cuối cùng là mapBoundsgì?
hobbes3

2
Chắc chắn tất cả những gì làm là ngăn người dùng kéo đến xa trong một chuyển động kéo? Họ vẫn có thể tạo ra rất nhiều trò chơi nhỏ và kết thúc ở bất cứ đâu, không?
James

1

Điều này có thể được sử dụng để căn giữa bản đồ đến một vị trí cụ thể. Đó là những gì tôi cần.

    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
Điều này không trả lời câu hỏi.
Kit Sunde

0

Đây là biến thể của tôi để giải quyết vấn đề về giới hạn của khu vực có thể xem.

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

strictBoundslà một đối tượng của new google.maps.LatLngBounds()loại. self.gmaplưu trữ một đối tượng Google Map ( new google.maps.Map()).

Nó thực sự hiệu quả nhưng đừng quên tính đến bệnh trĩ với việc vượt qua các đường kinh tuyến số 0 và đường ngang nếu giới hạn của bạn bao phủ chúng.


Thuật toán của Daniel Vassallo được chấp nhận không hoạt động đúng với tôi. Có một số khác biệt chính của nó ở đây.
Alexander Palamarchuk

0

Đối với một số lý do

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

không làm việc cho tôi (có thể là một vấn đề bán cầu nam). Tôi đã phải thay đổi nó thành:

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

Hy vọng nó sẽ giúp ích cho ai đó.


0

Một giải pháp là, Nếu bạn biết lat / lng cụ thể.

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

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

});

Nếu không có vĩ độ / lng cụ thể

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

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

});

hoặc là

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

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

});

0

Kể từ giữa năm 2016 , không có cách chính thức nào để hạn chế khu vực có thể xem. Tuy nhiên, hầu hết các giải pháp đặc biệt để hạn chế các giới hạn đều có một lỗ hổng, bởi vì chúng không giới hạn các giới hạn một cách chính xác để vừa với chế độ xem bản đồ, chúng chỉ hạn chế nó nếu tâm bản đồ nằm ngoài các giới hạn đã chỉ định. Nếu bạn muốn hạn chế giới hạn đối với hình ảnh lớp phủ như tôi, điều này có thể dẫn đến hành vi như được minh họa bên dưới, nơi bản đồ lớp phủ hiển thị dưới lớp phủ hình ảnh của chúng tôi:

nhập mô tả hình ảnh ở đây

Để giải quyết vấn đề này, tôi đã tạo một thư viện , thư viện này giới hạn thành công các giới hạn để bạn không thể di chuyển ra khỏi lớp phủ.

Tuy nhiên, như các giải pháp hiện có khác, nó có một vấn đề "rung". Khi người dùng xoay bản đồ đủ mạnh, sau khi họ thả nút chuột trái, bản đồ vẫn tiếp tục tự quay, dần dần chậm lại. Tôi luôn đưa bản đồ trở lại giới hạn, nhưng điều đó dẫn đến rung động. Hiện tại, không thể dừng hiệu ứng xoay này bằng bất kỳ phương tiện nào do API Js cung cấp. Có vẻ như cho đến khi google thêm hỗ trợ cho một cái gì đó như map.stopPanningAnimation (), chúng tôi sẽ không thể tạo ra trải nghiệm mượt mà.

Ví dụ bằng cách sử dụng thư viện đã đề cập, trải nghiệm giới hạn nghiêm ngặt mượt mà nhất mà tôi có thể nhận được:

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>

Thư viện cũng có thể tự động tính toán giới hạn thu phóng tối thiểu. Sau đó, nó hạn chế mức thu phóng bằng cách sử dụngminZoom thuộc tính của bản đồ.

Hy vọng rằng điều này sẽ giúp những người muốn một giải pháp hoàn toàn tôn trọng các ranh giới đã cho và không muốn cho phép di chuyển ra khỏi chúng.


-4

Điều này có thể hữu ích.

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

Mức độ thu phóng có thể được tùy chỉnh theo yêu cầu.


Điều này không giải quyết câu hỏi ban đầu về việc giới hạn mức thu phóng trong một phạm vi e.g. only between levels 6 and 9, nó đặt mức thu phóng mặc định và loại bỏ giao diện người dùng mặc định (tức là +/ -) hơi quá mức cần thiết.
Alastair
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.