将fitBounds()与Google Maps API V3结合使用后,使用setZoom()


78

我正在使用fitBounds()在地图上设置缩放级别,也包括当前显示的所有标记。但是,当我只看到一个标记时,缩放比例为100%(...我认为是20的缩放比例...)。但是,我不希望它被放大得那么远,以便用户无需缩小就可以调整标记的位置。

我有以下代码:

var marker = this.map.createMarker(view.latlng, this.markerNumber);
this.map.bounds.extend(view.latlng);
this.map.map.setCenter(this.map.bounds.getCenter());
this.map.map.fitBounds(this.map.bounds);
if (this.markerNumber === 1) {
  this.map.map.setZoom(16);
}
this.markerNumber++;

之前this.map.bounds定义为:

this.map.bounds = new google.maps.LatLngBounds();

但是,我遇到的问题是,this.map.map.setZoom(16);如果使用this.map.map.fitBounds(this.map.bounds);,则该行不起作用,但是,我知道代码行是正确的,因为当我注释掉fitBound()行时,setZoom()会神奇地开始运行。

有什么想法可以解决吗?如果无法正常工作,我正在考虑设置maxZoom级别作为替代。


.map.map是故意存在的还是有错误?如果可能,请上传测试页并提供链接,我们可以更轻松地查看问题。
Argiropoulos Stavros 2010年

我有同样的问题。很想知道一个解决方法。
Herman Schaaf

.map.map是故意存在的。第一个引用我的地图对象,第二个引用谷歌地图对象。此后,我已经从代码中清除了此问题。
安德鲁·德·安德拉德

Answers:


111

好了,我知道了。显然,fitbounds()是异步发生的,因此bounds_changed在设置缩放有效之前,您必须等待事件。

map = this.map.map;

map.fitBounds(this.map.bounds);
zoomChangeBoundsListener = 
    google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
        if (this.getZoom()){
            this.setZoom(16);
        }
});
setTimeout(function(){google.maps.event.removeListener(zoomChangeBoundsListener)}, 2000);

更新:请参阅@Nequin的答案,以addListenerOnce获取不需要超时的更好解决方案。


10
不错的解决方案,也为我工作。尽管您可以做到addListenerOnce(),但可以取消removeListener()通话。
Mike Purcell

2
除了使用addListenerOnce之外,我建议使用setTimeout删除侦听器。我遇到了一种情况,因为标记彼此之间非常接近,所以边界没有变化。使用此代码,用户将无法缩放(至少一次)。
h0tw1r3 2012年

@MikePurcell和h0tw1r3:我编辑了代码以添加您的建议,谢谢!没有测试,所以希望我不要引入任何愚蠢的错误。
Herman Schaaf 2012年

@Herman ..... thnx herman我在这个问题上停留了大约3个小时... thnx再次...
Usman

1
我必须将removeListener放在addListener回调函数中。否则,执行过程甚至会在调用侦听器之前将其删除。
阿曼·比马托夫

104
google.maps.event.addListenerOnce(yourMap, 'bounds_changed', function(event) {
  if (this.getZoom() > 15) {
    this.setZoom(15);
  }
});

此解决方案效果更好……而不是等待超时来删除侦听器。请在使用前直接致电fitBounds(我相信以后也可以致电)。


4
好的解决方案。通过使用google.maps.event.addListenerOnce而不是添加然后删除侦听器的方法,可以使它更好。
chuck w

3
我已自由编辑要使用的答案addListenerOnce
Mathias Bynens 2014年

1
该解决方案对我不起作用。this.getZoom()在回调中始终未定义,而this.setZoom()无效。
horace

完美,最佳答案
00-BBB

记住使用此方法的问题,我将改为使用对传递给事件处理程序的映射的引用,如下所示:if (yourMap.getZoom() > 15) { ... }。听起来@horace遇到了问题,可能这是指正在执行实现的当前类或google.maps.event实例。如果只想使用传入的对地图的引用,请避免使用此选项。
Sparker73 '19

16

我发现额外的缩放有些刺耳。如果在调用fitBounds之前设置了maxZoom选项(然后在回调中将其取消设置),则可以避免使用它:

map.setOptions({
    maxZoom: 10
});

map.setCenter(new google.maps.LatLng(-89, -179)); // make sure it changes so the idle listener gets called back

map.fitBounds(bounds);

var listener = google.maps.event.addListenerOnce(map, "idle", function()
{
    map.setOptions({
        maxZoom: 999
    });
});

更好的解决方案,因为在边界更改后设置缩放(如其他答案所建议的那样)将不会很平滑,实际上将非常难看。
Pedro Estevao

2

我有简单而肮脏的解决方案。
使用其他...

var marker = this.map.createMarker(view.latlng, this.markerNumber);
this.map.bounds.extend(view.latlng);
this.map.map.setCenter(this.map.bounds.getCenter()); 
if (this.markerNumber === 1) {
  this.map.map.setZoom(16);
} else {
   this.map.map.fitBounds(this.map.bounds);
}       
this.markerNumber++;

1
但是你知道为什么两者不能一起工作吗?我不明白为什么在串行调用时这些不兼容。
安德鲁·德·安德拉德

1

我只向函数添加了一行,addBounds(position)并对其进行了修复,如下所示:

    addBounds: function(position) {
        this.get('bounds', new google.maps.LatLngBounds()).extend(this._latLng(position));
        this.get('map').fitBounds(this.get('bounds'));
        this.get('map').setZoom(16);//line added
        return this;
    },

0

所有使用事件侦听器的解决方案都不适合我(在回调中始终未定义this.getZoom(),而this.setZoom()无效)。

我想出了一个效果很好的解决方案:

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.