Refactoring to set the constraints to the map

This commit is contained in:
Éric Lemoine
2012-09-26 23:28:01 +02:00
parent 2991fa1178
commit b6bb05bf76
15 changed files with 164 additions and 178 deletions

View File

@@ -8,11 +8,10 @@ goog.require('ol.interaction.Drag');
/**
* @constructor
* @extends {ol.interaction.Drag}
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.AltDragRotate = function(constraints) {
ol.interaction.AltDragRotate = function() {
goog.base(this, constraints);
goog.base(this);
/**
* @private
@@ -34,7 +33,7 @@ ol.interaction.AltDragRotate.prototype.handleDrag = function(mapBrowserEvent) {
var theta = Math.atan2(
size.height / 2 - browserEvent.offsetY,
browserEvent.offsetX - size.width / 2);
this.rotate(map, this.startRotation_, -theta);
map.rotate(this.startRotation_, -theta);
};

View File

@@ -8,20 +8,13 @@ goog.require('ol.interaction.RotationConstraintType');
/**
* @constructor
* @param {ol.interaction.CenterConstraintType} centerConstraint
* Center constraint.
* @param {ol.interaction.ResolutionConstraintType} resolutionConstraint
* Resolution constraint.
* @param {ol.interaction.RotationConstraintType} rotationConstraint
* Rotation constraint.
*/
ol.interaction.Constraints =
function(centerConstraint, resolutionConstraint, rotationConstraint) {
/**
* @type {ol.interaction.CenterConstraintType}
*/
this.center = centerConstraint;
function(resolutionConstraint, rotationConstraint) {
/**
* @type {ol.interaction.ResolutionConstraintType}

View File

@@ -2,7 +2,6 @@ goog.provide('ol.interaction.DblClickZoom');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.Interaction');
@@ -10,10 +9,9 @@ goog.require('ol.interaction.Interaction');
/**
* @constructor
* @extends {ol.interaction.Interaction}
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.DblClickZoom = function(constraints) {
goog.base(this, constraints);
ol.interaction.DblClickZoom = function() {
goog.base(this);
};
goog.inherits(ol.interaction.DblClickZoom, ol.interaction.Interaction);
@@ -27,10 +25,12 @@ ol.interaction.DblClickZoom.prototype.handleMapBrowserEvent =
if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DBLCLICK &&
mapBrowserEvent.isMouseActionButton()) {
var map = mapBrowserEvent.map;
var resolution = map.getResolution();
var delta = mapBrowserEvent.browserEvent.shiftKey ? -1 : 1;
var anchor = mapBrowserEvent.getCoordinate();
this.zoom(map, resolution, delta, anchor);
if (mapBrowserEvent.browserEvent.shiftKey) {
map.zoomOut(anchor);
} else {
map.zoomIn(anchor);
}
mapBrowserEvent.preventDefault();
}
};

View File

@@ -6,7 +6,6 @@ goog.require('goog.events.EventType');
goog.require('goog.functions');
goog.require('ol.Coordinate');
goog.require('ol.MapBrowserEvent');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.Interaction');
@@ -14,11 +13,10 @@ goog.require('ol.interaction.Interaction');
/**
* @constructor
* @extends {ol.interaction.Interaction}
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.Drag = function(constraints) {
ol.interaction.Drag = function() {
goog.base(this, constraints);
goog.base(this);
/**
* @private

View File

@@ -2,7 +2,6 @@ goog.provide('ol.interaction.DragPan');
goog.require('ol.Coordinate');
goog.require('ol.MapBrowserEvent');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.Drag');
@@ -10,10 +9,9 @@ goog.require('ol.interaction.Drag');
/**
* @constructor
* @extends {ol.interaction.Drag}
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.DragPan = function(constraints) {
goog.base(this, constraints);
ol.interaction.DragPan = function() {
goog.base(this);
};
goog.inherits(ol.interaction.DragPan, ol.interaction.Drag);
@@ -30,7 +28,9 @@ ol.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) {
if (map.canRotate() && goog.isDef(rotation)) {
delta.rotate(rotation);
}
this.pan(map, delta, this.startCenter);
var newCenter = new ol.Coordinate(
this.startCenter.x + delta.x, this.startCenter.y + delta.y);
map.setCenter(newCenter);
};

View File

@@ -3,38 +3,13 @@
goog.provide('ol.interaction.Interaction');
goog.require('ol.MapBrowserEvent');
goog.require('ol.interaction.Constraints');
/**
* @constructor
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.Interaction = function(constraints) {
/**
* @protected
* @type {ol.interaction.Constraints}
*/
this.constraints = constraints;
};
/**
* @param {ol.Map} map Map.
* @param {ol.Extent} extent Extent.
*/
ol.interaction.Interaction.prototype.fitExtent = function(map, extent) {
var resolution = map.getResolutionForExtent(extent);
resolution = this.constraints.resolution(resolution, 0);
var center = extent.getCenter();
center = this.constraints.center(center, resolution, ol.Coordinate.ZERO);
map.withFrozenRendering(function() {
map.setCenter(center);
map.setResolution(resolution);
});
ol.interaction.Interaction = function() {
};
@@ -43,69 +18,3 @@ ol.interaction.Interaction.prototype.fitExtent = function(map, extent) {
*/
ol.interaction.Interaction.prototype.handleMapBrowserEvent =
goog.abstractMethod;
/**
* @param {ol.Map} map Map.
* @param {ol.Coordinate} delta Delta.
* @param {ol.Coordinate=} opt_anchor Anchor.
*/
ol.interaction.Interaction.prototype.pan = function(map, delta, opt_anchor) {
var center = opt_anchor ? opt_anchor : map.getCenter();
var resolution = map.getResolution();
center = this.constraints.center(center, resolution, delta);
map.setCenter(center);
};
/**
* @param {ol.Map} map Map.
* @param {number|undefined} rotation Rotation.
* @param {number} delta Delta.
* @param {ol.Coordinate=} opt_anchor Anchor.
*/
ol.interaction.Interaction.prototype.rotate = function(
map, rotation, delta, opt_anchor) {
// FIXME handle rotation about anchor
rotation = this.constraints.rotation(rotation, delta);
map.setRotation(rotation);
};
/**
* @param {ol.Map} map Map.
* @param {number|undefined} resolution Resolution.
*/
ol.interaction.Interaction.prototype.setResolution = function(map, resolution) {
resolution = this.constraints.resolution(resolution, 0);
map.setResolution(resolution);
};
/**
* @param {ol.Map} map Map.
* @param {number|undefined} resolution Resolution.
* @param {number} delta Delta.
* @param {ol.Coordinate=} opt_anchor Anchor.
*/
ol.interaction.Interaction.prototype.zoom = function(
map, resolution, delta, opt_anchor) {
if (goog.isDefAndNotNull(opt_anchor)) {
var anchor = opt_anchor;
var mapCenter = /** @type {!ol.Coordinate} */ map.getCenter();
var mapResolution = map.getResolution();
resolution = this.constraints.resolution(resolution, delta);
var x = anchor.x - resolution * (anchor.x - mapCenter.x) / mapResolution;
var y = anchor.y - resolution * (anchor.y - mapCenter.y) / mapResolution;
var center = new ol.Coordinate(x, y);
center = this.constraints.center(center, resolution, ol.Coordinate.ZERO);
map.withFrozenRendering(function() {
map.setCenter(center);
map.setResolution(resolution);
});
} else {
resolution = this.constraints.resolution(resolution, delta);
map.setResolution(resolution);
}
};

View File

@@ -12,7 +12,7 @@ goog.require('ol.interaction.Interaction');
*/
ol.interaction.Keyboard = function() {
goog.base(this, null);
goog.base(this);
/**
* @private

View File

@@ -2,7 +2,6 @@ goog.provide('ol.interaction.KeyboardPan');
goog.require('goog.events.KeyCodes');
goog.require('goog.events.KeyHandler.EventType');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.Interaction');
@@ -10,12 +9,11 @@ goog.require('ol.interaction.Interaction');
/**
* @constructor
* @extends {ol.interaction.Interaction}
* @param {ol.interaction.Constraints} constraints Constraints.
* @param {number} pixelDelta Pixel delta.
*/
ol.interaction.KeyboardPan = function(constraints, pixelDelta) {
ol.interaction.KeyboardPan = function(pixelDelta) {
goog.base(this, constraints);
goog.base(this);
/**
* @private
@@ -54,7 +52,10 @@ ol.interaction.KeyboardPan.prototype.handleMapBrowserEvent =
goog.asserts.assert(keyCode == goog.events.KeyCodes.UP);
delta = new ol.Coordinate(0, mapUnitsDelta);
}
this.pan(map, delta);
var oldCenter = map.getCenter();
var newCenter = new ol.Coordinate(
oldCenter.x + delta.x, oldCenter.y + delta.y);
map.setCenter(newCenter);
keyEvent.preventDefault();
mapBrowserEvent.preventDefault();
}

View File

@@ -3,17 +3,15 @@ goog.provide('ol.interaction.KeyboardZoom');
goog.require('goog.events.KeyCodes');
goog.require('goog.events.KeyHandler.EventType');
goog.require('ol.interaction.Interaction');
goog.require('ol.interaction.ResolutionConstraintType');
/**
* @constructor
* @extends {ol.interaction.Interaction}
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.KeyboardZoom = function(constraints) {
goog.base(this, constraints);
ol.interaction.KeyboardZoom = function() {
goog.base(this);
};
goog.inherits(ol.interaction.KeyboardZoom, ol.interaction.Interaction);
@@ -29,9 +27,11 @@ ol.interaction.KeyboardZoom.prototype.handleMapBrowserEvent =
var charCode = keyEvent.charCode;
if (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0)) {
var map = mapBrowserEvent.map;
var resolution = map.getResolution();
var delta = charCode == '+'.charCodeAt(0) ? 1 : -1;
this.zoom(map, resolution, delta);
if (charCode == '+'.charCodeAt(0)) {
map.zoomIn();
} else {
map.zoomOut();
}
keyEvent.preventDefault();
mapBrowserEvent.preventDefault();
}

View File

@@ -3,17 +3,15 @@ goog.provide('ol.interaction.MouseWheelZoom');
goog.require('goog.events.MouseWheelEvent');
goog.require('goog.events.MouseWheelHandler.EventType');
goog.require('ol.MapBrowserEvent');
goog.require('ol.interaction.Constraints');
/**
* @constructor
* @extends {ol.interaction.Interaction}
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.MouseWheelZoom = function(constraints) {
goog.base(this, constraints);
ol.interaction.MouseWheelZoom = function() {
goog.base(this);
};
goog.inherits(ol.interaction.MouseWheelZoom, ol.interaction.Interaction);
@@ -29,13 +27,14 @@ ol.interaction.MouseWheelZoom.prototype.handleMapBrowserEvent =
var mouseWheelEvent = /** @type {goog.events.MouseWheelEvent} */
mapBrowserEvent.browserEvent;
goog.asserts.assert(mouseWheelEvent instanceof goog.events.MouseWheelEvent);
if (mouseWheelEvent.deltaY !== 0) {
var delta = mouseWheelEvent.deltaY < 0 ? 1 : -1;
var resolution = map.getResolution();
var anchor = mapBrowserEvent.getCoordinate();
this.zoom(map, resolution, delta, anchor);
var oldResolution = map.getResolution();
var factor = Math.exp(Math.log(2) / 4);
if (mouseWheelEvent.deltaY < 0) {
factor = 1 / factor;
}
map.zoomToResolution(oldResolution * factor, anchor);
mapBrowserEvent.preventDefault();
mouseWheelEvent.preventDefault();
}
}
};

View File

@@ -2,7 +2,6 @@ goog.provide('ol.interaction.ShiftDragRotateAndZoom');
goog.require('goog.math.Vec2');
goog.require('ol.MapBrowserEvent');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.Drag');
@@ -10,11 +9,10 @@ goog.require('ol.interaction.Drag');
/**
* @constructor
* @extends {ol.interaction.Drag}
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.ShiftDragRotateAndZoom = function(constraints) {
ol.interaction.ShiftDragRotateAndZoom = function() {
goog.base(this, constraints);
goog.base(this);
/**
* @private
@@ -45,9 +43,9 @@ ol.interaction.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.rotate(map, this.startRotation_, -theta);
map.rotate(this.startRotation_, -theta);
var resolution = this.startRatio_ * delta.magnitude();
this.setResolution(map, resolution);
map.zoomToResolution(resolution);
};

View File

@@ -5,7 +5,6 @@ goog.provide('ol.interaction.ShiftDragZoom');
goog.require('ol.Extent');
goog.require('ol.MapBrowserEvent');
goog.require('ol.control.DragBox');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.Drag');
@@ -27,10 +26,9 @@ ol.SHIFT_DRAG_ZOOM_HYSTERESIS_PIXELS_SQUARED =
/**
* @constructor
* @extends {ol.interaction.Drag}
* @param {ol.interaction.Constraints} constraints Constraints.
*/
ol.interaction.ShiftDragZoom = function(constraints) {
goog.base(this, constraints);
ol.interaction.ShiftDragZoom = function() {
goog.base(this);
/**
* @type {ol.control.DragBox}
@@ -54,7 +52,7 @@ ol.interaction.ShiftDragZoom.prototype.handleDragEnd =
var extent = ol.Extent.boundingExtent(
this.startCoordinate,
mapBrowserEvent.getCoordinate());
this.fitExtent(map, extent);
map.fitExtent(extent);
}
};

View File

@@ -34,6 +34,7 @@ goog.require('ol.Pixel');
goog.require('ol.Projection');
goog.require('ol.Size');
goog.require('ol.TransformFunction');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.Interaction');
goog.require('ol.renderer.Layer');
@@ -136,6 +137,13 @@ ol.Map = function(container, mapOptionsLiteral, opt_viewportSizeMonitor) {
*/
this.container_ = container;
/**
* @private
* FIXME change ol.interaction.Constraints -> ol.Constraints
* @type {ol.interaction.Constraints}
*/
this.constraints_ = mapOptions.constraints;
/**
* @private
* @type {Element}
@@ -218,7 +226,9 @@ ol.Map.prototype.canRotate = function() {
ol.Map.prototype.fitExtent = function(extent) {
this.withFrozenRendering(function() {
this.setCenter(extent.getCenter());
this.setResolution(this.getResolutionForExtent(extent));
var resolution = this.getResolutionForExtent(extent);
resolution = this.constraints_.resolution(resolution, 0);
this.setResolution(resolution);
if (this.canRotate()) {
this.setRotation(0);
}
@@ -614,6 +624,16 @@ ol.Map.prototype.renderFrame_ = function() {
};
/**
* @param {number|undefined} rotation Rotation.
* @param {number} delta Delta.
*/
ol.Map.prototype.rotate = function(rotation, delta) {
rotation = this.constraints_.rotation(rotation, delta);
this.setRotation(rotation);
};
/**
* @param {ol.Color} backgroundColor Background color.
*/
@@ -790,3 +810,62 @@ ol.Map.prototype.withFrozenRendering = function(f, opt_obj) {
this.unfreezeRendering();
}
};
/**
* @private
* @param {number|undefined} resolution Resolution to go to.
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
*/
ol.Map.prototype.zoom_ = function(resolution, opt_anchor) {
if (goog.isDefAndNotNull(resolution) && goog.isDefAndNotNull(opt_anchor)) {
var anchor = opt_anchor;
var oldCenter = /** @type {!ol.Coordinate} */ this.getCenter();
var oldResolution = this.getResolution();
var x = anchor.x - resolution * (anchor.x - oldCenter.x) / oldResolution;
var y = anchor.y - resolution * (anchor.y - oldCenter.y) / oldResolution;
var center = new ol.Coordinate(x, y);
this.withFrozenRendering(function() {
this.setCenter(center);
this.setResolution(resolution);
}, this);
} else {
this.setResolution(resolution);
}
};
/**
* @param {number} delta Delta from previous zoom level.
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
*/
ol.Map.prototype.zoomByDelta = function(delta, opt_anchor) {
var resolution = this.constraints_.resolution(this.getResolution(), delta);
this.zoom_(resolution, opt_anchor);
};
/**
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
*/
ol.Map.prototype.zoomIn = function(opt_anchor) {
this.zoomByDelta(4, opt_anchor);
};
/**
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
*/
ol.Map.prototype.zoomOut = function(opt_anchor) {
this.zoomByDelta(-4, opt_anchor);
};
/**
* @param {number|undefined} resolution Resolution to go to.
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
*/
ol.Map.prototype.zoomToResolution = function(resolution, opt_anchor) {
resolution = this.constraints_.resolution(resolution, 0);
this.zoom_(resolution, opt_anchor);
};

View File

@@ -151,14 +151,36 @@ ol.MapOptions.create = function(mapOptionsLiteral) {
}
}
/**
* @type {ol.interaction.Constraints}
*/
var constraints = ol.MapOptions.createConstraints_(mapOptionsLiteral);
return {
rendererConstructor: rendererConstructor,
constraints: constraints,
values: values
};
};
/**
* @private
* @param {ol.MapOptionsLiteral} mapOptionsLiteral Map options literal.
* @return {ol.interaction.Constraints} Map constraints.
*/
ol.MapOptions.createConstraints_ = function(mapOptionsLiteral) {
// FIXME this should be configurable
var resolutionConstraint =
ol.interaction.ResolutionConstraint.createSnapToPower(
Math.exp(Math.log(2) / 4), ol.Projection.EPSG_3857_HALF_SIZE / 128);
var rotationConstraint = ol.interaction.RotationConstraint.none;
return new ol.interaction.Constraints(
resolutionConstraint, rotationConstraint);
};
/**
* @private
* @param {ol.MapOptionsLiteral} mapOptionsLiteral Map options literal.
@@ -166,33 +188,24 @@ ol.MapOptions.create = function(mapOptionsLiteral) {
*/
ol.MapOptions.createInteractions_ = function(mapOptionsLiteral) {
// FIXME this should be a configuration option
var centerConstraint = ol.interaction.CenterConstraint.snapToPixel;
var resolutionConstraint =
ol.interaction.ResolutionConstraint.createSnapToPower(
Math.exp(Math.log(2) / 8), ol.Projection.EPSG_3857_HALF_SIZE / 128);
var rotationConstraint = ol.interaction.RotationConstraint.none;
var constraints = new ol.interaction.Constraints(
centerConstraint, resolutionConstraint, rotationConstraint);
var interactions = new ol.Collection();
var rotate = goog.isDef(mapOptionsLiteral.rotate) ?
mapOptionsLiteral.rotate : true;
if (rotate) {
interactions.push(new ol.interaction.AltDragRotate(constraints));
interactions.push(new ol.interaction.AltDragRotate());
}
var doubleClickZoom = goog.isDef(mapOptionsLiteral.doubleClickZoom) ?
mapOptionsLiteral.doubleClickZoom : true;
if (doubleClickZoom) {
interactions.push(new ol.interaction.DblClickZoom(constraints));
interactions.push(new ol.interaction.DblClickZoom());
}
var dragPan = goog.isDef(mapOptionsLiteral.dragPan) ?
mapOptionsLiteral.dragPan : true;
if (dragPan) {
interactions.push(new ol.interaction.DragPan(constraints));
interactions.push(new ol.interaction.DragPan());
}
var keyboard = goog.isDef(mapOptionsLiteral.keyboard) ?
@@ -200,21 +213,20 @@ ol.MapOptions.createInteractions_ = function(mapOptionsLiteral) {
var keyboardPanOffset = goog.isDef(mapOptionsLiteral.keyboardPanOffset) ?
mapOptionsLiteral.keyboardPanOffset : 80;
if (keyboard) {
interactions.push(
new ol.interaction.KeyboardPan(constraints, keyboardPanOffset));
interactions.push(new ol.interaction.KeyboardZoom(constraints));
interactions.push(new ol.interaction.KeyboardPan(keyboardPanOffset));
interactions.push(new ol.interaction.KeyboardZoom());
}
var mouseWheelZoom = goog.isDef(mapOptionsLiteral.mouseWheelZoom) ?
mapOptionsLiteral.mouseWheelZoom : true;
if (mouseWheelZoom) {
interactions.push(new ol.interaction.MouseWheelZoom(constraints));
interactions.push(new ol.interaction.MouseWheelZoom());
}
var shiftDragZoom = goog.isDef(mapOptionsLiteral.shiftDragZoom) ?
mapOptionsLiteral.shiftDragZoom : true;
if (shiftDragZoom) {
interactions.push(new ol.interaction.ShiftDragZoom(constraints));
interactions.push(new ol.interaction.ShiftDragZoom());
}
return interactions;

View File

@@ -155,12 +155,12 @@ ol.renderer.dom.Map.prototype.resetLayersPane_ = function() {
ol.renderer.dom.Map.prototype.setOrigin_ = function() {
var center = this.map.getCenter();
var resolution = this.map.getResolution();
var targetSize = this.map.getSize();
var targetWidth = targetSize.width;
var targetHeight = targetSize.height;
var mapSize = this.map.getSize();
var mapWidth = mapSize.width;
var mapHeight = mapSize.height;
var origin = new ol.Coordinate(
center.x - resolution * targetWidth / 2,
center.y + resolution * targetHeight / 2);
center.x - resolution * mapWidth / 2,
center.y + resolution * mapHeight / 2);
goog.object.forEach(this.layerRenderers, function(layerRenderer) {
layerRenderer.setOrigin(origin);
});