为了快速访问,这里是这个解决方案的 jsfiddle:http: //jsfiddle.net/nYz6k/
假设您对当前检测中心边界的解决方案感到满意,您所要做的就是根据当前地图画布大小限制边界。
您现在得到的结果是,当完全限制时(即纬度和经度都超过边界角),限制边界的每个角落都会出现在地图的中心。
解决方案是实际从边界中删除 x 和 y 偏移,并且仍然能够检查中心(与其他基于边界的检查解决方案相比,这是最有效的解决方案)。
此外,只有在初始化地图和调整窗口大小时,您才必须限制边界,这意味着当您平移时,除了您已经提供的检查方法之外没有额外的处理开销。
不要忘记为地图设置maxZoom属性(根据需要对其进行调整),因为在确定的缩放级别之上,限制边界本身将适合视口,并且没有解决方案。
重要的!使用 'center_changed' 而不是 'drag' 因为 'drag' 具有滑动行为,当您完成拖动并设置中心时,地图仍会沿平移方向滑动。
在您实施该解决方案之前,我建议您查看 Maps API 坐标系和投影的工作原理,因为该解决方案在很大程度上基于它,如果您想对其进行调整,了解这些信息很有用。
https://developers.google.com/maps/documentation/javascript/maptypes并查看自定义地图类型 -> 地图坐标部分。
这是你需要做的。首先,您需要实现 2 个在地理坐标 (LatLng) 和像素坐标之间转换的简短方法。
var fromLatLngToPixel = function (latLng) {
var point = map.getProjection().fromLatLngToPoint(latLng);
var zoom = map.getZoom();
return new google.maps.Point(
Math.floor(point.x * Math.pow(2, zoom)),
Math.floor(point.y * Math.pow(2, zoom))
);
}
var fromPixelToLatLng = function (pixel) {
var zoom = map.getZoom();
var point = new google.maps.Point(
pixel.x / Math.pow(2, zoom),
pixel.y / Math.pow(2, zoom)
);
return map.getProjection().fromPointToLatLng(point);
}
接下来,实现有效限制边界的方法。请注意,您始终必须保留一个存储原始边界的变量,因为每次调整地图画布的大小时,生成的边界都会改变。
为此,假设originalBounds保留您使用 sw_lat、sw_long 等提供的边界,并且此方法修改了shrinkedBounds 。您可以将其重命名为 strictBounds 以仍然在您的方法中工作,但这取决于您。这使用 jQuery 获取画布对象的宽度和高度。
var shrinkBounds = function () {
zoom = map.getZoom();
// The x and y offset will always be half the current map canvas
// width and height respectively
xoffset = $('#map_canvas').width() / 2;
yoffset = $('#map_canvas').height() / 2;
// Convert the bounds extremities to global pixel coordinates
var pixswOriginal = fromLatLngToPixel(originalBounds.getSouthWest());
var pixneOriginal = fromLatLngToPixel(originalBounds.getNorthEast());
// Shrink the original bounds with the x and y offset
var pixswShrinked = new google.maps.Point(pixswOriginal.x + xoffset, pixswOriginal.y - yoffset);
var pixneShrinked = new google.maps.Point(pixneOriginal.x - xoffset, pixneOriginal.y + yoffset);
// Rebuild the shrinkedBounds object with the modified
shrinkedBounds = new google.maps.LatLngBounds(
fromPixelToLatLng(pixswShrinked),
fromPixelToLatLng(pixneShrinked));
}
接下来,您所要做的就是调用此方法:
地图初始化时一次。请注意,根据您调用该方法的时间,您可能会遇到一些奇怪的错误,因为地图可能尚未初始化它的所有属性。最好的方法是使用 projection_changed 事件。
google.maps.event.addListener(map, 'projection_changed', function (e) {
shrinkBounds();
});
每次调整地图画布大小时
google.maps.event.addListener(map, 'resize', function (e) {
shrinkBounds();
});
但其中最重要的部分是“resize”事件永远不会因地图容器的编程调整大小而触发,因此每次以编程方式调整画布大小时都必须手动触发它(如果你这样做,但我怀疑你这样做) .
最常见的方法是在调整窗口大小时触发它:
$(window).resize(function () {
google.maps.event.trigger(map, 'resize');
});
在所有这些之后,您现在可以安全地使用您的方法,但作为 'center_changed' 的处理程序,而不是我之前提到的 'drag' 的处理程序。
我用完整的工作代码设置了一个 jsfiddle。
http://jsfiddle.net/nYz6k/
您可以在左下角看到限制,并显示那个小半标记,它位于边界的 SW 角。西北角也有一个,但自然看不到,因为它显示在位置上方。