ChatGPT解决这个技术问题 Extra ChatGPT

在将 fitBounds() 与 Google Maps API V3 一起使用后使用 setZoom()

我正在使用 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.fitBounds(this.map.bounds);,行 this.map.map.setZoom(16); 不起作用,但是,我知道这行代码是正确的,因为当我注释掉 fitBound() 行时,setZoom()神奇地开始运作。

任何想法我如何解决这个问题?如果我不能让它工作,我正在考虑设置一个 maxZoom 级别作为替代方案。

.map.map 是故意的还是错误的?如果可能的话,上传一个测试页面并提供一个链接,这样我们就可以更容易地看到问题。
我有同样的问题。很想知道一个修复。
.map.map 是故意的。第一个指的是我的地图对象,第二个指的是谷歌地图对象。我已经从我的代码中清除了这个问题。

H
Herman Schaaf

好吧,我已经想通了。显然, 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);

更新:使用 addListenerOnce 查看 @Nequin 的答案以获得不需要超时的更好解决方案。


很好的解决方案,也为我工作。尽管您可以执行 addListenerOnce() 来取消 removeListener() 调用。
除了使用 addListenerOnce 之外,我还建议使用 setTimeout 来删除监听器。我有一个案例,因为标记彼此非常接近,所以边界没有改变。使用此代码,用户将无法缩放(至少一次)。
@MikePurcell & h0tw1r3:我编辑了代码以添加您的建议,谢谢!没有测试它,所以希望我没有引入任何愚蠢的错误。
@Herman .....thnx herman 我在这个问题上已经坚持了大约 3 个小时......再次......
我不得不将 removeListener 放在 addListener 回调函数中。否则执行会在调用它之前移除监听器。
M
Mathias Bynens
google.maps.event.addListenerOnce(yourMap, 'bounds_changed', function(event) {
  if (this.getZoom() > 15) {
    this.setZoom(15);
  }
});

这个解决方案效果更好……而不是等待超时来删除监听器。在使用 fitBounds 之前直接调用它(我相信之后调用也可以)。


很好的解决方案。可以通过使用 google.maps.event.addListenerOnce 而不是添加然后删除侦听器来使其更好。
我冒昧地编辑了使用 addListenerOnce 的答案。
该解决方案对我不起作用。 this.getZoom() 在回调中始终未定义,并且 this.setZoom() 无效。
完美,最佳答案
请记住使用 this 时的问题,我将改为使用对传递给事件处理程序的映射的引用,例如:if (yourMap.getZoom() > 15) { ... }。听起来@horace 有问题,这可能是指正在完成实现的当前类或 google.maps.event 实例。如果您只想使用传入的地图引用,请避免使用此选项。
E
Emery Lapinski

我发现额外的变焦有点刺耳。如果您在调用 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
    });
});

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

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

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++;

但是你知道为什么两者不合作吗?我不明白为什么这些在串行调用时不兼容。
M
Mike G

我只是在函数 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;
    },

h
horace

所有带有事件监听器的解决方案都对我不起作用(this.getZoom() 在回调中总是未定义,this.setZoom() 没有效果)。

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

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);