diff --git a/lib/OpenLayers/Control/NavigationHistory.js b/lib/OpenLayers/Control/NavigationHistory.js index a33c308183..4322a4a1d2 100644 --- a/lib/OpenLayers/Control/NavigationHistory.js +++ b/lib/OpenLayers/Control/NavigationHistory.js @@ -294,7 +294,10 @@ OpenLayers.Control.NavigationHistory = OpenLayers.Class(OpenLayers.Control, { getState: function() { return { center: this.map.getCenter(), - resolution: this.map.getResolution() + resolution: this.map.getResolution(), + projection: this.map.getProjectionObject(), + units: this.map.getProjectionObject().getUnits() || + this.map.units || this.map.baseLayer.units }; }, @@ -306,8 +309,21 @@ OpenLayers.Control.NavigationHistory = OpenLayers.Class(OpenLayers.Control, { * state - {Object} An object representing the state to restore. */ restore: function(state) { - var zoom = this.map.getZoomForResolution(state.resolution); - this.map.setCenter(state.center, zoom); + var center, zoom; + if (this.map.getProjectionObject() == state.projection) { + zoom = this.map.getZoomForResolution(state.resolution); + center = state.center; + } else { + center = state.center.clone(); + center.transform(state.projection, this.map.getProjectionObject()); + var sourceUnits = state.units; + var targetUnits = this.map.getProjectionObject().getUnits() || + this.map.units || this.map.baseLayer.units; + var resolutionFactor = sourceUnits && targetUnits ? + OpenLayers.INCHES_PER_UNIT[sourceUnits] / OpenLayers.INCHES_PER_UNIT[targetUnits] : 1; + zoom = this.map.getZoomForResolution(resolutionFactor*state.resolution); + } + this.map.setCenter(center, zoom); }, /** diff --git a/tests/Control/NavigationHistory.html b/tests/Control/NavigationHistory.html index 29ed3d1d62..cccf4b8d9e 100644 --- a/tests/Control/NavigationHistory.html +++ b/tests/Control/NavigationHistory.html @@ -195,6 +195,48 @@ control.destroy(); } + function test_reprojection(t) { + t.plan(2); + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer( + "test", {isBaseLayer: true} + ); + map.addLayer(layer); + map.zoomToMaxExtent(); + + var control = new OpenLayers.Control.NavigationHistory(); + map.addControl(control); + + map.zoomTo(4); + var bounds = map.getExtent().clone(); + var expected = bounds.transform(new OpenLayers.Projection('EPSG:4326'), + new OpenLayers.Projection('EPSG:900913')); + // change the projection to EPSG:900913 + var projSettings = { + units: "m", + maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508), + maxResolution: 156543.0339 + }; + map.setOptions(projSettings); + map.projection = 'EPSG:900913'; + delete projSettings.maxResolution; + projSettings.projection = new OpenLayers.Projection('EPSG:900913'); + layer.addOptions(projSettings); + layer.initResolutions(); + + map.zoomTo(7); + + // go back one in the history + control.previous.trigger(); + + t.eq(map.getExtent().left.toFixed(3), expected.left.toFixed(3), "The extent [left] is reprojected correctly"); + t.eq(map.getExtent().right.toFixed(3), expected.right.toFixed(3), "The extent [right] is reprojected correctly"); + // top and bottom cannot be checked here since in EPSG:900913 the extent is not a rectangle so they are adjusted. + + control.destroy(); + + } +