From 1daf36956cd6e70773e5c669762df1d49e8b3450 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sun, 6 Jul 2014 17:56:54 -0600 Subject: [PATCH] Layer extent option If provided, the layer extent will be used to limit data requests and rendering. If undefined, to limit will be imposed. --- externs/olx.js | 53 ++++++++++++++++++++++++ src/ol/layer/layerbase.js | 35 ++++++++++++++++ src/ol/layer/layergroup.js | 5 +++ test/spec/ol/layer/layer.test.js | 5 +++ test/spec/ol/layer/layergroup.test.js | 58 +++++++++++++++++++++++++++ 5 files changed, 156 insertions(+) diff --git a/externs/olx.js b/externs/olx.js index ad1c275762..5d03d0b633 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -1969,6 +1969,7 @@ olx.interaction.SelectOptions.prototype.toggleCondition; * opacity: (number|undefined), * saturation: (number|undefined), * visible: (boolean|undefined), + * extent: (ol.Extent|undefined), * minResolution: (number|undefined), * maxResolution: (number|undefined)}} * @api @@ -2018,6 +2019,14 @@ olx.layer.BaseOptions.prototype.saturation; olx.layer.BaseOptions.prototype.visible; +/** + * The bounding extent for layer rendering. The layer will not be rendered + * outside of this extent. + * @type {ol.Extent|undefined} + */ +olx.layer.BaseOptions.prototype.extent; + + /** * The minimum resolution (inclusive) at which this layer will be visible. * @type {number|undefined} @@ -2040,6 +2049,7 @@ olx.layer.BaseOptions.prototype.maxResolution; * saturation: (number|undefined), * source: ol.source.Source, * visible: (boolean|undefined), + * extent: (ol.Extent|undefined), * minResolution: (number|undefined), * maxResolution: (number|undefined)}} * @api @@ -2096,6 +2106,14 @@ olx.layer.LayerOptions.prototype.source; olx.layer.LayerOptions.prototype.visible; +/** + * The bounding extent for layer rendering. The layer will not be rendered + * outside of this extent. + * @type {ol.Extent|undefined} + */ +olx.layer.LayerOptions.prototype.extent; + + /** * The minimum resolution (inclusive) at which this layer will be visible. * @type {number|undefined} @@ -2117,6 +2135,7 @@ olx.layer.LayerOptions.prototype.maxResolution; * opacity: (number|undefined), * saturation: (number|undefined), * visible: (boolean|undefined), + * extent: (ol.Extent|undefined), * minResolution: (number|undefined), * maxResolution: (number|undefined), * layers: (Array.|ol.Collection|undefined)}} @@ -2167,6 +2186,14 @@ olx.layer.GroupOptions.prototype.saturation; olx.layer.GroupOptions.prototype.visible; +/** + * The bounding extent for layer rendering. The layer will not be rendered + * outside of this extent. + * @type {ol.Extent|undefined} + */ +olx.layer.GroupOptions.prototype.extent; + + /** * The minimum resolution (inclusive) at which this layer will be visible. * @type {number|undefined} @@ -2197,6 +2224,7 @@ olx.layer.GroupOptions.prototype.layers; * blur: (number|undefined), * shadow: (number|undefined), * weight: (string|function(ol.Feature):number|undefined), + * extent: (ol.Extent|undefined), * minResolution: (number|undefined), * maxResolution: (number|undefined), * opacity: (number|undefined), @@ -2267,6 +2295,14 @@ olx.layer.HeatmapOptions.prototype.shadow; olx.layer.HeatmapOptions.prototype.weight; +/** + * The bounding extent for layer rendering. The layer will not be rendered + * outside of this extent. + * @type {ol.Extent|undefined} + */ +olx.layer.HeatmapOptions.prototype.extent; + + /** * The minimum resolution (inclusive) at which this layer will be visible. * @type {number|undefined} @@ -2318,6 +2354,7 @@ olx.layer.HeatmapOptions.prototype.visible; * saturation: (number|undefined), * source: ol.source.Source, * visible: (boolean|undefined), + * extent: (ol.Extent|undefined), * minResolution: (number|undefined), * maxResolution: (number|undefined), * useInterimTilesOnError: (boolean|undefined)}} @@ -2382,6 +2419,14 @@ olx.layer.TileOptions.prototype.source; olx.layer.TileOptions.prototype.visible; +/** + * The bounding extent for layer rendering. The layer will not be rendered + * outside of this extent. + * @type {ol.Extent|undefined} + */ +olx.layer.TileOptions.prototype.extent; + + /** * The minimum resolution (inclusive) at which this layer will be visible. * @type {number|undefined} @@ -2450,6 +2495,14 @@ olx.layer.VectorOptions.prototype.renderOrder; olx.layer.VectorOptions.prototype.hue; +/** + * The bounding extent for layer rendering. The layer will not be rendered + * outside of this extent. + * @type {ol.Extent|undefined} + */ +olx.layer.VectorOptions.prototype.extent; + + /** * The minimum resolution (inclusive) at which this layer will be visible. * @type {number|undefined} diff --git a/src/ol/layer/layerbase.js b/src/ol/layer/layerbase.js index f2c9c1b6b6..51652f0cde 100644 --- a/src/ol/layer/layerbase.js +++ b/src/ol/layer/layerbase.js @@ -19,6 +19,7 @@ ol.layer.LayerProperty = { OPACITY: 'opacity', SATURATION: 'saturation', VISIBLE: 'visible', + EXTENT: 'extent', MAX_RESOLUTION: 'maxResolution', MIN_RESOLUTION: 'minResolution' }; @@ -33,6 +34,7 @@ ol.layer.LayerProperty = { * saturation: number, * sourceState: ol.source.State, * visible: boolean, + * extent: (ol.Extent|undefined), * maxResolution: number, * minResolution: number}} */ @@ -141,6 +143,7 @@ ol.layer.Base.prototype.getLayerState = function() { var saturation = this.getSaturation(); var sourceState = this.getSourceState(); var visible = this.getVisible(); + var extent = this.getExtent(); var maxResolution = this.getMaxResolution(); var minResolution = this.getMinResolution(); return { @@ -152,6 +155,7 @@ ol.layer.Base.prototype.getLayerState = function() { saturation: goog.isDef(saturation) ? Math.max(saturation, 0) : 1, sourceState: sourceState, visible: goog.isDef(visible) ? !!visible : true, + extent: extent, maxResolution: goog.isDef(maxResolution) ? maxResolution : Infinity, minResolution: goog.isDef(minResolution) ? Math.max(minResolution, 0) : 0 }; @@ -174,6 +178,21 @@ ol.layer.Base.prototype.getLayersArray = goog.abstractMethod; ol.layer.Base.prototype.getLayerStatesArray = goog.abstractMethod; +/** + * @return {ol.Extent|undefined} The layer extent. + * @observable + * @api + */ +ol.layer.Base.prototype.getExtent = function() { + return /** @type {ol.Extent|undefined} */ ( + this.get(ol.layer.LayerProperty.EXTENT)); +}; +goog.exportProperty( + ol.layer.Base.prototype, + 'getExtent', + ol.layer.Base.prototype.getExtent); + + /** * @return {number|undefined} The maximum resolution of the layer. * @observable @@ -320,6 +339,22 @@ goog.exportProperty( ol.layer.Base.prototype.setHue); +/** + * Set the extent at which the layer is visible. If `undefined`, the layer + * will be visible at all extents. + * @param {ol.Extent|undefined} extent The extent of the layer. + * @observable + * @api + */ +ol.layer.Base.prototype.setExtent = function(extent) { + this.set(ol.layer.LayerProperty.EXTENT, extent); +}; +goog.exportProperty( + ol.layer.Base.prototype, + 'setExtent', + ol.layer.Base.prototype.setExtent); + + /** * @param {number|undefined} maxResolution The maximum resolution of the layer. * @observable diff --git a/src/ol/layer/layergroup.js b/src/ol/layer/layergroup.js index daf4b8e099..fc6edd8579 100644 --- a/src/ol/layer/layergroup.js +++ b/src/ol/layer/layergroup.js @@ -11,6 +11,7 @@ goog.require('ol.CollectionEvent'); goog.require('ol.CollectionEventType'); goog.require('ol.Object'); goog.require('ol.ObjectEventType'); +goog.require('ol.extent'); goog.require('ol.layer.Base'); goog.require('ol.source.State'); @@ -211,6 +212,10 @@ ol.layer.Group.prototype.getLayerStatesArray = function(opt_states) { layerState.maxResolution, ownLayerState.maxResolution); layerState.minResolution = Math.max( layerState.minResolution, ownLayerState.minResolution); + if (goog.isDef(ownLayerState.extent) && goog.isDef(layerState.extent)) { + layerState.extent = ol.extent.getIntersection( + layerState.extent, ownLayerState.extent); + } } return states; diff --git a/test/spec/ol/layer/layer.test.js b/test/spec/ol/layer/layer.test.js index be6297f268..71bea3b08d 100644 --- a/test/spec/ol/layer/layer.test.js +++ b/test/spec/ol/layer/layer.test.js @@ -56,6 +56,7 @@ describe('ol.layer.Layer', function() { saturation: 1, visible: true, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: Infinity, minResolution: 0 }); @@ -99,6 +100,7 @@ describe('ol.layer.Layer', function() { saturation: 5, visible: false, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: 500, minResolution: 0.25 }); @@ -191,6 +193,7 @@ describe('ol.layer.Layer', function() { saturation: 0.3, visible: false, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: 500, minResolution: 0.25 }); @@ -212,6 +215,7 @@ describe('ol.layer.Layer', function() { saturation: 0, visible: false, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: Infinity, minResolution: 0 }); @@ -231,6 +235,7 @@ describe('ol.layer.Layer', function() { saturation: 42, visible: true, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: Infinity, minResolution: 0 }); diff --git a/test/spec/ol/layer/layergroup.test.js b/test/spec/ol/layer/layergroup.test.js index d26885f25f..b9c6918842 100644 --- a/test/spec/ol/layer/layergroup.test.js +++ b/test/spec/ol/layer/layergroup.test.js @@ -52,6 +52,7 @@ describe('ol.layer.Group', function() { saturation: 1, visible: true, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: Infinity, minResolution: 0 }); @@ -179,6 +180,7 @@ describe('ol.layer.Group', function() { saturation: 5, visible: false, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: 500, minResolution: 0.25 }); @@ -190,6 +192,56 @@ describe('ol.layer.Group', function() { goog.dispose(layerGroup); }); + it('accepts an extent option', function() { + var layer = new ol.layer.Layer({ + source: new ol.source.Source({ + projection: 'EPSG:4326' + }) + }); + + var groupExtent = [-10, -5, 10, 5]; + var layerGroup = new ol.layer.Group({ + layers: [layer], + brightness: 0.5, + contrast: 10, + hue: 180, + opacity: 0.5, + saturation: 5, + visible: false, + extent: groupExtent, + maxResolution: 500, + minResolution: 0.25 + }); + + expect(layerGroup.getBrightness()).to.be(0.5); + expect(layerGroup.getContrast()).to.be(10); + expect(layerGroup.getHue()).to.be(180); + expect(layerGroup.getOpacity()).to.be(0.5); + expect(layerGroup.getSaturation()).to.be(5); + expect(layerGroup.getVisible()).to.be(false); + expect(layerGroup.getExtent()).to.eql(groupExtent); + expect(layerGroup.getMaxResolution()).to.be(500); + expect(layerGroup.getMinResolution()).to.be(0.25); + expect(layerGroup.getLayerState()).to.eql({ + layer: layerGroup, + brightness: 0.5, + contrast: 10, + hue: 180, + opacity: 0.5, + saturation: 5, + visible: false, + sourceState: ol.source.State.READY, + extent: groupExtent, + maxResolution: 500, + minResolution: 0.25 + }); + expect(layerGroup.getLayers()).to.be.a(ol.Collection); + expect(layerGroup.getLayers().getLength()).to.be(1); + expect(layerGroup.getLayers().item(0)).to.be(layer); + + goog.dispose(layer); + goog.dispose(layerGroup); + }); }); describe('#getLayerState', function() { @@ -211,6 +263,8 @@ describe('ol.layer.Group', function() { layerGroup.setOpacity(0.3); layerGroup.setSaturation(0.3); layerGroup.setVisible(false); + var groupExtent = [-100, 50, 100, 50]; + layerGroup.setExtent(groupExtent); layerGroup.setMaxResolution(500); layerGroup.setMinResolution(0.25); expect(layerGroup.getLayerState()).to.eql({ @@ -222,6 +276,7 @@ describe('ol.layer.Group', function() { saturation: 0.3, visible: false, sourceState: ol.source.State.READY, + extent: groupExtent, maxResolution: 500, minResolution: 0.25 }); @@ -243,6 +298,7 @@ describe('ol.layer.Group', function() { saturation: 0, visible: false, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: Infinity, minResolution: 0 }); @@ -262,6 +318,7 @@ describe('ol.layer.Group', function() { saturation: 42, visible: true, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: Infinity, minResolution: 0 }); @@ -384,6 +441,7 @@ describe('ol.layer.Group', function() { saturation: 25, visible: false, sourceState: ol.source.State.READY, + extent: undefined, maxResolution: 150, minResolution: 0.25 });