diff --git a/rendering/cases/zoomify-no-zdirection/main.js b/rendering/cases/zoomify-no-zdirection/main.js index 50f4645a31..c954a64144 100644 --- a/rendering/cases/zoomify-no-zdirection/main.js +++ b/rendering/cases/zoomify-no-zdirection/main.js @@ -16,7 +16,6 @@ new Map({ target: 'map', view: new View({ resolutions: [2, 1], - extent: [0, -200, 200, 0], center: [100, -100], zoom: 0.4 }) diff --git a/rendering/cases/zoomify-zdirection/main.js b/rendering/cases/zoomify-zdirection/main.js index 9a854dae6a..6863e47579 100644 --- a/rendering/cases/zoomify-zdirection/main.js +++ b/rendering/cases/zoomify-zdirection/main.js @@ -17,7 +17,6 @@ new Map({ target: 'map', view: new View({ resolutions: [2, 1], - extent: [0, -200, 200, 0], center: [100, -100], zoom: 0.4 }) diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 7c76e2cdb7..6cf34cbf21 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -964,6 +964,10 @@ class PluggableMap extends BaseObject { * @private */ handleSizeChanged_() { + if (this.getView()) { + this.getView().resolveConstraints(0); + } + this.render(); } @@ -1051,6 +1055,8 @@ class PluggableMap extends BaseObject { this.viewChangeListenerKey_ = listen( view, EventType.CHANGE, this.handleViewPropertyChanged_, this); + + view.resolveConstraints(0); } this.render(); } diff --git a/src/ol/View.js b/src/ol/View.js index 6342888e37..839ca4c881 100644 --- a/src/ol/View.js +++ b/src/ol/View.js @@ -375,17 +375,13 @@ class View extends BaseObject { if (options.resolution !== undefined) { this.setResolution(options.resolution); } else if (options.zoom !== undefined) { - if (this.resolutions_) { // in case map zoom is out of min/max zoom range - const resolution = this.getResolutionForZoom(options.zoom); - this.setResolution(clamp(resolution, - this.minResolution_, this.maxResolution_)); - } else { - this.setZoom(options.zoom); - } + this.setZoom(options.zoom); } + this.resolveConstraints(0); this.setProperties(properties); + /** * @private * @type {ViewOptions} @@ -648,7 +644,7 @@ class View extends BaseObject { } if (!this.getAnimating()) { - setTimeout(this.resolveConstraints_.bind(this), 0); + setTimeout(this.resolveConstraints.bind(this), 0); } } @@ -1283,12 +1279,13 @@ class View extends BaseObject { /** * If any constraints need to be applied, an animation will be triggered. * This is typically done on interaction end. + * Note: calling this with a duration of 0 will apply the constrained values straight away, + * without animation. * @param {number=} opt_duration The animation duration in ms. * @param {number=} opt_resolutionDirection Which direction to zoom. * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation. - * @private */ - resolveConstraints_(opt_duration, opt_resolutionDirection, opt_anchor) { + resolveConstraints(opt_duration, opt_resolutionDirection, opt_anchor) { const duration = opt_duration !== undefined ? opt_duration : 200; const direction = opt_resolutionDirection || 0; @@ -1297,6 +1294,14 @@ class View extends BaseObject { const newResolution = this.constraints_.resolution(this.targetResolution_, direction, size); const newCenter = this.constraints_.center(this.targetCenter_, newResolution, size); + if (duration === 0) { + this.targetResolution_ = newResolution; + this.targetRotation_ = newRotation; + this.targetCenter_ = newCenter; + this.applyTargetState_(); + return; + } + if (this.getResolution() !== newResolution || this.getRotation() !== newRotation || !this.getCenter() || @@ -1336,7 +1341,7 @@ class View extends BaseObject { endInteraction(opt_duration, opt_resolutionDirection, opt_anchor) { this.setHint(ViewHint.INTERACTING, -1); - this.resolveConstraints_(opt_duration, opt_resolutionDirection, opt_anchor); + this.resolveConstraints(opt_duration, opt_resolutionDirection, opt_anchor); } /** diff --git a/test/spec/ol/view.test.js b/test/spec/ol/view.test.js index 3fc8c4e9ce..5f4d3e783a 100644 --- a/test/spec/ol/view.test.js +++ b/test/spec/ol/view.test.js @@ -28,6 +28,71 @@ describe('ol.View', function() { }); + describe('parameter initialization with resolution/zoom constraints', function() { + it('correctly handles max resolution constraint', function() { + const view = new View({ + maxResolution: 1000, + resolution: 1200 + }); + expect(view.getResolution()).to.eql(1000); + expect(view.targetResolution_).to.eql(1000); + }); + + it('correctly handles min resolution constraint', function() { + const view = new View({ + maxResolution: 1024, + minResolution: 128, + resolution: 50 + }); + expect(view.getResolution()).to.eql(128); + expect(view.targetResolution_).to.eql(128); + }); + + it('correctly handles resolutions array constraint', function() { + let view = new View({ + resolutions: [1024, 512, 256, 128, 64, 32], + resolution: 1200 + }); + expect(view.getResolution()).to.eql(1024); + expect(view.targetResolution_).to.eql(1024); + + view = new View({ + resolutions: [1024, 512, 256, 128, 64, 32], + resolution: 10 + }); + expect(view.getResolution()).to.eql(32); + expect(view.targetResolution_).to.eql(32); + }); + + it('correctly handles min zoom constraint', function() { + const view = new View({ + minZoom: 3, + zoom: 2 + }); + expect(view.getZoom()).to.eql(3); + expect(view.targetResolution_).to.eql(view.getMaxResolution()); + }); + + it('correctly handles max zoom constraint', function() { + const view = new View({ + maxZoom: 4, + zoom: 5 + }); + expect(view.getZoom()).to.eql(4); + expect(view.targetResolution_).to.eql(view.getMaxResolution() / Math.pow(2, 4)); + }); + + it('correctly handles extent constraint', function() { + // default viewport size is 100x100 + const view = new View({ + extent: [0, 0, 50, 50], + resolution: 1 + }); + expect(view.getResolution()).to.eql(0.5); + expect(view.targetResolution_).to.eql(0.5); + }); + }); + describe('create constraints', function() { describe('create center constraint', function() { @@ -988,8 +1053,7 @@ describe('ol.View', function() { let view; beforeEach(function() { view = new View({ - resolutions: [1024, 512, 256, 128, 64, 32, 16, 8], - smoothResolutionConstraint: false + resolutions: [1024, 512, 256, 128, 64, 32, 16, 8] }); }); @@ -1021,8 +1085,7 @@ describe('ol.View', function() { it('works for resolution arrays with variable zoom factors', function() { const view = new View({ - resolutions: [10, 5, 2, 1], - smoothResolutionConstraint: false + resolutions: [10, 5, 2, 1] }); view.setZoom(1); @@ -1047,8 +1110,7 @@ describe('ol.View', function() { it('returns correct zoom levels', function() { const view = new View({ minZoom: 10, - maxZoom: 20, - smoothResolutionConstraint: false + maxZoom: 20 }); view.setZoom(5); @@ -1124,9 +1186,7 @@ describe('ol.View', function() { describe('#getResolutionForZoom', function() { it('returns correct zoom resolution', function() { - const view = new View({ - smoothResolutionConstraint: false - }); + const view = new View(); const max = view.getMaxZoom(); const min = view.getMinZoom();