I\'m working on a site that makes use of v7 of the Bing Maps AJAX Control. One of the things I need to do is restrict the zoom level so as to prevent users from zoom in past
I was dealing with a similar issue and I ended up doing something very similar to what MrJamin describes in his answer, with one (subtle, but major) difference: I added a handler for targetviewchanged
. According to the official docs on MSDN, 'targetviewchanged' occurs when the view towards which the map is navigating changes
. Also, instead of calling Map#getZoom
, I used Map#getTargetZoom
which returns the zoom level of the view to which the map is navigating
. Note, this approach prevents jitter.
Here's the shortened version of my code:
function restrictZoom(map,min,max) {
Microsoft.Maps.Events.addHandler(map,'targetviewchanged',function(){
var targetZoom = map.getTargetZoom();
var adjZoom = targetZoom;
if(targetZoom > max) {
adjZoom = max;
} else if(targetZoom < min) {
adjZoom = min;
}
if(targetZoom != adjZoom) {
map.setView({zoom:adjZoom});
}
});
}
According to Bing Maps support, the only way to do this (which isn't particularly elegant, and results in some unwelcome jitter on the map) is as follows:
// "map" is our Bing Maps object, overload the built-in getZoomRange function
// to set our own min/max zoom
map.getZoomRange = function ()
{
return {
max: 14,
min: 5
};
};
// Attach a handler to the event that gets fired whenever the map's view is about to change
Microsoft.Maps.Events.addHandler(map,'viewchangestart',restrictZoom);
// Forcibly set the zoom to our min/max whenever the view starts to change beyond them
var restrictZoom = function ()
{
if (map.getZoom() <= map.getZoomRange().min)
{
map.setView({
'zoom': map.getZoomRange().min,
'animate': false
});
}
else if (map.getZoom() >= map.getZoomRange().max)
{
map.setView({
'zoom': map.getZoomRange().max,
'animate': false
});
}
};
Another way to achieve this is to handle the event thrown when the mouse wheel is moved. http://msdn.microsoft.com/en-us/library/gg427609.aspx
When you handle the mousewheel
event, you can check whether the mouse wheel is being scrolled forwards or backwards, and then check the map.targetZoom()
in order to compare with a min or max zoom value. If the min or max are exceeded, then set event.handled = true
. This prevents the event from being handled by any other handlers which prevents default behaviour. From the documentation:
A boolean indicating whether the event is handled. If this property is set to true, the default map control behavior for the event is cancelled.
See below:
var Zoom = {
MAX: 10,
MIN: 2
}
var mouseWheelHandler = function(event) {
// If wheelDelta is greater than 0, then the wheel is being scrolled forward which zooms in
if(event.wheelDelta > 0) {
if(map.getTargetZoom() >= Zoom.MAX) {
event.handled = true;
}
}
else {
if(map.getTargetZoom() <= Zoom.MIN) {
event.handled = true;
}
}
}
Microsoft.Maps.Events.addHandler(map, 'mousewheel', mouseWheelHandler);