简体   繁体   English

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

[英]Google Maps v3 - limit viewable area and zoom level

is it possible to limit Google map v3 to a certain area? 是否可以将Google地图v3限制在某个区域? I want to allow displaying only some area (eg a country) and disallow the user to slide elsewhere. 我想允许只显示某个区域(例如国家/地区)并禁止用户滑动到其他位置。 Also I want to restrict the zoom level - eg only between levels 6 and 9. And I want to use all the base map types. 此外,我想限制缩放级别 - 例如仅在级别6和9之间。我想使用所有基本地图类型。

Is there any way to achieve this? 有没有办法实现这个目标?

I had a partial success with limiting zoom level by using StyledMap, but I succeeded only with restricting ROADMAP, I wasn't able to limit zoom on other basic types this way. 我通过使用StyledMap限制缩放级别取得了部分成功,但我仅限制了ROADMAP,我无法通过这种方式限制其他基本类型的缩放。

Thanks for any help 谢谢你的帮助

Better way to restrict zoom level might be to use the minZoom / maxZoom options rather than reacting to events? 限制缩放级别的更好方法可能是使用minZoom / maxZoom选项而不是对事件做出反应?

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

Or the options can be specified during map initialization, eg: 或者可以在地图初始化期间指定选项,例如:

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

See: Google Maps JavaScript API V3 Reference 请参阅: Google Maps JavaScript API V3参考

You can listen to the dragend event, and if the map is dragged outside the allowed bounds, move it back inside. 您可以收听dragend事件,如果将地图拖到允许范围之外,则将其移回内部。 You can define your allowed bounds in a LatLngBounds object and then use the contains() method to check if the new lat/lng center is within the bounds. 您可以在LatLngBounds对象中定义允许的边界,然后使用contains()方法检查新的lat / lng中心是否在边界内。

You can also limit the zoom level very easily. 您还可以非常轻松地限制缩放级别。

Consider the following example: 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>

Screenshot from the above example. 以上示例的屏幕截图。 The user will not be able to drag further south or far east in this case: 在这种情况下,用户将无法再向南或远东拖动:

Google Maps JavaScript API v3示例:强制停止地图拖动

Good news. 好消息。 Starting from the version 3.35 of Maps JavaScript API, that was launched on February 14, 2019, you can use new restriction option in order to limit the viewport of the map. 从2019年2月14日推出的Maps JavaScript API版本3.35开始,您可以使用新的restriction选项来限制地图的视口。

According to the documentation 根据文件

MapRestriction interface MapRestriction接口

A restriction that can be applied to the Map. 可应用于Map的限制。 The map's viewport will not exceed these restrictions. 地图的视口不会超出这些限制。

source: https://developers.google.com/maps/documentation/javascript/reference/3.35/map#MapRestriction 来源: https//developers.google.com/maps/documentation/javascript/reference/3.35/map#MapRestriction

So, now you just add restriction option during a map initialization and that it. 所以,现在你只需在地图初始化期间添加限制选项即可。 Have a look at the following example that limits viewport to Switzerland 看看以下限制视口到瑞士的示例

 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> 

I hope this helps! 我希望这有帮助!

To limit the zoom on v.3+. 限制v.3 +的缩放。 in your map setting add default zoom level and minZoom or maxZoom (or both if required) zoom levels are 0 to 19. You must declare deafult zoom level if limitation is required. 在地图设置中添加默认缩放级别和minZoom或maxZoom(或两者,如果需要)缩放级别为0到19.如果需要限制,则必须声明deafult缩放级别。 all are case sensitive! 一切都区分大小写!

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

Much better way to limit the range... used the contains logic from above poster. 限制范围的更好方法...使用上面海报中的包含逻辑。

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 can be used to re-center the map to a specific location. 这可用于将地图重新​​定位到特定位置。 Which is what I needed. 这就是我需要的。

    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));
        }
    });
myOptions = {
        center: myLatlng,
        minZoom: 6,
        maxZoom: 9,
        styles: customStyles,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

Here's my variant to solve the problem of viewable area's limitation. 这是我解决可视区域限制问题的变种。

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

strictBounds is an object of new google.maps.LatLngBounds() type. strictBoundsnew google.maps.LatLngBounds()类型的对象。 self.gmap stores a Google Map object ( new google.maps.Map() ). self.gmap存储Google Map对象( new google.maps.Map() )。

It really works but don't only forget to take into account the haemorrhoids with crossing 0th meridians and parallels if your bounds cover them. 它确实有效,但是如果你的界限覆盖它们,不仅忘记考虑穿过0号经络和平行线的痔疮。

For some reason 由于某些原因

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

didnt work for me (maybe a southern hemisphere issue). 对我没用(可能是南半球问题)。 I had to change it to: 我不得不把它改成:

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

Hope it will help someone. 希望它会帮助某人。

One solution is like, If you know the specific lat/lng. 一个解决方案是,如果你知道具体的lat / lng。

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

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

});

If don't have specific lat/lng 如果没有特定的lat / lng

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

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

});

or 要么

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

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

});

As of middle 2016 , there is no official way to restrict viewable area. 截至2016年中期 ,没有官方方式来限制可视区域。 Most of ad-hoc solutions to restrict the bounds have a flaw though, because they don't restrict the bounds exactly to fit the map view, they only restrict it if the center of the map is out of the specified bounds. 大多数限制边界的临时解决方案都存在缺陷,因为它们不会严格限制边界以适应地图视图,只有在地图中心超出指定边界时才会限制它。 If you want to restrict the bounds to overlaying image like me, this can result in a behavior like illustrated below, where the underlaying map is visible under our image overlay: 如果你想限制像我一样覆盖图像的边界,这可能会导致如下图所示的行为,其中底层地图在我们的图像叠加下可见:

在此输入图像描述

To tackle this issue, I have created a library , which successfully restrict the bounds so you cannot pan out of the overlay. 为了解决这个问题,我创建了一个 ,它成功地限制了边界,因此您无法平移覆盖。

However, as other existing solutions, it has a "vibrating" issue. 然而,作为其他现有解决方案,它具有“振动”问题。 When the user pans the map aggressively enough, after they release the left mouse button, the map still continues panning by itself, gradually slowing. 当用户足够积极地平移地图时,在他们释放鼠标左键后,地图仍然会自动继续平移,逐渐减慢。 I always return the map back to the bounds, but that results in kind of vibrating. 我总是将地图返回到边界,但这会导致振动。 This panning effect cannot be stopped with any means provided by the Js API at the moment. 此刻平移效果无法通过Js API提供的任何方式停止。 It seems that until google adds support for something like map.stopPanningAnimation() we won't be able to create a smooth experience. 似乎在Google添加对map.stopPanningAnimation()等内容的支持之前,我们将无法创建流畅的体验。

Example using the mentioned library, the smoothest strict bounds experience I was able to get: 使用上述库的示例,我能够得到的最顺畅的严格边界体验:

 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> 

The library is also able to calculate the minimum zoom restriction automatically. 该库还能够自动计算最小缩放限制。 It then restricts the zoom level using minZoom map's attribute. 然后使用minZoom贴图的属性限制缩放级别。

Hopefully this helps someone who wants a solution which fully respect the given boundaries and doesn't want to allow panning out of them. 希望这有助于那些想要一个完全尊重给定边界并且不想让它们平移的解决方案的人。

This may be helpful. 这可能会有所帮助。

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

The Zoom level can be customizable according to the requirement. 可根据要求自定义缩放级别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM