Javascript Google Maps API v3:我可以在 fitBounds 之后 setZoom 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2437683/
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 00:19:57  来源:igfitidea点击:

Google Maps API v3: Can I setZoom after fitBounds?

javascriptgoogle-mapsgoogle-maps-api-3fitbounds

提问by chris

I have a set of points I want to plot on an embedded Google Map (API v3). I'd like the bounds to accommodate all points unless the zoom level is too low (i.e., zoomed out too much). My approach has been like this:

我有一组要在嵌入式 Google 地图(API v3)上绘制的点。我希望边界能够容纳所有点,除非缩放级别太低(即缩小太多)。我的方法是这样的:

var bounds = new google.maps.LatLngBounds();

// extend bounds with each point

gmap.fitBounds(bounds); 
gmap.setZoom( Math.max(6, gmap.getZoom()) );

This doesn't work. The last line "gmap.setZoom()" doesn't change the zoom level of the map if called directly after fitBounds.

这不起作用。如果在 fitBounds 之后直接调用,最后一行“gmap.setZoom()”不会改变地图的缩放级别。

Is there a way to get the zoom level of a bounds without applying it to the map? Other ideas to solve this?

有没有办法在不将其应用于地图的情况下获得边界的缩放级别?解决这个问题的其他想法?

回答by LGT

Edit: See Matt Diamond's comment below.

编辑:请参阅下面的 Matt Diamond 评论。

Got it! Try this:

知道了!尝试这个:

map.fitBounds(bounds);
var listener = google.maps.event.addListener(map, "idle", function() { 
  if (map.getZoom() > 16) map.setZoom(16); 
  google.maps.event.removeListener(listener); 
});

Modify to your needs.

根据您的需要进行修改。

回答by Jim Garvin

I solved a similar problem in one of my apps. I was a little confused by your description of the problem, but I think you have the same goal I had...

我在我的一个应用程序中解决了类似的问题。你对问题的描述让我有点困惑,但我认为你的目标和我一样......

In my app I wanted to plot a one or more markers and ensure the map was showing them all. The problem was, if I relied solely on the fitBounds method, then the zoom-level would be maxed out when there was a single point - that was no good.

在我的应用程序中,我想绘制一个或多个标记并确保地图显示所有标记。问题是,如果我只依赖 fitBounds 方法,那么当只有一个点时缩放级别会被最大化 - 这不好。

The solution was to use fitBounds when there was many points, and setCenter+setZoom when there was only one point.

解决方案是当点多时使用fitBounds,当只有一个点时使用setCenter+setZoom。

if (pointCount > 1) {
  map.fitBounds(mapBounds);
}
else if (pointCount == 1) {
  map.setCenter(mapBounds.getCenter());
  map.setZoom(14);
}

回答by Benjamin Sussman

I have come to this page multiple times to get the answer, and while all the existing answers were super helpful, they did not solve my problem exactly.

我多次来到此页面以获得答案,虽然所有现有答案都非常有帮助,但它们并没有完全解决我的问题。

google.maps.event.addListenerOnce(googleMap, 'zoom_changed', function() {
    var oldZoom = googleMap.getZoom();
    googleMap.setZoom(oldZoom - 1); //Or whatever
});

Basically I found that the 'zoom_changed' event prevented the UI of the map from "skipping" which happened when i waited for the 'idle' event.

基本上我发现 'zoom_changed' 事件阻止了地图的用户界面在我等待 'idle' 事件时发生的“跳过”。

Hope this helps somebody!

希望这对某人有帮助!

回答by Robin Whittleton

I've just fixed this by setting maxZoom in advance, then removing it afterwards. For example:

我只是通过预先设置 maxZoom 来解决这个问题,然后再将其删除。例如:

map.setOptions({ maxZoom: 15 });
map.fitBounds(bounds);
map.setOptions({ maxZoom: null });

回答by Lester S

If I'm not mistaken, I'm assuming you want all your points to be visible on the map with the highest possible zoom level. I accomplished this by initializing the zoom level of the map to 16(not sure if it's the highest possible zoom level on V3).

如果我没记错的话,我假设您希望您的所有点都以尽可能高的缩放级别在地图上可见。我通过将地图的缩放级别初始化为16(不确定它是否是 V3 上可能的最高缩放级别)来完成此操作。

var map = new google.maps.Map(document.getElementById('map_canvas'), {
  zoom: 16,
  center: marker_point,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

Then after that I did the bounds stuff:

然后我做了边界的东西:

var bounds = new google.maps.LatLngBounds();

// You can have a loop here of all you marker points
// Begin loop
bounds.extend(marker_point);
// End loop

map.fitBounds(bounds);

Result: Success!

结果:成功!

回答by ytg

I use:

我用:

gmap.setZoom(24); //this looks a high enough zoom value
gmap.fitBounds(bounds); //now the fitBounds should make the zoom value only less

This will use the smaller of 24 and the necessary zoom level according to your code, however it probably changes the zoom anyway and doesn't care about how much you zoomed out.

这将根据您的代码使用 24 和必要的缩放级别中的较小者,但是无论如何它可能会更改缩放并且不关心您缩小了多少。

回答by Atif Tariq

Please try this:

请试试这个:

map.fitBounds(bounds);

// CHANGE ZOOM LEVEL AFTER FITBOUNDS
zoomChangeBoundsListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  if (this.getZoom()){
    this.setZoom(15);
  }
});
setTimeout(function(){
  google.maps.event.removeListener(zoomChangeBoundsListener)
}, 2000);

回答by Svilen Marchev

I saw many incorrect or too complicated solutions, so decided to post a working, elegant solution.

我看到了许多不正确或过于复杂的解决方案,因此决定发布一个有效的、优雅的解决方案

The reason setZoom()doesn't work as you expect is that fitBounds()is asynchronous, so it gives no guarantee that it would immediately update the zoom, but your call to setZoom()relies on that.

原因setZoom()不像您期望的那样工作,因为它fitBounds()是异步的,因此不能保证它会立即更新缩放,但是您对它的调用setZoom()依赖于此。

What you might consider is setting the minZoommap option before calling fitBounds()and then clearing it after it completes (so that users can still zoom out manually if they want to):

您可能会考虑minZoom在调用之前设置地图选项fitBounds(),然后在完成后将其清除(以便用户仍然可以手动缩小,如果他们愿意):

var bounds = new google.maps.LatLngBounds();
// ... (extend bounds with all points you want to fit)

// Ensure the map does not get too zoomed out when fitting the bounds.
gmap.setOptions({minZoom: 6});
// Clear the minZoom only after the map fits the bounds (note that
// fitBounds() is asynchronous). The 'idle' event fires when the map
// becomes idle after panning or zooming.
google.maps.event.addListenerOnce(gmap, 'idle', function() {
  gmap.setOptions({minZoom: null});
});

gmap.fitBounds(bounds);

In addition, if you want to also limit the max zoom, you can apply the same trick with the maxZoomproperty.

此外,如果您还想限制最大缩放,您可以对maxZoom属性应用相同的技巧。

See the MapOptions docs.

请参阅MapOptions 文档

回答by CheapSteaks

I've found a solution that does the check before calling fitBoundsso you don't zoom in and suddenly zoom out

我找到了一个解决方案,可以在调用之前进行检查,fitBounds这样您就不会放大和突然缩小

var bounds = new google.maps.LatLngBounds();

// extend bounds with each point

var minLatSpan = 0.001;
if (bounds.toSpan().lat() > minLatSpan) {
    gmap.fitBounds(bounds); 
} else {
    gmap.setCenter(bounds.getCenter());
    gmap.setZoom(16);
}

You'll have to play around with the minLatSpan variable a bit to get it where you want. It will vary based on both zoom-level and the dimensions of the map canvas.

您必须稍微使用 minLatSpan 变量才能将其置于您想要的位置。它会根据缩放级别和地图画布的尺寸而有所不同。

You could also use longitude instead of latitude

您也可以使用经度而不是纬度

回答by 9monkeys

I had the same issue and I was able to solve it using the following code. This listener (google.maps.addListenerOnce()) event will only get fired once, right after map.fitBounds()is executed. So, there is no need to

我遇到了同样的问题,我能够使用以下代码解决它。此侦听器 ( google.maps.addListenerOnce()) 事件只会在map.fitBounds()执行后立即触发一次。所以,没有必要

  1. Keep track of and manually remove the listener, or
  2. Wait until the map is idle.
  1. 跟踪并手动删除侦听器,或
  2. 等到地图出来了idle

It sets the appropriate zoom level initially and allows the user to zoom in and out past the initial zoom level because the event listener has expired. For example, if only google.maps.addListener()was called, then the user would neverbe able to zoom-in past the stated zoom level (in the case, 4). Since we implemented google.maps.addListenerOnce(), the user will be able to zoom to any level he/she chooses.

它最初设置适当的缩放级别,并允许用户放大和缩小超过初始缩放级别,因为事件侦听器已过期。例如,如果 onlygoogle.maps.addListener()被调用,那么用户将永远无法放大超过规定的缩放级别(在这种情况下为 4)。由于我们实施了google.maps.addListenerOnce(),用户将能够缩放到他/她选择的任何级别。

map.fitBounds(bounds);

var zoom_level_for_one_marker = 4;

google.maps.event.addListenerOnce(map, 'bounds_changed', function(event){
   if (this.getZoom() >= zoom_level_for_one_marker){  
       this.setZoom(zoom_level_for_one_marker) 
   }
});