Javascript Google Maps v3:使用fitBounds时强制执行最小缩放级别

Javascript Google Maps v3:使用fitBounds时强制执行最小缩放级别,javascript,google-maps,google-maps-api-3,fitbounds,Javascript,Google Maps,Google Maps Api 3,Fitbounds,我正在地图上绘制一系列标记(使用MapsAPI的v3) 在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 (

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

在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);
这样做可以确保地图上始终显示适当的细节

我试图在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);
我尝试过不同的排列(例如,在setZoom之前移动fitBounds),但我对setZoom所做的任何操作似乎都不会影响贴图。我错过什么了吗?有什么方法可以做到这一点吗?

在我发现,基本上,当您执行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);
希望有帮助


Anthony。

如果不尝试,我想说您应该能够在获得缩放级别之前使用
fitBounds()
,即

map.fitBounds(bounds);
var zoom = map.getZoom();
map.setZoom(zoom > 6 ? 6 : zoom);
如果您确实尝试了,但没有成功,您可以在
MapOptions
中使用
minZoom
设置地图,如下所示:

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

当使用
fitBounds()
时,这将防止地图进一步缩小,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 );

在我的例子中,我只是想将缩放级别设置为比google maps在fitBounds期间为我选择的级别低一级。其目的是使用fitBounds,但也要确保任何地图工具下都没有标记,等等

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

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

var mapZoom = null;
然后在调用map.fitBounds之前,将其添加到添加标记的每个块中

google.maps.event.addListenerOnce(map, 'bounds_changed', function() { 
    if (mapZoom != map.getZoom()) { 
        mapZoom = (map.getZoom() - 1); 
        map.setZoom(mapZoom); 
    } 
});
当使用“bounds_changed”而不进行检入时,无论是否需要,地图都会为每个标记缩小一次。相反,当我使用“zoom_changed”时,我有时会在地图工具下使用标记,因为缩放实际上没有改变。现在它总是被触发,但检查确保它只在需要时缩小一次


希望这有帮助。

当您对一个项目调用map.fitBounds()时,地图可能放大得太近。要解决此问题,只需将“maxZoom”添加到mapOptions

var mapOptions = {
  maxZoom: 15
};

由于Google Maps V3是事件驱动的,因此当zoom_changed事件触发时,您可以告诉API将缩放设置为适当的大小:

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

我使用initial使地图在最终的fitBounds被permorfed时不会放大太多,而是让用户可以随心所欲地放大。如果没有该条件,用户可以在11上执行任何缩放事件

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

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

我发现以下方法非常有效。这是Ryan的to的变体。它保证显示的面积至少是
偏移值的两倍,单位为度

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

我只是有同样的任务要解决,并使用一个简单的函数来解决它

它不关心边界中有多少标记-如果有很多标记,并且缩放已经很远,这会缩小一点,但是当只有一个标记(或者很多标记彼此非常接近)时,缩放是重要的(可使用
extendBy
变量自定义):

要使用它,我使用自己的函数执行
fitBounds()

地图是我的谷歌地图对象


这是一个好方法。另一种方法是检查当前边界并扩展边界,即。虽然这里的链接答案只是将边界扩展了一小部分,但您可以使用相同的方法将边界扩展一个更大的数字;我发现向所有角落添加7都很好。我想更正我之前的评论。我认为可能需要设置initialZoom属性。在省略了这部分代码后,我在放大IE 9时遇到了一些麻烦。。。很酷的解决方案!使用
google.maps.event.addListenerOnce()
,这样以后就不必手动删除侦听器了。因为我已经第三次看到这个了,这里是golfed版本。谢谢@pstadler
google.maps.event.addListenerOnce(映射,'bounds_changed',function(){this.setZoom(Math.min(15,this.getZoom());})
使用AddListener时,您可以简单地收听
zoom\u changed
。我正在使用
zoom\u changed
就在
map.fitbunds(bounds)之前并且似乎在Chrome上工作得很好。很好的简单而优雅的解决方案!设置minZoom和maxZoom值会限制用户缩放超过这些值,因此,如果您只想将初始缩放设置为合理的值(这是我认为OP所说的),那么它也没有帮助,因此基本上与我在回答中所写的差不多?@Izazael提出了一个很好的观点,答案中没有涉及到这一点。这非常有助于阻止
fitBounds()
缩放过远,但也会限制用户与地图缩放按钮的交互。如果您希望用户拥有完全控制权,那么接受的答案是更好的选择。可能不起作用,因为有新版本。fitBounds()异步工作!您可以使用
addListenerOnce
而不是删除侦听器,但我使用的是此解决方案。这似乎是唯一一个真正应该使用
addListener
的答案,而不是在每个
映射之前重复(并依靠记忆)到
addListenerOnce
我喜欢此选项,因为它不会像许多其他选项一样导致
zoom\u changed
事件触发两次
var extendBounds = function() {
  // Extends the Bounds so that the Zoom Level on fitBounds() is a bit farer away
  var extendBy = 0.005;
  var point1 = new google.maps.LatLng(
    bounds.getNorthEast().lat() + extendBy,
    bounds.getNorthEast().lng() + extendBy
  )
  var point2 = new google.maps.LatLng(
    bounds.getSouthWest().lat() - extendBy,
    bounds.getSouthWest().lng() - extendBy
  )
  bounds.extend(point1);
  bounds.extend(point2);
}
var refreshBounds = function() {
  extendBounds();
  map.fitBounds(bounds);
}