diff --git a/examples/wms-custom-proj.js b/examples/wms-custom-proj.js index 8ea4cc8d87..87c7d6d7d1 100644 --- a/examples/wms-custom-proj.js +++ b/examples/wms-custom-proj.js @@ -62,6 +62,7 @@ var map = new ol.Map({ view: new ol.View2D({ projection: projection, center: [660000, 190000], + extent: extent, zoom: 2 }) }); diff --git a/examples/wms-image-custom-proj.js b/examples/wms-image-custom-proj.js index 460fd588fb..80262a7c03 100644 --- a/examples/wms-image-custom-proj.js +++ b/examples/wms-image-custom-proj.js @@ -54,6 +54,7 @@ var map = new ol.Map({ view: new ol.View2D({ projection: projection, center: [660000, 190000], + extent: extent, zoom: 2 }) }); diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 332699752c..b058b7ad1a 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -101,6 +101,7 @@ * @property {ol.Coordinate|undefined} center The initial center for the view. * The coordinate system for the center is specified with the `projection` * option. + * @property {ol.Extent|undefined} extent The extent to constraint the center to. * @property {number|undefined} maxResolution The maximum resolution used to * determine the resolution constraint. It is used together with `maxZoom` * and `zoomFactor`. If unspecified it is calculated in such a way that the diff --git a/src/ol/centerconstraint.js b/src/ol/centerconstraint.js new file mode 100644 index 0000000000..2cc4db9592 --- /dev/null +++ b/src/ol/centerconstraint.js @@ -0,0 +1,42 @@ +goog.provide('ol.CenterConstraint'); +goog.provide('ol.CenterConstraintType'); + +goog.require('goog.math'); + + +/** + * @typedef {function((ol.Coordinate|undefined)): (ol.Coordinate|undefined)} + */ +ol.CenterConstraintType; + + +/** + * @param {ol.Extent} extent Extent. + * @return {ol.CenterConstraintType} + */ +ol.CenterConstraint.createExtent = function(extent) { + return ( + /** + * @param {ol.Coordinate|undefined} center Center. + * @return {ol.Coordinate|undefined} Center. + */ + function(center) { + if (goog.isDef(center)) { + return [ + goog.math.clamp(center[0], extent[0], extent[2]), + goog.math.clamp(center[1], extent[1], extent[3]) + ]; + } else { + return undefined; + } + }); +}; + + +/** + * @param {ol.Coordinate|undefined} center Center. + * @return {ol.Coordinate|undefined} Center. + */ +ol.CenterConstraint.none = function(center) { + return center; +}; diff --git a/src/ol/constraints.js b/src/ol/constraints.js index 81b3e4cd57..84fc289b6f 100644 --- a/src/ol/constraints.js +++ b/src/ol/constraints.js @@ -1,5 +1,6 @@ goog.provide('ol.Constraints'); +goog.require('ol.CenterConstraintType'); goog.require('ol.ResolutionConstraintType'); goog.require('ol.RotationConstraintType'); @@ -7,12 +8,19 @@ goog.require('ol.RotationConstraintType'); /** * @constructor + * @param {ol.CenterConstraintType} centerConstraint Center constraint. * @param {ol.ResolutionConstraintType} resolutionConstraint * Resolution constraint. * @param {ol.RotationConstraintType} rotationConstraint * Rotation constraint. */ -ol.Constraints = function(resolutionConstraint, rotationConstraint) { +ol.Constraints = + function(centerConstraint, resolutionConstraint, rotationConstraint) { + + /** + * @type {ol.CenterConstraintType} + */ + this.center = centerConstraint; /** * @type {ol.ResolutionConstraintType} diff --git a/src/ol/interaction/dragpaninteraction.js b/src/ol/interaction/dragpaninteraction.js index 8d303ce846..0ef41626d6 100644 --- a/src/ol/interaction/dragpaninteraction.js +++ b/src/ol/interaction/dragpaninteraction.js @@ -68,6 +68,7 @@ ol.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) { ]; ol.coordinate.rotate(newCenter, view2DState.rotation); ol.coordinate.add(newCenter, this.startCenter); + newCenter = view.constrainCenter(newCenter); map.requestRenderFrame(); view.setCenter(newCenter); }; @@ -95,6 +96,7 @@ ol.interaction.DragPan.prototype.handleDragEnd = function(mapBrowserEvent) { centerpx[0] - distance * Math.cos(angle), centerpx[1] - distance * Math.sin(angle) ]); + dest = view.constrainCenter(dest); view.setCenter(dest); } map.requestRenderFrame(); diff --git a/src/ol/interaction/interaction.js b/src/ol/interaction/interaction.js index 667a7a7e2f..99978dc5a7 100644 --- a/src/ol/interaction/interaction.js +++ b/src/ol/interaction/interaction.js @@ -42,7 +42,9 @@ ol.interaction.Interaction.pan = function( easing: ol.easing.linear })); } - view.setCenter([currentCenter[0] + delta[0], currentCenter[1] + delta[1]]); + var center = view.constrainCenter( + [currentCenter[0] + delta[0], currentCenter[1] + delta[1]]); + view.setCenter(center); } }; diff --git a/src/ol/interaction/touchpaninteraction.js b/src/ol/interaction/touchpaninteraction.js index c8c1dee132..e2bd7c4533 100644 --- a/src/ol/interaction/touchpaninteraction.js +++ b/src/ol/interaction/touchpaninteraction.js @@ -69,6 +69,7 @@ ol.interaction.TouchPan.prototype.handleTouchMove = function(mapBrowserEvent) { ol.coordinate.scale(center, view2DState.resolution); ol.coordinate.rotate(center, view2DState.rotation); ol.coordinate.add(center, view2DState.center); + center = view.constrainCenter(center); map.requestRenderFrame(); view.setCenter(center); } @@ -95,6 +96,7 @@ ol.interaction.TouchPan.prototype.handleTouchEnd = centerpx[0] - distance * Math.cos(angle), centerpx[1] - distance * Math.sin(angle) ]); + dest = view.constrainCenter(dest); view.setCenter(dest); } map.requestRenderFrame(); diff --git a/src/ol/view2d.js b/src/ol/view2d.js index 75d569f975..d181295df3 100644 --- a/src/ol/view2d.js +++ b/src/ol/view2d.js @@ -4,6 +4,7 @@ goog.provide('ol.View2D'); goog.provide('ol.View2DProperty'); goog.require('goog.asserts'); +goog.require('ol.CenterConstraint'); goog.require('ol.Constraints'); goog.require('ol.IView2D'); goog.require('ol.IView3D'); @@ -112,6 +113,7 @@ ol.View2D = function(opt_options) { */ this.minResolution_ = resolutionConstraintInfo.minResolution; + var centerConstraint = ol.View2D.createCenterConstraint_(options); var resolutionConstraint = resolutionConstraintInfo.constraint; var rotationConstraint = ol.View2D.createRotationConstraint_(options); @@ -119,8 +121,8 @@ ol.View2D = function(opt_options) { * @private * @type {ol.Constraints} */ - this.constraints_ = new ol.Constraints(resolutionConstraint, - rotationConstraint); + this.constraints_ = new ol.Constraints( + centerConstraint, resolutionConstraint, rotationConstraint); if (goog.isDef(options.resolution)) { values[ol.View2DProperty.RESOLUTION] = options.resolution; @@ -172,6 +174,15 @@ ol.View2D.prototype.calculateCenterZoom = function(resolution, anchor) { }; +/** + * @param {ol.Coordinate|undefined} center Center. + * @return {ol.Coordinate|undefined} Constrained center. + */ +ol.View2D.prototype.constrainCenter = function(center) { + return this.constraints_.center(center); +}; + + /** * Get the constrained the resolution of this view. * @param {number|undefined} resolution Resolution. @@ -472,6 +483,20 @@ ol.View2D.prototype.setZoom = function(zoom) { }; +/** + * @param {ol.View2DOptions} options View2D options. + * @private + * @return {ol.CenterConstraintType} + */ +ol.View2D.createCenterConstraint_ = function(options) { + if (goog.isDef(options.extent)) { + return ol.CenterConstraint.createExtent(options.extent); + } else { + return ol.CenterConstraint.none; + } +}; + + /** * @private * @param {ol.View2DOptions} options View2D options.