谷歌地图API 3缩小了fitBounds

时间:2011-11-17 15:44:51

标签: google-maps-api-3 fitbounds

我遇到了一个调用map.fitBounds似乎缩小的问题。我正在尝试使用backbone.js路由器来保存网址中的地图边界。我希望能够为网址添加书签,然后让地图看起来完全一样。

我注意到在控制台中调用map.fitBounds(map.getBounds())将始终缩小。我想在哪里不改变地图。

这是正常行为吗?我如何强制执行此操作,以使地图从一个步骤到下一个步骤看起来相同?

由于

7 个答案:

答案 0 :(得分:12)

Google Map API的这个问题已经讨论过几次了。参见:

函数map.fitBounds()将视口设置为包含边界。但是map.getBounds()函数返回带有一些额外边距的视口边界(请注意,这是正常行为,没有错误)。放大的边界不再适合上一个视口,因此地图会缩小。

解决问题的一个简单方法是使用地图中心和缩放级别。查看函数map.getCenter()map.setCenter()map.getZoom()map.setZoom()

答案 1 :(得分:4)

2017年修复此问题

在将边界框发送到map.fitBounds()之前稍微收缩它。

这是缩小边界框的功能:

// Values between 0.08 and 0.28 seem to work
// Any lower and the map will zoom out too much
// Any higher and it will zoom in too much
var BOUNDS_SHRINK_PERCENTAGE = 0.08; // 8%

/**
 * @param  {google.maps.LatLngLiteral} southwest
 * @param  {google.maps.LatLngLiteral} northeast
 * @return {Array[google.maps.LatLngLiteral]}
 */
function slightlySmallerBounds(southwest, northeast) {
  function adjustmentAmount(value1, value2) {
    return Math.abs(value1 - value2) * BOUNDS_SHRINK_PERCENTAGE;
  }

  var latAdjustment = adjustmentAmount(northeast.lat, southwest.lat);
  var lngAdjustment = adjustmentAmount(northeast.lng, southwest.lng);

  return [
    {lat: southwest.lat + latAdjustment, lng: southwest.lng + lngAdjustment},
    {lat: northeast.lat - latAdjustment, lng: northeast.lng - lngAdjustment}
  ]
}

像这样使用:

// Ensure `southwest` and `northwest` are objects in google.maps.LatLngLiteral form:
// southwest == {lat: 32.79712, lng: -117.13931}
// northwest == {lat: 32.85020, lng: -117.09356}

var shrunkBounds = slightlySmallerBounds(southwest, northeast);
var newSouthwest = shrunkBounds[0];
var newNortheast = shrunkBounds[1];

// `map` is a `google.maps.Map`
map.fitBounds(
  new google.maps.LatLngBounds(newSouthwest, newNortheast)
);

我有一个应用程序与codr做同样的事情:保存URL中的当前地图边界,并在刷新时从URL边界初始化地图。这个解决方案非常有效。

为什么这样做?

Google地图基本上是在调用fitBounds()时执行此操作:

  1. 将地图置于给定边界框的中心点上。
  2. 放大视口包含视口框内 的最高缩放级别。
  3. 如果给定的界限完全与视口匹配,则Google地图不会将其视为"包含"边界,所以它缩小了一个级别。

答案 2 :(得分:3)

对于在2018年看到此问题的人,Google Maps API v3现在支持第二个padding参数,该参数指定要包含在您指定的边界周围的填充量。

要避免缩小,只需使用fitBounds的填充调用0即可。对于此示例,它将是map.fitBounds(map.getBounds(), 0)

答案 3 :(得分:2)

初始化名为map.fitBounds(...)的地图后,我遇到了同样的问题。我遇到的行为是,如果初始化地图后几秒钟调用了fitBounds方法,那么就没问题了(缩放是适当的)。 因此,我首先在加载地图后开始调用fitBounds方法,在Google地图上,该方法将转换为idle的时间。

google.maps.event.addListener(map, 'idle', function() {
   var bounds = //define bounds...
   map.fitBounds(bounds);
});

这实际上有效,但是idle事件几乎总是被触发。如果此更改停止后地图发生任何变化(拖动,缩放等),则地图将再次适合边界... 问题在于,仅一次调用该方法就不会起作用(使用布尔值来检查是否已被调用,或者使用google.maps.event.addListenerOnce,因为映射第一次空闲时,它仍然“不是“还没准备好”以适应边界。(根据经验)。

所以我的解决方案是要在其他事件上触发fitBounds。事件idle实际上可以完成工作(仅被调用一次),而不是为fitBounds方法调用得太早的tilesloaded

解决方案:

google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
   var bounds = //define bounds...
   map.fitBounds(bounds);
});

答案 4 :(得分:0)

我也注意到了这个问题。我的解决方案是将map.getBounds()与我设置界限进行比较;如果它们是相同的,我正在跳过map.fitBounds()电话。

答案 5 :(得分:0)

我遇到了同样的问题,@ Tomik的回答帮助我解决了这个问题。这是我使用的代码片段。

保存上一个缩放和居中。

const lastMapZoom = this.map.getZoom();
const lastMapCenter = this.map.getCenter();

要重新设置值。

this.map.setCenter(lastMapZoom);
this.map.setZoom(lastMapCenter);

答案 6 :(得分:0)

当我在隐藏的地图视图上使用fitBounds()时(使用诸如Angular之类的前端渲染框架)时,我注意到了这种行为。由于这是一个移动视图,因此我首先显示了位置列表,并在加载列表(并发加载)时在隐藏地图上填充标记。因此,当用户想要查看地图时,他们切换了细分视图/标签/其他选项时,地图将显示已加载的标记并显示在视图中。但是,这个错误被放大并放大以在地图上显示整个世界。

<div [hidden]="view !== 'map'>
    <google-map></google-map>
</div>

fitBounds()需要在视图中加载地图,因为它使用地图尺寸来调整地图的大小。如果地图是隐藏的,它将缩放地图,直到显示完整的地图。

解决方案很简单:切换视图时,再次调用fitBounds()

<button (click)="showMap()">Show Map</button>

public showMap() {
    this.view = 'map';
    setTimeout(() => {
        if (typeof this.map !== 'undefined') this.map.fitBounds(this.bounds);
    });
}

注意:我在setTimeout调用周围包裹了fitBounds(),以便Angular可以完成生命周期并在调用地图之前对其进行渲染。