Javascript 谷歌地图 v3:强制执行分钟。使用 fitBounds 时的缩放级别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2989858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:48:57  来源:igfitidea点击:

Google Maps v3: Enforcing min. zoom level when using fitBounds

javascriptgoogle-mapsgoogle-maps-api-3fitbounds

提问by chris

I'm drawing a series of markers on a map (using v3 of the maps api).

我正在地图上绘制一系列标记(使用地图 API 的 v3)。

In v2, I had the following code:

在 v2 中,我有以下代码:

  bounds = new GLatLngBounds();

  ... loop thru and put markers on map ...
  bounds.extend(point);
  ... end looping

  map.setCenter(bounds.getCenter());
  var level = map.getBoundsZoomLevel(bounds);
  if ( level == 1 ) 
    level = 5;
  map.setZoom(level > 6 ? 6 : level);

And that work fine to ensure that there was always an appropriate level of detail displayed on the map.

这工作得很好,以确保地图上始终显示适当的细节级别。

I'm trying to duplicate this functionality in v3, but the setZoom and fitBounds don't seem to be cooperating:

我试图在 v3 中复制此功能,但 setZoom 和 fitBounds 似乎没有合作:

... loop thru and put markers on the map
  var ll = new google.maps.LatLng(p.lat,p.lng);
  bounds.extend(ll);
... end loop

var zoom = map.getZoom();
map.setZoom(zoom > 6 ? 6 : zoom);
map.fitBounds(bounds);

I've tried different permutation (moving the fitBounds before the setZoom, for example) but nothing I do with setZoom seems to affect the map. Am I missing something? Is there a way to do this?

我尝试了不同的排列(例如,在 setZoom 之前移动 fitBounds),但我对 setZoom 所做的一切似乎都不会影响地图。我错过了什么吗?有没有办法做到这一点?

回答by Malks

At this discussion on Google GroupsI discovered that basically when you do a fitBounds, the zoom happens asynchronously so you need to capture the zoom and bounds change event. The code in the final post worked for me with a small modification... as it stands it stops you zooming greater than 15 completely, so used the idea from the fourth post to have a flag set to only do it the first time.

这次关于 Google Groups 的讨论中,我发现基本上当您执行 fitBounds 时,缩放会异步发生,因此您需要捕获缩放和边界更改事件。最后一篇文章中的代码对我做了一个小的修改......就目前而言,它完全阻止了你放大超过 15 倍,所以使用了第四篇文章中的想法来设置一个标志,只在第一次这样做。

// Do other stuff to set up map
var map = new google.maps.Map(mapElement, myOptions);
// This is needed to set the zoom after fitbounds, 
google.maps.event.addListener(map, 'zoom_changed', function() {
    zoomChangeBoundsListener = 
        google.maps.event.addListener(map, 'bounds_changed', function(event) {
            if (this.getZoom() > 15 && this.initialZoom == true) {
                // Change max/min zoom here
                this.setZoom(15);
                this.initialZoom = false;
            }
        google.maps.event.removeListener(zoomChangeBoundsListener);
    });
});
map.initialZoom = true;
map.fitBounds(bounds);

Hope that helps,

希望有所帮助,

Anthony.

安东尼。

回答by Flygenring

Without trying it, I'd say you should be able to do it just by having fitBounds()before you get the zoom level, i.e.

无需尝试,我会说您应该能够fitBounds()在获得缩放级别之前完成它,即

map.fitBounds(bounds);
var zoom = map.getZoom();
map.setZoom(zoom > 6 ? 6 : zoom);

If you did try that and it didn't work, you can setup your map with minZoomin the MapOptions(api-reference)like this:

如果您确实尝试过但它不起作用,您可以minZoomMapOptions(api-reference)中设置您的地图,如下所示:

var map = new google.maps.Map(document.getElementById("map"), { minZoom: 6 });

This would keep the map from zooming any further out when using fitBounds().

这将防止地图在使用时进一步缩小fitBounds()

回答by Joost

You can also set the maxZoom option just before calling fitBounds() and reset the value afterwards:

您还可以在调用 fitBounds() 之前设置 maxZoom 选项并在之后重置该值:

if(!bounds.isEmpty()) {
    var originalMaxZoom = map.maxZoom;
    map.setOptions({maxZoom: 18});
    map.fitBounds(bounds);
    map.setOptions({maxZoom: originalMaxZoom});
}

回答by Angry Dan

Anthony's solution is very nice. I only needed to fix the zoom for the inital page load (ensuring that you weren't too far zoomed in to start with) and this did the trick for me:

Anthony 的解决方案非常好。我只需要修复初始页面加载的缩放(确保您开始时不会放大太远),这对我来说很有效:

var zoomChangeBoundsListener =
    google.maps.event.addListener(map, 'bounds_changed', function(event) {
        google.maps.event.removeListener(zoomChangeBoundsListener);
        map.setZoom( Math.min( 15, map.getZoom() ) );
    });


map.fitBounds( zoomBounds );

回答by Mark Swardstrom

When you call map.fitBounds() on one item - the map may zoom in too closely. To fix this, simply add 'maxZoom' to mapOptions...

当您在一项上调用 map.fitBounds() 时 - 地图可能会放大得太近。要解决此问题,只需将 'maxZoom' 添加到 mapOptions...

var mapOptions = {
  maxZoom: 15
};

回答by oucil

In my case, I simply wanted to set the zoom level to one less than what google maps chose for me during fitBounds. The purpose was to use fitBounds, but also ensure no markers were under any map tools, etc.

就我而言,我只是想将缩放级别设置为比 fitBounds 期间谷歌地图为我选择的级别小一。目的是使用 fitBounds,但也要确保任何地图工具等下都没有标记。

My map is created early and then a number of other dynamic components of the page have an opportunity to add markers, calling fitBounds after each addition.

我的地图很早就创建了,然后页面的许多其他动态组件有机会添加标记,在每次添加后调用 fitBounds。

This is in the initial block where the map object is originally created...

这是在最初创建地图对象的初始块中...

var mapZoom = null;

Then this is added to each block where a marker is added, right before the map.fitBounds is called...

然后将其添加到添加标记的每个块中,就在调用 map.fitBounds 之前...

google.maps.event.addListenerOnce(map, 'bounds_changed', function() { 
    if (mapZoom != map.getZoom()) { 
        mapZoom = (map.getZoom() - 1); 
        map.setZoom(mapZoom); 
    } 
});

When using 'bounds_changed' without the check in place, the map zoomed out once for every marker regardless of whether it needed it or not. Conversely, when I used 'zoom_changed', I would sometimes have markers under map tools because the zoom didn't actually change. Now it is always triggered, but the check ensures that it only zooms out once and only when needed.

当使用 'bounds_changed' 而不进行检查时,无论是否需要,地图都会为每个标记缩小一次。相反,当我使用“zoom_changed”时,有时我会在地图工具下有标记,因为缩放实际上并没有改变。现在它总是被触发,但检查确保它只在需要时缩小一次。

Hope this helps.

希望这可以帮助。

回答by tuned

Since Google Maps V3 is event driven, you can tell the API to set back the zoom to a proper amount when the zoom_changedevent triggers:

由于 Google Maps V3 是事件驱动的,您可以告诉 API 在zoom_changed事件触发时将缩放设置回适当的量:

var initial = true
google.maps.event.addListener(map, "zoom_changed", function() {
    if (initial == true){
       if (map.getZoom() > 11) {
         map.setZoom(11);
         initial = false;
       }
    }
}); 

I used initialto make the map not zooming too much when the eventual fitBounds is permorfed, but to let the user zoom as much as he/she wants. Without the condition any zoom event over 11 would be possible for the user.

当最终的 fitBounds 被 permorfed 时,我使用initial使地图不会缩放太多,而是让用户缩放到他/她想要的程度。如果没有该条件,用户可能会遇到超过 11 的任何缩放事件。

回答by Jan K.

I found the following to work quite nicely. It is a variant on Ryan's answerto https://stackoverflow.com/questions/3334729/.... It guarantees to show an area of at least two times the value of offsetin degrees.

我发现以下工作非常好。这是 Ryan对https://stackoverflow.com/questions/3334729/...回答的一个变体。它保证显示的面积至少是度数的两倍。offset

const center = bounds.getCenter()
const offset = 0.01
const northEast = new google.maps.LatLng(
    center.lat() + offset,
    center.lng() + offset
)
const southWest = new google.maps.LatLng(
    center.lat() - offset,
    center.lng() - offset
)
const minBounds = new google.maps.LatLngBounds(southWest, northEast)
map.fitBounds(bounds.union(minBounds))