diff --git a/src/ol/view2d.js b/src/ol/view2d.js index fa8d0eb8eb..6fe6b0c949 100644 --- a/src/ol/view2d.js +++ b/src/ol/view2d.js @@ -12,6 +12,7 @@ goog.require('ol.IView3D'); goog.require('ol.Projection'); goog.require('ol.ResolutionConstraint'); goog.require('ol.RotationConstraint'); +goog.require('ol.RotationConstraintType'); goog.require('ol.Size'); goog.require('ol.View'); goog.require('ol.animation'); @@ -64,11 +65,29 @@ ol.View2D = function(opt_options) { values[ol.View2DProperty.ROTATION] = options.rotation; this.setValues(values); + var parts = ol.View2D.createResolutionConstraint_(options); + + /** + * @private + * @type {number} + */ + this.maxResolution_ = parts[1]; + + /** + * @private + * @type {number} + */ + this.minResolution_ = parts[2]; + + var resolutionConstraint = parts[0]; + var rotationConstraint = ol.View2D.createRotationConstraint_(options); + /** * @private * @type {ol.Constraints} */ - this.constraints_ = ol.View2D.createConstraints_(options); + this.constraints_ = new ol.Constraints(resolutionConstraint, + rotationConstraint); }; goog.inherits(ol.View2D, ol.View); @@ -141,6 +160,26 @@ ol.View2D.prototype.getResolutionForExtent = function(extent, size) { }; +/** + * Return a function that returns a value between 0 and 1 for a + * resolution. Exponential scaling is assumed. + * @param {number=} opt_power Power. + * @return {function(number): number} Resolution for value function. + */ +ol.View2D.prototype.getResolutionForValueFunction = function(opt_power) { + var power = opt_power || 2; + var maxResolution = this.maxResolution_; + var minResolution = this.minResolution_; + var max = Math.log(maxResolution / minResolution) / Math.log(power); + return function(value) { + var resolution = maxResolution / Math.pow(power, value * max); + goog.asserts.assert(resolution >= minResolution && + resolution <= maxResolution); + return resolution; + }; +}; + + /** * @return {number} Map rotation. */ @@ -154,6 +193,25 @@ goog.exportProperty( ol.View2D.prototype.getRotation); +/** + * Return a function that returns a resolution for a value between + * 0 and 1. Exponential scaling is assumed. + * @param {number=} opt_power Power. + * @return {function(number): number} Value for resolution function. + */ +ol.View2D.prototype.getValueForResolutionFunction = function(opt_power) { + var power = opt_power || 2; + var maxResolution = this.maxResolution_; + var minResolution = this.minResolution_; + var max = Math.log(maxResolution / minResolution) / Math.log(power); + return function(resolution) { + var value = (Math.log(maxResolution / resolution) / Math.log(power)) / max; + goog.asserts.assert(value >= 0 && value <= 1); + return value; + }; +}; + + /** * @inheritDoc */ @@ -420,15 +478,21 @@ ol.View2D.prototype.zoomWithoutConstraints = /** * @private * @param {ol.View2DOptions} options View2D options. - * @return {ol.Constraints} Constraints. + * @return {Array} Array of three elements: the resolution constraint, + * maxResolution, and minResolution. */ -ol.View2D.createConstraints_ = function(options) { +ol.View2D.createResolutionConstraint_ = function(options) { var resolutionConstraint; + var maxResolution; + var minResolution; if (goog.isDef(options.resolutions)) { + var resolutions = options.resolutions; + maxResolution = resolutions[0]; + minResolution = resolutions[resolutions.length - 1]; resolutionConstraint = ol.ResolutionConstraint.createSnapToResolutions( - options.resolutions); + resolutions); } else { - var maxResolution, numZoomLevels, zoomFactor; + var numZoomLevels, zoomFactor; if (goog.isDef(options.maxResolution) && goog.isDef(options.numZoomLevels) && goog.isDef(options.zoomFactor)) { @@ -444,10 +508,20 @@ ol.View2D.createConstraints_ = function(options) { numZoomLevels = 29; zoomFactor = 2; } + minResolution = maxResolution / Math.pow(zoomFactor, numZoomLevels - 1); resolutionConstraint = ol.ResolutionConstraint.createSnapToPower( zoomFactor, maxResolution, numZoomLevels - 1); } - // FIXME rotation constraint is not configurable at the moment - var rotationConstraint = ol.RotationConstraint.createSnapToZero(); - return new ol.Constraints(resolutionConstraint, rotationConstraint); + return [resolutionConstraint, maxResolution, minResolution]; +}; + + +/** + * @private + * @param {ol.View2DOptions} options View2D options. + * @return {ol.RotationConstraintType} Rotation constraint. + */ +ol.View2D.createRotationConstraint_ = function(options) { + // FIXME rotation constraint is not configurable at the moment + return ol.RotationConstraint.createSnapToZero(); }; diff --git a/test/spec/ol/view2d.test.js b/test/spec/ol/view2d.test.js index f95e90fb72..95dfab872f 100644 --- a/test/spec/ol/view2d.test.js +++ b/test/spec/ol/view2d.test.js @@ -8,7 +8,7 @@ describe('ol.View2D', function() { describe('with no options', function() { it('gives a correct resolution constraint function', function() { var options = {}; - var fn = ol.View2D.createConstraints_(options).resolution; + var fn = ol.View2D.createResolutionConstraint_(options)[0]; expect(fn(156543.03392804097, 0, 0)) .to.roughlyEqual(156543.03392804097, 1e-9); expect(fn(78271.51696402048, 0, 0)) @@ -24,7 +24,12 @@ describe('ol.View2D', function() { numZoomLevels: 4, zoomFactor: 3 }; - var fn = ol.View2D.createConstraints_(options).resolution; + var parts = ol.View2D.createResolutionConstraint_(options); + var maxResolution = parts[1]; + expect(maxResolution).to.eql(81); + var minResolution = parts[2]; + expect(minResolution).to.eql(3); + var fn = parts[0]; expect(fn(82, 0, 0)).to.eql(81); expect(fn(81, 0, 0)).to.eql(81); expect(fn(27, 0, 0)).to.eql(27); @@ -39,7 +44,12 @@ describe('ol.View2D', function() { var options = { resolutions: [97, 76, 65, 54, 0.45] }; - var fn = ol.View2D.createConstraints_(options).resolution; + var parts = ol.View2D.createResolutionConstraint_(options); + var maxResolution = parts[1]; + expect(maxResolution).to.eql(97); + var minResolution = parts[2]; + expect(minResolution).to.eql(0.45); + var fn = parts[0]; expect(fn(97, 0, 0)).to.eql(97); expect(fn(76, 0, 0)).to.eql(76); expect(fn(65, 0, 0)).to.eql(65); @@ -53,7 +63,7 @@ describe('ol.View2D', function() { describe('create rotation constraint', function() { it('gives a correct rotation constraint function', function() { var options = {}; - var fn = ol.View2D.createConstraints_(options).rotation; + var fn = ol.View2D.createRotationConstraint_(options); expect(fn(0.01, 0)).to.eql(0); expect(fn(0.15, 0)).to.eql(0.15); });