13

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

我注意到map.fitBounds(map.getBounds())在控制台中调用总是会缩小。我希望它不改变地图。

这是正常行为吗?我该如何强制执行此操作,以便地图从一个步骤到另一个步骤看起来都一样?

谢谢

4

7 回答 7

14

Google Map API 的这个问题被讨论过几次。看:

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

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

于 2011-11-17T21:01:27.463 回答
14

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

为避免缩小,只需fitBounds使用0. 对于这个例子,它将是map.fitBounds(map.getBounds(), 0)

于 2018-03-08T01:54:22.380 回答
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 边界初始化地图。该解决方案对此非常有效。

为什么这行得通?

谷歌地图在fitBounds()被调用时基本上是这样做的:

  1. 将地图居中于给定边界框的中心点。
  2. 放大到视口将包含视口框内给定边界的最高缩放级别。

如果给定的边界与视口完全匹配,则 Google 地图不会将其视为“包含”边界,因此会再缩小一层。

于 2017-01-19T22:42:14.643 回答
4

在初始化名为map.fitBounds(...). 我遇到的行为是,如果在fitBounds地图初始化后几秒钟调用该方法,那么没有问题(缩放是合适的)。所以首先我在地图加载后开始调用该fitBounds方法,这在谷歌地图上转换为地图何时为idle.

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

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

所以我的解决方案是触发fitBounds不同的事件。事件实际上完成了工作(仅调用一次) ,而不是为方法idle调用太早!fitBoundstilesloaded

解决方案:

google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
   var bounds = //define bounds...
   map.fitBounds(bounds);
});
于 2020-05-15T02:09:19.183 回答
2

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 可以在调用之前完成生命周期并渲染地图。

于 2019-06-05T09:18:46.663 回答
0

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

于 2012-11-01T23:19:30.717 回答
0

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

保存以前的缩放和居中。

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

重新设置值。

this.map.setCenter(lastMapCenter);
this.map.setZoom(lastMapZoom);
于 2019-02-04T00:33:48.423 回答