感谢Giles Gardam的回答,但它只解决经度,而不解决纬度。完整的解决方案应计算纬度所需的缩放级别和经度所需的缩放级别,然后取两者中的较小者(更远)。
这是一个同时使用纬度和经度的函数:
function getBoundsZoomLevel(bounds, mapDim) {
var WORLD_DIM = { height: 256, width: 256 };
var ZOOM_MAX = 21;
function latRad(lat) {
var sin = Math.sin(lat * Math.PI / 180);
var radX2 = Math.log((1 + sin) / (1 - sin)) / 2;
return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2;
}
function zoom(mapPx, worldPx, fraction) {
return Math.floor(Math.log(mapPx / worldPx / fraction) / Math.LN2);
}
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
var latFraction = (latRad(ne.lat()) - latRad(sw.lat())) / Math.PI;
var lngDiff = ne.lng() - sw.lng();
var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;
var latZoom = zoom(mapDim.height, WORLD_DIM.height, latFraction);
var lngZoom = zoom(mapDim.width, WORLD_DIM.width, lngFraction);
return Math.min(latZoom, lngZoom, ZOOM_MAX);
}
Demo on jsfiddle
参数:
参数“ bounds”应该是一个google.maps.LatLngBounds
对象。
“ mapDim”参数值应该是具有“ height”和“ width”属性的对象,这些属性表示显示地图的DOM元素的高度和宽度。如果要确保填充,可能需要减小这些值。也就是说,您可能不希望边界内的地图标记离地图边缘太近。
如果使用的是jQuery库,则mapDim
可以按以下方式获取值:
var $mapDiv = $('#mapElementId');
var mapDim = { height: $mapDiv.height(), width: $mapDiv.width() };
如果使用原型库,则可以按以下方式获取mapDim值:
var mapDim = $('mapElementId').getDimensions();
返回值:
返回值是最大缩放级别,仍将显示整个范围。此值介于0
和之间,包括最大缩放级别。
最大缩放级别为21。(我相信Google Maps API v2仅为19。)
说明:
Google Maps使用墨卡托投影。在墨卡托投影中,经度线等距分布,但纬度线不等距。纬度线之间的距离随着从赤道到极点的增加而增加。实际上,距离到达极点时趋向于无穷大。但是,谷歌地图不会显示北纬约85度以上或南纬约-85度以下的纬度。(参考)(我以+/- 85.05112877980658度计算实际截止值。)
这使得纬度边界的分数计算比经度更为复杂。我使用了维基百科的公式来计算纬度分数。我假设这与Google Maps使用的投影相匹配。毕竟,我上面链接到的Google Maps文档页面包含指向同一Wikipedia页面的链接。
其他说明:
- 缩放级别从0到最大缩放级别。缩放级别0是完全缩小的地图。较高的级别将地图进一步放大。(参考)
- 缩放级别为0时,整个世界可以显示在256 x 256像素的区域中。(参考)
- 对于每个较高的缩放级别,显示相同区域所需的像素数在宽度和高度上都会加倍。(参考)
- 地图沿纵向包裹,但不沿纬向包裹。