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

Posted

技术标签:

【中文标题】如何在使用 map.fitBounds 之前确定 LatLngBounds 的缩放级别?【英文标题】:How do I determine the zoom level of a LatLngBounds before using map.fitBounds? 【发布时间】:2012-05-24 03:10:34 【问题描述】:

在调用 map.fitBounds() 之前,我试图找出确定地图缩放级别的方法,但我似乎找不到方法。

在 API v2 中有一个方法 GMap.getBoundsZoomLevel(bounds:GLatLngBounds),但我在 API v3 文档中找不到等效方法。

是否有非 Google 算法可以预先确定缩放级别?

【问题讨论】:

标准库中没有等价物。你想达到什么目的?您不再需要将缩放级别传递给setCenter。 v3 版本的setCenter 只需要一个参数,一个google.maps.LatLng ***.com/questions/6048975/… 【参考方案1】:

尼克是对的,这个讨论概述了一个可行的方法: Google Maps V3 - How to calculate the zoom level for a given bounds

但是,它是用 javascript 编写的。对于那些需要使用 android GMaps v3 执行此操作的人,以下是翻译:

private static final double LN2 = 0.6931471805599453;
private static final int WORLD_PX_HEIGHT = 256;
private static final int WORLD_PX_WIDTH = 256;
private static final int ZOOM_MAX = 21;

public int getBoundsZoomLevel(LatLngBounds bounds, int mapWidthPx, int mapHeightPx)

    LatLng ne = bounds.northeast;
    LatLng sw = bounds.southwest;

    double latFraction = (latRad(ne.latitude) - latRad(sw.latitude)) / Math.PI;

    double lngDiff = ne.longitude - sw.longitude;
    double lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;

    double latZoom = zoom(mapHeightPx, WORLD_PX_HEIGHT, latFraction);
    double lngZoom = zoom(mapWidthPx, WORLD_PX_WIDTH, lngFraction);

    int result = Math.min((int)latZoom, (int)lngZoom);
    return Math.min(result, ZOOM_MAX);


private double latRad(double lat) 
    double sin = Math.sin(lat * Math.PI / 180);
    double radX2 = Math.log((1 + sin) / (1 - sin)) / 2;
    return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2;

private double zoom(int mapPx, int worldPx, double fraction) 
    return Math.floor(Math.log(mapPx / worldPx / fraction) / LN2);

【讨论】:

Google API 文档 (developers.google.com/android/reference/com/google/android/gms/…) 说“整个世界大约是 256dp 宽” - 注意:“dp”,而不是“px”。因此,上述出色的计算应转换为“dp”(例如,通过显示指标,“缩放密度”)。我使用:双 latZoom = zoom(mapHeightPx, WORLD_DP_HEIGHT * mDisplayMetrics.scaledDensity, latFraction);双 lngZoom = zoom(mapWidthPx, WORLD_DP_WIDTH * mDisplayMetrics.scaledDensity, lngFraction); 除了WORLD_PX_HEIGHT * density这个东西,我还需要删除zoom函数上的Math.floor,让它返回float并将int result设置为float result,否则我有更大的填充然后在直接使用增量边界时。当然,所有受影响的调用都必须改变,不要忘记getBoundsZoomLevel 也必须返回float

以上是关于如何在使用 map.fitBounds 之前确定 LatLngBounds 的缩放级别?的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

谷歌地图 API 3 缩小 fitBounds

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

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