2010-09-29 120 views
82

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

有什么办法可以达到这个目的吗?

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

感谢所有帮助

回答

112

你可以听dragend事件,如果地图拖动允许的范围以外,将其移回内部。您可以在LatLngBounds对象中定义允许的边界,然后使用方法检查新的纬度/经度中心是否在边界内。

您还可以非常轻松地限制缩放级别。

考虑下面的例子:从上面的例子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

该决定看起来不干净。为什么'if(x maxX)x = maxX;'不排除对方?为什么您将画布放在minX/maxX和maxX/maxY坐标上,尽管它们不是中心的坐标? – 2012-08-19 11:06:08

+1

而不是'dragend'事件,您可以在地图实例([工作示例](http://jsfiddle.net/32pc6f5v/))上使用'draggable:false') – machineaddict 2014-09-24 11:43:35

+0

这不是使用“zoom_changed”事件的好技术限制用户。因为第一次它总是会超出最低等级,然后使用你的代码,所以你再次设置最小缩放,这将使屏幕变得更加简单。 – 2015-07-16 04:50:56

164

更好的办法可能是使用了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 Reference

+2

现在这无疑是限制缩放级别的最佳方式。在我撰写帖子时,该功能未出现在Maps API v3中。谢天谢地,他们不断改进API。 – Tomik 2011-03-05 23:14:16

+2

这很好,这应该是缩放的最佳答案。 – paullb 2011-12-23 04:23:35

+3

这应该被标记为仅针对所选答案的人的答案。 – ErJab 2012-03-30 22:43:33

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

为什么为第二个侦听器添加'this.googleMap'而不是'map'?也不应该'dragStart'是'dragStartCenter'吗?最后是什么'mapBounds'? – hobbes3 2012-02-02 21:07:51

+2

当然,所有这一切都是阻止用户在一次拖动中拖到远处?他们仍然可以制造很多小拖拽,最终到达任何地方,不是吗? – James 2012-07-02 15:03:36

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地图对象(new google.maps.Map())。

它确实有效,但如果你的边界覆盖了它们,不仅忘记考虑穿越第0经络和平行线的痔疮。

+0

接受Daniel Vassallo的算法对我无法正常工作。这里有几个主要的区别。 – 2012-08-19 12:51:57

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

希望它会帮助别人。

-4

这可能对您有帮助。

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

缩放级别可以根据需要定制。

+0

这并没有解决将缩放级别限制在一个范围内的原始问题。只在级别6和9之间,它设置*默认*缩放级别并删除默认UI(即'+'/'-'),这有点矫枉过正。 – Alastair 2013-10-05 18:30:48

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

}); 
6

要限制在3.0版+变焦。 在您的地图设置中添加默认缩放级别和minZoom或maxZoom(或两者,如果需要) 缩放级别为0到19. 如果需要限制,您必须声明deafult缩放级别。都是区分大小写的!

function initialize() { 
    var mapOptions = { 
     maxZoom:17, 
     minZoom:15, 
     zoom:15, 
     .... 
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)); 
     } 
    }); 
2
myOptions = { 
     center: myLatlng, 
     minZoom: 6, 
     maxZoom: 9, 
     styles: customStyles, 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 
+0

这不回答这个问题。 – 2015-10-14 01:27:06

0

作为中间2016,有限制可视区域没有官方途径。大多数限制界限的临时解决方案都存在缺陷,因为它们不会严格限制界限以适应地图视图,而只是在地图中心超出指定界限时才会限制界限。如果你想限制的范围,以覆盖图像像我这样的,这可能会导致行为像如下图所示,在垫层图是我们的图像叠加下可见:

enter image description here

为了解决这个问题,我有创建了一个library,它成功地限制了界限,因此您无法移出覆盖图。

但是,作为其他现有的解决方案,它有一个“振动”的问题。当用户足够积极地平铺地图时,在释放鼠标左键后,地图仍然继续自行平移,逐渐放缓。我总是将地图返回到边界,但这会导致一些震动。此平移效果目前无法用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){ 
 
\t var bounds = new google.maps.LatLngBounds(
 
\t \t new google.maps.LatLng(62.281819, -150.287132), 
 
\t \t new google.maps.LatLng(62.400471, -150.005608)); 
 

 
\t var image_src = 'https://developers.google.com/maps/documentation/' + 
 
\t \t 'javascript/examples/full/images/talkeetna.png'; 
 

 
\t 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()"> 
 
\t <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映射的属性限制缩放级别。

希望这可以帮助那些想要解决方案的人完全尊重给定的界限,并且不想让他们摆脱困境。

相关问题