如何影响 map.fitBounds() 的“宽限”

Posted

技术标签:

【中文标题】如何影响 map.fitBounds() 的“宽限”【英文标题】:How to affect the "grace margin" of map.fitBounds() 【发布时间】:2012-04-08 06:44:01 【问题描述】:

在 Google maps API v2 中,我们国家的地图很好地适应了 700x400px 的地图,如下所示:

map.getBoundsZoomLevel(<bounds of our country>)

但在 API v3 中,map.fitBounds() 方法不适用于 700x400 的缩放级别 - 它缩小了一级。

这意味着map.fitBounds() 具有一些“宽限”或其他内容。

如何影响此边距的大小?

【问题讨论】:

“宽限”可以是您想要的范围的百分比吗?如果这个边距是固定的,你可以输入一个更小的、测量的边界到 fitBounds(),这样宽限距的末端就匹配你最初想要的边界。希望这是有道理的。 @HeitorChang,这将是一个非常老套和笨拙的解决方案,但无论如何,如果不知道 fitBounds() 是如何精确计算“宽限”的,你就不能这样做。 经过一番折腾,我得出结论,只有在长维度上至少有 45 像素的填充(到边界定义的矩形的两侧)时,v3 fitBounds() 才会放大,那时缩放级别。假设这是一个接近的电话,地图将保持缩小,留下很大的余量。我希望这对你有用。 读完后:***.com/questions/6048975/… 恐怕除了写我自己的fitBounds 之外没有其他解决方案。糟糕的 api v3,又一个缺陷! 在许多情况下,您可以将地图边界替换为对地图中心坐标和缩放级别的引用。 【参考方案1】:

这里有一个解决方案,可以在没有自定义边距的情况下尽可能放大地图。如果您愿意,您应该能够对其进行调整以占一定的利润。

我的解决方案基于this comment in a Google Groups thread。不幸的是,对helper.getProjection() 的调用总是返回未定义,所以我稍微修改了上面的答案并想出了这个工作代码。

只需将您对map.fitBounds(bounds) 的现有调用替换为myFitBounds(map, bounds)

function myFitBounds(myMap, bounds) 
    myMap.fitBounds(bounds);

    var overlayHelper = new google.maps.OverlayView();
    overlayHelper.draw = function () 
        if (!this.ready) 
            var projection = this.getProjection(),
                zoom = getExtraZoom(projection, bounds, myMap.getBounds());
            if (zoom > 0) 
                myMap.setZoom(myMap.getZoom() + zoom);
            
            this.ready = true;
            google.maps.event.trigger(this, 'ready');
        
    ;
    overlayHelper.setMap(myMap);


// LatLngBounds b1, b2 -> zoom increment
function getExtraZoom(projection, expectedBounds, actualBounds) 
    var expectedSize = getSizeInPixels(projection, expectedBounds),
        actualSize = getSizeInPixels(projection, actualBounds);

    if (Math.floor(expectedSize.x) == 0 || Math.floor(expectedSize.y) == 0) 
        return 0;
    

    var qx = actualSize.x / expectedSize.x;
    var qy = actualSize.y / expectedSize.y;
    var min = Math.min(qx, qy);

    if (min < 1) 
        return 0;
    

    return Math.floor(Math.log(min) / Math.log(2) /* = log2(min) */);


// LatLngBounds bnds -> height and width as a Point
function getSizeInPixels(projection, bounds) 
    var sw = projection.fromLatLngToContainerPixel(bounds.getSouthWest());
    var ne = projection.fromLatLngToContainerPixel(bounds.getNorthEast());
    return new google.maps.Point(Math.abs(sw.y - ne.y), Math.abs(sw.x - ne.x));

【讨论】:

这对我来说效果很好,但是当expectedSize 正好是actualSize 的两倍时,我不得不修改一行来处理浮点舍入错误。将getSizeInPixels的return语句改为:return new google.maps.Point( Math.round(10000 * Math.abs(sw.y - ne.y)) / 10000, Math.round(10000 * Math.abs(sw.x - ne.x)) / 10000 );【参考方案2】:

现在,fitBounds 方法有第二个参数,表示填充的大小。想要去掉的,只需要传0即可。

Map.map.fitBounds(bounds, 0);


New method signature: fitBounds(bounds:LatLngBounds|LatLngBoundsLiteral, padding?:number)

【讨论】:

以上是关于如何影响 map.fitBounds() 的“宽限”的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 map.fitBounds 之前确定 LatLngBounds 的缩放级别?

调用 map.fitBounds 后立即谷歌地图 map.getBounds()

在 Google Maps API v3.0 中多次调用 map.fitBounds()

谷歌地图 API 3 缩小 fitBounds

map.fitbounds google maps api v3 不适用于从 jQM 面板选择的位置

Google Maps API 3 fitBounds 填充 - 确保标记不会被覆盖控件遮挡