From 7ab3b3dd825ce74c31450354bbdaf50c94002048 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sat, 4 Aug 2012 15:50:06 +0200 Subject: [PATCH] Add rotation constraints --- src/ol/base/createmap.js | 4 ++- src/ol/control/constraints.js | 13 ++++++-- src/ol/control/control.js | 17 ++++++----- src/ol/control/rotationconstraint.js | 39 ++++++++++++++++++++++++ src/ol/control/shiftdragrotate.js | 2 +- src/ol/control/shiftdragrotateandzoom.js | 2 +- 6 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 src/ol/control/rotationconstraint.js diff --git a/src/ol/base/createmap.js b/src/ol/base/createmap.js index d1e1cdddcd..9638897381 100644 --- a/src/ol/base/createmap.js +++ b/src/ol/base/createmap.js @@ -14,6 +14,7 @@ goog.require('ol.control.KeyboardPan'); goog.require('ol.control.KeyboardZoom'); goog.require('ol.control.MouseWheelZoom'); goog.require('ol.control.ResolutionConstraint'); +goog.require('ol.control.RotationConstraint'); goog.require('ol.control.ShiftDragRotateAndZoom'); goog.require('ol.control.ShiftDragZoom'); goog.require('ol.dom'); @@ -82,8 +83,9 @@ ol.createMap = function(target, opt_values, opt_rendererHints) { var centerConstraint = ol.control.CenterConstraint.snapToPixel; var resolutionConstraint = ol.control.ResolutionConstraint.createSnapToPower( 2, ol.Projection.EPSG_3857_HALF_SIZE / 128); + var rotationConstraint = ol.control.RotationConstraint.none; var constraints = new ol.control.Constraints( - centerConstraint, resolutionConstraint); + centerConstraint, resolutionConstraint, rotationConstraint); if (!goog.object.containsKey(values, ol.MapProperty.CONTROLS)) { var controls = new ol.Collection(); diff --git a/src/ol/control/constraints.js b/src/ol/control/constraints.js index df47aca5fe..b9f0acc99d 100644 --- a/src/ol/control/constraints.js +++ b/src/ol/control/constraints.js @@ -1,9 +1,8 @@ -// FIXME add rotation constraint - goog.provide('ol.control.Constraints'); goog.require('ol.control.CenterConstraintType'); goog.require('ol.control.ResolutionConstraintType'); +goog.require('ol.control.RotationConstraintType'); @@ -12,8 +11,11 @@ goog.require('ol.control.ResolutionConstraintType'); * @param {ol.control.CenterConstraintType} centerConstraint Center constraint. * @param {ol.control.ResolutionConstraintType} resolutionConstraint * Resolution constraint. + * @param {ol.control.RotationConstraintType} rotationConstraint + * Rotation constraint. */ -ol.control.Constraints = function(centerConstraint, resolutionConstraint) { +ol.control.Constraints = + function(centerConstraint, resolutionConstraint, rotationConstraint) { /** * @type {ol.control.CenterConstraintType} @@ -25,4 +27,9 @@ ol.control.Constraints = function(centerConstraint, resolutionConstraint) { */ this.resolution = resolutionConstraint; + /** + * @type {ol.control.RotationConstraintType} + */ + this.rotation = rotationConstraint; + }; diff --git a/src/ol/control/control.js b/src/ol/control/control.js index 3488557d84..b8eefd1b31 100644 --- a/src/ol/control/control.js +++ b/src/ol/control/control.js @@ -59,21 +59,22 @@ ol.Control.prototype.pan = function(map, delta, opt_anchor) { /** * @param {ol.Map} map Map. - * @param {number|undefined} resolution Resolution. + * @param {number|undefined} rotation Rotation. + * @param {number} delta Delta. */ -ol.Control.prototype.setResolution = function(map, resolution) { - resolution = this.constraints.resolution(resolution, 0); - map.setResolution(resolution); +ol.Control.prototype.rotate = function(map, rotation, delta) { + rotation = this.constraints.rotation(rotation, delta); + map.setRotation(rotation); }; /** * @param {ol.Map} map Map. - * @param {number} rotation Rotation. + * @param {number|undefined} resolution Resolution. */ -ol.Control.prototype.setRotation = function(map, rotation) { - // FIXME use a constraint - map.setRotation(rotation); +ol.Control.prototype.setResolution = function(map, resolution) { + resolution = this.constraints.resolution(resolution, 0); + map.setResolution(resolution); }; diff --git a/src/ol/control/rotationconstraint.js b/src/ol/control/rotationconstraint.js new file mode 100644 index 0000000000..dde5403272 --- /dev/null +++ b/src/ol/control/rotationconstraint.js @@ -0,0 +1,39 @@ +goog.provide('ol.control.RotationConstraint'); +goog.provide('ol.control.RotationConstraintType'); + + +/** + * @typedef {function((number|undefined), number): (number|undefined)} + */ +ol.control.RotationConstraintType; + + +/** + * @param {number|undefined} rotation Rotation. + * @param {number} delta Delta. + * @return {number|undefined} Rotation. + */ +ol.control.RotationConstraint.none = function(rotation, delta) { + if (goog.isDef(rotation)) { + return rotation + delta; + } else { + return undefined; + } +}; + + +/** + * @param {number} n N. + * @return {ol.control.RotationConstraintType} Rotation constraint. + */ +ol.control.RotationConstraint.createSnapToN = function(n) { + var theta = 2 * Math.PI / n; + return function(rotation, delta) { + if (goog.isDef(rotation)) { + rotation = Math.floor((rotation + delta) / theta + 0.5) * theta; + return rotation; + } else { + return undefined; + } + }; +}; diff --git a/src/ol/control/shiftdragrotate.js b/src/ol/control/shiftdragrotate.js index 2faa029c84..1d5e8d2b8a 100644 --- a/src/ol/control/shiftdragrotate.js +++ b/src/ol/control/shiftdragrotate.js @@ -33,7 +33,7 @@ ol.control.ShiftDragRotate.prototype.handleDrag = function(mapBrowserEvent) { var theta = Math.atan2( size.height / 2 - browserEvent.offsetY, browserEvent.offsetX - size.width / 2); - map.setRotation(this.startRotation_ - theta); + this.rotate(map, this.startRotation_, -theta); }; diff --git a/src/ol/control/shiftdragrotateandzoom.js b/src/ol/control/shiftdragrotateandzoom.js index 5f3ebcc9b0..3a1f276c20 100644 --- a/src/ol/control/shiftdragrotateandzoom.js +++ b/src/ol/control/shiftdragrotateandzoom.js @@ -45,7 +45,7 @@ ol.control.ShiftDragRotateAndZoom.prototype.handleDrag = size.height / 2 - browserEvent.offsetY); var theta = Math.atan2(delta.y, delta.x); // FIXME this should use map.withFrozenRendering but an assertion fails :-( - this.setRotation(map, this.startRotation_ - theta); + this.rotate(map, this.startRotation_, -theta); var resolution = this.startRatio_ * delta.magnitude(); this.setResolution(map, resolution); };