Merge pull request #524 from ahocevar/panzoombar

Zoom level restriction improvements. r=@bartvde
This commit is contained in:
ahocevar
2012-06-22 16:59:13 -07:00
4 changed files with 77 additions and 19 deletions

View File

@@ -99,6 +99,7 @@ OpenLayers.Control.PanZoomBar = OpenLayers.Class(OpenLayers.Control.PanZoom, {
this.map.events.un({ this.map.events.un({
"changebaselayer": this.redraw, "changebaselayer": this.redraw,
"updatesize": this.redraw,
scope: this scope: this
}); });
@@ -116,7 +117,11 @@ OpenLayers.Control.PanZoomBar = OpenLayers.Class(OpenLayers.Control.PanZoom, {
*/ */
setMap: function(map) { setMap: function(map) {
OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments); OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments);
this.map.events.register("changebaselayer", this, this.redraw); this.map.events.on({
"changebaselayer": this.redraw,
"updatesize": this.redraw,
scope: this
});
}, },
/** /**
@@ -189,6 +194,7 @@ OpenLayers.Control.PanZoomBar = OpenLayers.Class(OpenLayers.Control.PanZoom, {
_addZoomBar:function(centered) { _addZoomBar:function(centered) {
var imgLocation = OpenLayers.Util.getImageLocation("slider.png"); var imgLocation = OpenLayers.Util.getImageLocation("slider.png");
var id = this.id + "_" + this.map.id; var id = this.id + "_" + this.map.id;
var minZoom = this.map.getMinZoom();
var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom(); var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom();
var slider = OpenLayers.Util.createAlphaImageDiv(id, var slider = OpenLayers.Util.createAlphaImageDiv(id,
centered.add(-1, zoomsToEnd * this.zoomStopHeight), centered.add(-1, zoomsToEnd * this.zoomStopHeight),
@@ -211,7 +217,7 @@ OpenLayers.Control.PanZoomBar = OpenLayers.Class(OpenLayers.Control.PanZoom, {
var sz = { var sz = {
w: this.zoomStopWidth, w: this.zoomStopWidth,
h: this.zoomStopHeight * this.map.getNumZoomLevels() h: this.zoomStopHeight * (this.map.getNumZoomLevels() - minZoom)
}; };
var imgLocation = OpenLayers.Util.getImageLocation("zoombar.png"); var imgLocation = OpenLayers.Util.getImageLocation("zoombar.png");
var div = null; var div = null;
@@ -242,7 +248,7 @@ OpenLayers.Control.PanZoomBar = OpenLayers.Class(OpenLayers.Control.PanZoom, {
this.map.events.register("zoomend", this, this.moveZoomBar); this.map.events.register("zoomend", this, this.moveZoomBar);
centered = centered.add(0, centered = centered.add(0,
this.zoomStopHeight * this.map.getNumZoomLevels()); this.zoomStopHeight * (this.map.getNumZoomLevels() - minZoom));
return centered; return centered;
}, },

View File

@@ -83,6 +83,7 @@ OpenLayers.Map = OpenLayers.Class({
* mouseout - triggered after mouseout the map * mouseout - triggered after mouseout the map
* mousemove - triggered after mousemove the map * mousemove - triggered after mousemove the map
* changebaselayer - triggered after the base layer changes * changebaselayer - triggered after the base layer changes
* updatesize - triggered after the <updateSize> method was executed
*/ */
/** /**
@@ -1490,6 +1491,7 @@ OpenLayers.Map = OpenLayers.Class({
} }
} }
this.events.triggerEvent("updatesize");
}, },
/** /**
@@ -1784,9 +1786,13 @@ OpenLayers.Map = OpenLayers.Class({
* <baseLayer>'s maxExtent. * <baseLayer>'s maxExtent.
*/ */
adjustZoom: function(zoom) { adjustZoom: function(zoom) {
if (this.baseLayer && this.baseLayer.wrapDateLine) {
var resolution, resolutions = this.baseLayer.resolutions, var resolution, resolutions = this.baseLayer.resolutions,
maxResolution = this.getMaxExtent().getWidth() / this.size.w; maxResolution = this.getMaxExtent().getWidth() / this.size.w;
if (this.getResolutionForZoom(zoom) > maxResolution) { if (this.getResolutionForZoom(zoom) > maxResolution) {
if (this.fractionalZoom) {
zoom = this.getZoomForResolution(maxResolution);
} else {
for (var i=zoom|0, ii=resolutions.length; i<ii; ++i) { for (var i=zoom|0, ii=resolutions.length; i<ii; ++i) {
if (resolutions[i] <= maxResolution) { if (resolutions[i] <= maxResolution) {
zoom = i; zoom = i;
@@ -1794,9 +1800,29 @@ OpenLayers.Map = OpenLayers.Class({
} }
} }
} }
}
}
return zoom; return zoom;
}, },
/**
* APIMethod: getMinZoom
* Returns the minimum zoom level for the current map view. If the base
* layer is configured with <wrapDateLine> set to true, this will be the
* first zoom level that shows no more than one world width in the current
* map viewport. Components that rely on this value (e.g. zoom sliders)
* should also listen to the map's "updatesize" event and call this method
* in the "updatesize" listener.
*
* Returns:
* {Number} Minimum zoom level that shows a map not wider than its
* <baseLayer>'s maxExtent. This is an Integer value, unless the map is
* configured with <fractionalZoom> set to true.
*/
getMinZoom: function() {
return this.adjustZoom(0);
},
/** /**
* Method: moveTo * Method: moveTo
* *
@@ -1818,14 +1844,12 @@ OpenLayers.Map = OpenLayers.Class({
zoom = Math.round(zoom); zoom = Math.round(zoom);
} }
} }
if (this.baseLayer.wrapDateLine) {
var requestedZoom = zoom; var requestedZoom = zoom;
zoom = this.adjustZoom(zoom); zoom = this.adjustZoom(zoom);
if (zoom !== requestedZoom) { if (zoom !== requestedZoom) {
// zoom was adjusted, so keep old lonlat to avoid panning // zoom was adjusted, so keep old lonlat to avoid panning
lonlat = this.getCenter(); lonlat = this.getCenter();
} }
}
// dragging is false by default // dragging is false by default
var dragging = options.dragging || this.dragging; var dragging = options.dragging || this.dragging;
// forceZoomChange is false by default // forceZoomChange is false by default

View File

@@ -34,6 +34,31 @@
t.eq( control2.div.style.top, "100px", "2nd control div is located correctly"); t.eq( control2.div.style.top, "100px", "2nd control div is located correctly");
} }
function test_draw(t) {
t.plan(3);
map = new OpenLayers.Map('map', {controls:[]});
var layer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
map.addLayer(layer);
map.zoomToMaxExtent();
control = new OpenLayers.Control.PanZoomBar();
map.addControl(control);
t.eq(control.zoombarDiv.style.height, '176px', "Bar's height is correct.");
map.baseLayer.wrapDateLine = true;
control.redraw();
t.eq(control.zoombarDiv.style.height, '154px', "Bar's height is correct after minZoom restriction.");
map.div.style.width = "512px";
map.updateSize();
t.eq(control.zoombarDiv.style.height, '165px', "Bar's height is correct after resize and minZoom restriction.");
map.div.style.width = "1024px";
map.destroy();
}
function test_Control_PanZoomBar_clearDiv(t) { function test_Control_PanZoomBar_clearDiv(t) {
t.plan(2); t.plan(2);
map = new OpenLayers.Map('map', {controls:[]}); map = new OpenLayers.Map('map', {controls:[]});

View File

@@ -2047,7 +2047,7 @@
} }
function test_adjustZoom(t) { function test_adjustZoom(t) {
t.plan(4); t.plan(5);
var map = new OpenLayers.Map({ var map = new OpenLayers.Map({
div: 'map', div: 'map',
layers: [ layers: [
@@ -2063,6 +2063,9 @@
t.eq(map.adjustZoom(9), 9, "valid zoom maintained"); t.eq(map.adjustZoom(9), 9, "valid zoom maintained");
t.eq(map.adjustZoom(1), 2, "zoom adjusted to not exceed world width"); t.eq(map.adjustZoom(1), 2, "zoom adjusted to not exceed world width");
map.fractionalZoom = true;
t.eq(map.adjustZoom(1).toPrecision(3), "1.29", "zoom adjusted to match world width");
map.moveTo([16, 48], 0); map.moveTo([16, 48], 0);
t.eq(map.getCenter().toShortString(), "0, 0", "no panning when moveTo is called with invalid zoom"); t.eq(map.getCenter().toShortString(), "0, 0", "no panning when moveTo is called with invalid zoom");
} }