如何在 Google Maps API V3 中限制平移?

IT技术 javascript google-maps google-maps-api-3
2021-01-18 22:04:37

在 V2 中,有一种方法可以限制平移/拖动,以便地图保持在特定范围内。在 V3 中是如何做到的?

假设我希望用户只关注欧洲。我已经限制了缩放,但是如果我允许拖动(在这种情况下我必须这样做,出于其他原因),那么用户可以平移超出我想要显示的区域。

请提供工作示例或代码片段-我不是专家编码员...

6个回答

我想我参加聚会有点晚了,但是由于这正是我刚才所需要的并且我对此有所改进,因此我想无论如何我都会发布答案。

有了Daniel Vassallobrendo的回答,用户仍然可以使用平移控件(如果它被激活)从想要的区域移开。@Yauhen.F 在评论中提到的事情。

因此,我没有使用 dragend 事件,而是使用 center_changed 事件。在拖动过程中以及每次有人使用平移控件时都会连续触发。

// bounds of the desired area
var allowedBounds = new google.maps.LatLngBounds(
     new google.maps.LatLng(70.33956792419954, 178.01171875), 
     new google.maps.LatLng(83.86483689701898, -88.033203125)
);
var lastValidCenter = map.getCenter();

google.maps.event.addListener(map, 'center_changed', function() {
    if (allowedBounds.contains(map.getCenter())) {
        // still within valid bounds, so save the last valid position
        lastValidCenter = map.getCenter();
        return; 
    }

    // not valid anymore => return to last valid position
    map.panTo(lastValidCenter);
});

通过在拖动过程中连续保存最后一个有效位置,一旦超出范围,运动就会停止,而不是在拖动结束后立即返回。......

边界/约束框的边缘似乎随着缩放级别而变化......有没有办法针对所有缩放级别修复它?
2021-03-22 22:04:37
这是一个很好的方法。我喜欢 brendo 的想法,但这会将橡皮筋移回原位,只是将地图停在边界处。我使用它将地图转换为静态图像,根本没有平移,但带有动态标记。非常便利。谢谢!
2021-03-28 22:04:37
我知道这里的代码有效,但在最后一行中, map.setCenter(...);map.panTo(...);? 后者似乎可能是奢侈的(CPU),因为它的目的只是阻止平移死在它的轨道上。
2021-03-29 22:04:37
有没有人想出如何在手机上做到这一点?在移动设备上拖动时不会出现 center_changed 或 drag 被调度
2021-04-01 22:04:37
太好了,center_changed事件是关键。但是在移动 (iOS) 设备上仍然存在一些问题。
2021-04-07 22:04:37

诀窍是监听dragend事件,如果地图被拖到允许的范围之外,请将其移回内部。如果您将允许的边界定义为LatLngBounds对象,则可以使用该contains()方法,因为如果给定的 lat/lng 参数在边界内,它会返回 true。

限制缩放级别也很重要,但您似乎已经在这样做了。

因此,您可能想尝试以下示例:

<!DOCTYPE html>
<html> 
<head> 
   <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
   <title>Google Maps JavaScript API v3 Example: Limit Panning</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"> 

   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 allowedBounds = 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 (allowedBounds.contains(map.getCenter())) return;

     // Out of bounds - Move the map back within the bounds

     var c = map.getCenter(),
         x = c.lng(),
         y = c.lat(),
         maxX = allowedBounds.getNorthEast().lng(),
         maxY = allowedBounds.getNorthEast().lat(),
         minX = allowedBounds.getSouthWest().lng(),
         minY = allowedBounds.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 示例:限制平移

在大地图上(当容器不是太小)默认情况下,还有允许用户导航的控件(导航面板)。使用可以按向左/向右箭头。因此,您的事件不足以解决所有问题。您将需要捕获空闲事件。很好的例子是这里code.google.com/p/gmaps-api-issues/issues/detail?id=1371一些人 isaac.z.foster 发布了它。但是无论如何,执行操作然后重新设置的逻辑非常糟糕。即使是默认情况下谷歌地图在几个世界的最大缩放级别上显示的最丑陋的东西。并且标记是重复的。谷歌代码真的很糟糕。
2021-03-18 22:04:37
也关于 minZoomLevel。有 minzoom 地图选项。不需要处理事件。
2021-04-06 22:04:37

我的版本基于@HenningJ 的版本,但对 进行了一些修改lastValidCenter以允许沿边界边缘平滑拖动

<!DOCTYPE html>
<html>
    <head>
        <style type="text/css">
            html { height: 100% }
            body { height: 100%; margin: 0; padding: 0 }
            #map-canvas { height: 100% }
        </style>
        <script type="text/javascript"
            src="http://maps.google.com/maps/api/js?sensor=false"></script>
        </script>
        <script type="text/javascript">
            function initialize() {
                var mapOptions = {
                    center: new google.maps.LatLng(28.70, -127.50),
                    zoom: 4,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                };
                var map = new google.maps.Map(document.getElementById("map-canvas"),
                        mapOptions);

                // bounds of the desired area
                var allowedBounds = new google.maps.LatLngBounds(
                  new google.maps.LatLng(28.70, -127.50),
                  new google.maps.LatLng(48.85, -55.90)
                );
                var boundLimits = {
                    maxLat : allowedBounds.getNorthEast().lat(),
                    maxLng : allowedBounds.getNorthEast().lng(),
                    minLat : allowedBounds.getSouthWest().lat(),
                    minLng : allowedBounds.getSouthWest().lng()
                };

                var lastValidCenter = map.getCenter();
                var newLat, newLng;
                google.maps.event.addListener(map, 'center_changed', function() {
                    center = map.getCenter();
                    if (allowedBounds.contains(center)) {
                        // still within valid bounds, so save the last valid position
                        lastValidCenter = map.getCenter();
                        return;
                    }
                    newLat = lastValidCenter.lat();
                    newLng = lastValidCenter.lng();
                    if(center.lng() > boundLimits.minLng && center.lng() < boundLimits.maxLng){
                        newLng = center.lng();
                    }
                    if(center.lat() > boundLimits.minLat && center.lat() < boundLimits.maxLat){
                        newLat = center.lat();
                    }
                    map.panTo(new google.maps.LatLng(newLat, newLng));
                });
            }
            google.maps.event.addDomListener(window, 'load', initialize);
        </script>
    </head>
    <body>
        <div id="map-canvas"/>
    </body>
</html>

在这里小提琴:http : //jsfiddle.net/koenpunt/n7h6t/

这必须是一个答案
2021-03-16 22:04:37
它与@HenningJ 的解决方案存在同样的问题。这只是检查地图的中心是否在边界内。如果地图的中心紧邻边界,则地图的一半位于边界之外。因此,需要更花哨的计算(中心可能是低缩放级别的一个很好的近似值,但不适用于世界视图)——
2021-03-21 22:04:37
不太好,好像您仍然希望人们放大/缩小
2021-03-30 22:04:37

这是对上述内容的一个很好的扩展,它将通过侦听 dragstart 事件将地图的中心重置为最后一个有效位置。

// Limit panning
var lastCenter = map.getCenter();

google.maps.event.addListener(map, 'dragstart', function() {
    lastCenter = map.getCenter();
});

google.maps.event.addListener(map, 'dragend', function() {
    if(allowedBounds.contains(map.getCenter())) return;

    map.setCenter(lastCenter);
});

限制的最佳方法是,设置缩放级别和中心点并禁用缩放、滚动等控件,如下所示。

 var latlng = new google.maps.LatLng(18.283078,84.047556);
     var myOptions = {
          zoom: 12,

          center: latlng,
          zoomControl: false,
          mapTypeId: google.maps.MapTypeId.ROADMAP,
          scrollwheel: false,
        navigationControl: false,
        mapTypeControl: false,
        scaleControl: false,
        draggable: false,
        disableDoubleClickZoom: true,
        };
        map = new google.maps.Map(document.getElementById("map_canvas"),   myOptions);
如果您想完全限制平移和缩放,而不是按照要求“限制在某些范围内”,这是一个很好的解决方案。如果地图已经存在并且您想在创建后锁定它,您也可以使用 map.setOptions()。
2021-04-03 22:04:37