我有一个动态磁贴集,我不希望允许在其边界之外进行平移.
下面的代码让我接近,但用户仍然可以在严格边界之外水平滚动,因为它使用地图中心进行比较
var strictBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(sw_lat, sw_lon),
new google.maps.LatLng(ne_lat, ne_lon)
);
google.maps.event.addListener(map, 'drag', function()
{
if (strictBounds.contains(map.getCenter())) return;
// We're out of bounds - Move the map back within the bounds
var c = map.getCenter(),
x = c.lng(),
y = c.lat(),
maxX = strictBounds.getNorthEast().lng(),
maxY = strictBounds.getNorthEast().lat(),
minX = strictBounds.getSouthWest().lng(),
minY = strictBounds.getSouthWest().lat();
if (x < minX) x = minX;
if (x > maxX) x = maxX;
if (y < minY) y = minY;
if (y > maxY) y = maxY;
map.setCenter(new google.maps.LatLng(y, x));
});
Run Code Online (Sandbox Code Playgroud)


为了快速访问,这里是这个解决方案的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);
}
Run Code Online (Sandbox Code Playgroud)
接下来,实现有效限制边界的方法.请注意,您始终必须保留一个存储原始边界的变量,因为每次调整地图画布时,结果边界都会更改.
对于这一点,让我们说originalBounds让你提供sw_lat,sw_long等的界限,shrinkedBounds通过此方法修饰.您可以将其重命名为strictBounds以在您的方法中仍然有效,但这取决于您.这使用jQuery获取canvas对象的宽度和高度.
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));
}
Run Code Online (Sandbox Code Playgroud)
接下来,您所要做的就是调用此方法:
一旦初始化地图.请注意,根据您调用方法的时间,您可能会收到一些奇怪的错误,因为地图可能尚未初始化其所有属性.最好的方法是使用projection_changed事件.
google.maps.event.addListener(map, 'projection_changed', function (e) {
shrinkBounds();
});
Run Code Online (Sandbox Code Playgroud)每次调整地图画布的大小
google.maps.event.addListener(map, 'resize', function (e) {
shrinkBounds();
});
Run Code Online (Sandbox Code Playgroud)但最重要的部分是"调整大小"事件永远不会触发地图容器的程序化大小调整,因此每次以编程方式调整画布大小时都必须手动触发它(如果你这样做,但我怀疑你这样做) .
最常见的方法是在调整窗口大小时触发它:
$(window).resize(function () {
google.maps.event.trigger(map, 'resize');
});
Run Code Online (Sandbox Code Playgroud)
这一切后,你现在可以安全地使用你的方法,但作为一个处理程序"center_changed的"而不是如我前面所提到的"拖拽".
我用完整的工作代码设置了一个jsfiddle.
您可以在左下角看到限制显示的小半标记,它位于边界的SW角落.在NW角落也有一个,但自然你看不到它,因为它显示在位置上方.
不要使用map.getCenter()作为检查,而是使用map.getBounds()
未经测试,但实现此目的的一个简单方法是检查两个边界的并集是否相同(如果不是,则您的地图边界超出了严格边界):
var union = strictBounds.union(map.getBounds());
if (strictBounds.equals(union)) { //new map bounds is within strict bounds
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2326 次 |
| 最近记录: |