Answers:
您可以听dragend
事件,如果将地图拖到允许的范围之外,请将其移回内部。您可以在LatLngBounds
对象中定义允许的范围,然后使用该contains()
方法检查新的经纬度中心是否在范围内。
您还可以非常轻松地限制缩放级别。
考虑以下示例: Fiddle Demo
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Limit Panning and Zoom</title>
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false"></script>
</head>
<body>
<div id="map" style="width: 400px; height: 300px;"></div>
<script type="text/javascript">
// This is the minimum zoom level that we'll allow
var minZoomLevel = 5;
var map = new google.maps.Map(document.getElementById('map'), {
zoom: minZoomLevel,
center: new google.maps.LatLng(38.50, -90.50),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Bounds for North America
var strictBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(28.70, -127.50),
new google.maps.LatLng(48.85, -55.90)
);
// Listen for the dragend event
google.maps.event.addListener(map, 'dragend', 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));
});
// Limit the zoom level
google.maps.event.addListener(map, 'zoom_changed', function() {
if (map.getZoom() < minZoomLevel) map.setZoom(minZoomLevel);
});
</script>
</body>
</html>
上面示例的屏幕截图。在这种情况下,用户将无法向南或向东拖动:
center_changed
活动而不是,这对我来说效果很好dragend
。
限制缩放级别的更好方法可能是使用minZoom
/ maxZoom
选项,而不是对事件做出反应?
var opt = { minZoom: 6, maxZoom: 9 };
map.setOptions(opt);
或者可以在地图初始化期间指定选项,例如:
var map = new google.maps.Map(document.getElementById('map-canvas'), opt);
好消息。从2019年2月14日启动的Maps JavaScript API版本3.35开始,您可以使用新restriction
选项来限制地图的视口。
根据文档
MapRestriction接口
可以应用于地图的限制。地图的视口不会超出这些限制。
来源:https://developers.google.com/maps/documentation/javascript/reference/map#MapRestriction
因此,现在您只需在地图初始化期间添加限制选项即可。看下面的示例,将视口限制为瑞士
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 46.818188, lng: 8.227512},
minZoom: 7,
maxZoom: 14,
zoom: 7,
restriction: {
latLngBounds: {
east: 10.49234,
north: 47.808455,
south: 45.81792,
west: 5.95608
},
strictBounds: true
},
});
}
#map {
height: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&callback=initMap" async defer></script>
我希望这有帮助!
更好的限制范围的方法...使用了上面海报中的包含逻辑。
var dragStartCenter;
google.maps.event.addListener(map, 'dragstart', function(){
dragStartCenter = map.getCenter();
});
google.maps.event.addListener(this.googleMap, 'dragend', function(){
if (mapBounds.contains(map.getCenter())) return;
map.setCenter(this.dragStart);
});
this.googleMap
而不是map
第二个侦听器?还不dragStart
应该dragStartCenter
吗?最后是什么mapBounds
?
这可用于将地图重新居中到特定位置。这就是我所需要的。
var MapBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(35.676263, 13.949096),
new google.maps.LatLng(36.204391, 14.89038));
google.maps.event.addListener(GoogleMap, 'dragend', function ()
{
if (MapBounds.contains(GoogleMap.getCenter()))
{
return;
}
else
{
GoogleMap.setCenter(new google.maps.LatLng(35.920242, 14.428825));
}
});
这是我的变体,用于解决可见区域限制的问题。
google.maps.event.addListener(this.map, 'idle', function() {
var minLat = strictBounds.getSouthWest().lat();
var minLon = strictBounds.getSouthWest().lng();
var maxLat = strictBounds.getNorthEast().lat();
var maxLon = strictBounds.getNorthEast().lng();
var cBounds = self.map.getBounds();
var cMinLat = cBounds.getSouthWest().lat();
var cMinLon = cBounds.getSouthWest().lng();
var cMaxLat = cBounds.getNorthEast().lat();
var cMaxLon = cBounds.getNorthEast().lng();
var centerLat = self.map.getCenter().lat();
var centerLon = self.map.getCenter().lng();
if((cMaxLat - cMinLat > maxLat - minLat) || (cMaxLon - cMinLon > maxLon - minLon))
{ //We can't position the canvas to strict borders with a current zoom level
self.map.setZoomLevel(self.map.getZoomLevel()+1);
return;
}
if(cMinLat < minLat)
var newCenterLat = minLat + ((cMaxLat-cMinLat) / 2);
else if(cMaxLat > maxLat)
var newCenterLat = maxLat - ((cMaxLat-cMinLat) / 2);
else
var newCenterLat = centerLat;
if(cMinLon < minLon)
var newCenterLon = minLon + ((cMaxLon-cMinLon) / 2);
else if(cMaxLon > maxLon)
var newCenterLon = maxLon - ((cMaxLon-cMinLon) / 2);
else
var newCenterLon = centerLon;
if(newCenterLat != centerLat || newCenterLon != centerLon)
self.map.setCenter(new google.maps.LatLng(newCenterLat, newCenterLon));
});
strictBounds
是new google.maps.LatLngBounds()
类型的对象。self.gmap
存储一个Google Map对象(new google.maps.Map()
)。
它确实有效,但如果边界覆盖了第0个子午线和平行线,则别忘了考虑痔疮与第0个经线和平行线的交叉。
因为某些原因
if (strictBounds.contains(map.getCenter())) return;
没有为我工作(也许是南半球问题)。我不得不将其更改为:
function checkBounds() {
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 > maxX || y < minY || y > maxY) {
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));
}
}
希望它会帮助某人。
一种解决方案是,如果您知道特定的经度/纬度。
google.maps.event.addListener(map, 'idle', function() {
map.setCenter(new google.maps.LatLng(latitude, longitude));
map.setZoom(8);
});
如果没有特定的经纬度
google.maps.event.addListener(map, 'idle', function() {
map.setCenter(map.getCenter());
map.setZoom(8);
});
要么
google.maps.event.addListener(map, 'idle', function() {
var bounds = new google.maps.LatLngBounds();
map.setCenter(bounds.getCenter());
map.setZoom(8);
});
截至2016年中,尚无官方限制可见区域的方法。但是,大多数限制边界的临时解决方案都有缺陷,因为它们没有严格限制边界以适合地图视图,而是仅在地图中心超出指定边界时才对其进行限制。如果您想像我一样将边界限制为叠加图像,则可能会导致如下所示的行为,其中在我们的图像叠加层下可以看到底层地图:
为了解决此问题,我创建了一个库,该库成功限制了边界,因此您无法平移叠加层。
但是,作为其他现有解决方案,它具有“振动”问题。当用户足够积极地平移地图时,松开鼠标左键后,地图仍会继续自行平移,并逐渐变慢。我总是将地图返回边界,但这会导致振动。目前无法通过Js API提供的任何手段来停止这种平移效果。在Google添加对诸如map.stopPanningAnimation()之类的支持之前,我们似乎无法创造出流畅的体验。
使用提到的库的示例,我能够获得最流畅的严格边界体验:
function initialise(){
var myOptions = {
zoom: 5,
center: new google.maps.LatLng(0,0),
mapTypeId: google.maps.MapTypeId.ROADMAP,
};
var map = new google.maps.Map(document.getElementById('map'), myOptions);
addStrictBoundsImage(map);
}
function addStrictBoundsImage(map){
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(62.281819, -150.287132),
new google.maps.LatLng(62.400471, -150.005608));
var image_src = 'https://developers.google.com/maps/documentation/' +
'javascript/examples/full/images/talkeetna.png';
var strict_bounds_image = new StrictBoundsImage(bounds, image_src, map);
}
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("maps", "3",{other_params:"sensor=false"});
</script>
<body style="margin:0px; padding:0px;" onload="initialise()">
<div id="map" style="height:400px; width:500px;"></div>
<script type="text/javascript"src="https://raw.githubusercontent.com/matej-pavla/StrictBoundsImage/master/StrictBoundsImage.js"></script>
</body>
该库还能够自动计算最小缩放限制。然后使用minZoom
地图的属性限制缩放级别。
希望这可以帮助想要解决方案的人完全尊重给定的边界,而又不想让他们陷入困境。
这可能会有所帮助。
var myOptions = {
center: new google.maps.LatLng($lat,$lang),
zoom: 7,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
缩放级别可以根据要求进行定制。
e.g. only between levels 6 and 9
,而是设置了默认缩放级别并删除了默认UI(即+
/ -
),这有点过头了。
if (x < minX) x = minX;
并且if (x > maxX) x = maxX;
不互相排斥?为什么将画布居中在minX / maxX和maxX / maxY坐标上,尽管它们不是中心坐标?