Google Maps v3-限制可见区域和缩放级别


97

是否可以将Google Map v3限制在某个区域?我只想显示一些区域(例如一个国家),而不允许用户滑动到其他地方。另外,我想限制缩放级别-例如仅在6和9级之间。并且我想使用所有基本地图类型。

有什么办法可以做到这一点?

通过使用StyledMap,我在限制缩放级别方面取得了部分成功,但仅在限制ROADMAP方面取得了成功,因此无法通过这种方式来限制其他基本类型的缩放。

谢谢你的帮助

Answers:


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坐标上,尽管它们不是中心坐标?
亚历山大·帕拉玛丘克

1
除了dragend事件,您可以draggable: false在地图实例(工作示例)上使用
machineaddict 2014年

这不是使用“ zoom_changed”事件来限制用户的好技术。因为第一次,它将始终超出最小级别,然后使用您的代码,因此您需要再次设置最小缩放,以使屏幕更加流畅。
Jitendra Pancholi 2015年

检查zillow.com/homes/for_sale/days_sort/…他们以正确的方式完成操作,不确定如何操作。
Jitendra Pancholi 2015年

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'3

2
这完美地工作,这应该是缩放的最佳答案。
paullb 2011年

3
对于仅查看所选答案的用户,应将其标记为答案。
ErJab 2012年

9
设置缩放级别对平移没有影响。
simpatico 2012年

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>

我希望这有帮助!



1
固定的文档链接。
xomena '19

谢谢,这段代码行得通。也就是说,如果将minZoom和maxZoom的缩放比例限制为仅1级。似乎您需要为每个缩放级别设置不同的南,西,北,东。每个缩放级别都有不同的限制设置会很不错。我使用了最大缩小级别,并从那里定义了坐标,因此,如果放大然后平移,则可以平移出边界。
金·斯坦因格

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第二个侦听器?还不dragStart应该dragStartCenter吗?最后是什么mapBounds
hobbes3 '02

2
当然,所有要做的就是停止用户一次拖动动作向远处拖动吗?他们仍然可以做出很多小的阻力,最终到任何地方,不是吗?
詹姆斯

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

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.gmap存储一个Google Map对象(new google.maps.Map())。

它确实有效,但如果边界覆盖了第0个子午线和平行线,则别忘了考虑痔疮与第0个经线和平行线的交叉。


接受Daniel Vassallo的算法对我而言无法正常工作。这里有几个主要区别。
亚历山大·帕拉玛丘克

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.