谷歌地图 v3 - 限制可视区域和缩放级别

100

有没有可能限制Google地图v3只在特定区域范围内显示? 我想要允许仅显示某个区域(例如一个国家),禁止用户滑动到其他地方。 另外,我希望限制缩放级别-例如只在6到9级之间。并且我想使用所有基本地图类型。

是否有任何方法可以实现这一点?

我尝试使用StyledMap限制缩放级别,但我只能成功限制ROADMAP地图类型,我无法采用这种方式限制其他基本类型的缩放。

感谢您提供的任何帮助。

12个回答

183
更好地限制缩放级别的方法可能是使用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
2
这个完美地运作,应该是Zoom的最佳答案。 - paullb
3
这应该被标记为答案,供那些仅查看所选答案的人使用。 - ErJab
9
调整缩放级别对平移没有影响。 - simpatico
1
绝对是最好的选择。 - ChrisRich
显示剩余2条评论

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
你可以在地图实例上使用 draggable: false,而不是 dragend 事件(工作示例)。 - machineaddict
使用“zoom_changed”事件来限制用户并不是一个好的技巧。因为第一次它总是会超出最小级别,然后使用您的代码,您又设置了最小缩放级别,这将导致屏幕闪烁。 - Jitendra Pancholi
请参见此链接:https://developers.google.com/maps/documentation/javascript/reference#MapOptions - Jitendra Pancholi
1
如果我改用center_changed事件而不是dragend,这对我来说完美地运作了。 - Johan B
显示剩余2条评论

23

好消息。从2019年2月14日推出的Maps JavaScript API 3.35版本开始,您可以使用新的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>

我希望这能帮到你!


链接无法使用。这里有关于此主题的新链接: 示例:https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/control-bounds-restriction 文档:https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/controls - Alex
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);
                           });

为什么你在第二个listener中添加this.googleMap而不是map?此外,dragStart不应该改为dragStartCenter吗?最后,mapBounds是什么? - hobbes3
2
这样做只是防止用户在一次拖动中拖得太远,对吧?他们仍然可以进行许多小的拖动,最终到达任何位置,不是吗? - James

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

1
这并没有回答问题。 - Kit Sunde

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

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年中期,没有官方的方法来限制可视区域。大多数临时解决方案都有一个缺陷,因为它们不能精确地将边界限制在地图视图上,只有当地图中心超出指定边界时才会限制它。如果您想将边界限制到像我这样的覆盖图像,这可能会导致下面所示的行为,其中底层地图在我们的图像叠加下仍然可见:

enter image description here

为了解决这个问题,我创建了一个,成功地限制了边界,使您无法超出叠加层。
然而,与其他现有的解决方案一样,它存在“振动”问题。当用户足够激烈地平移地图时,在释放左键后,地图仍会自行平移,并逐渐减速。我总是将地图返回到边界,但这会导致一种振动效果。目前 Js API 提供的任何手段都无法停止这种平移效果。看来在谷歌添加类似于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地图属性来限制缩放级别。

希望这可以帮助那些希望得到完全尊重给定边界并且不希望允许超出边界的解决方案的人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接