diff --git a/examples/select-features.js b/examples/select-features.js index 097b459616..f15b04f2e2 100644 --- a/examples/select-features.js +++ b/examples/select-features.js @@ -9,6 +9,7 @@ goog.require('ol.parser.ogc.GML_v3'); goog.require('ol.source.MapQuestOpenAerial'); goog.require('ol.source.Vector'); goog.require('ol.style.Fill'); +goog.require('ol.style.Rule'); goog.require('ol.style.Stroke'); goog.require('ol.style.Style'); @@ -22,6 +23,17 @@ var vector = new ol.layer.Vector({ url: 'data/gml/topp-states-wfs.xml' }), style: new ol.style.Style({ + rules: [ + new ol.style.Rule({ + filter: 'this.renderIntent == "selected"', + symbolizers: [ + new ol.style.Fill({ + color: '#ffffff', + opacity: 0.5 + }) + ] + }) + ], symbolizers: [ new ol.style.Fill({ color: '#ffffff', diff --git a/src/ol/control/selectcontrol.js b/src/ol/control/selectcontrol.js index 35c7db6d40..db4bcf8968 100644 --- a/src/ol/control/selectcontrol.js +++ b/src/ol/control/selectcontrol.js @@ -11,6 +11,7 @@ goog.require('ol.control.Control'); goog.require('ol.css'); goog.require('ol.interaction.condition'); goog.require('ol.layer.Vector'); +goog.require('ol.layer.VectorLayerRenderIntent'); goog.require('ol.source.Vector'); @@ -195,7 +196,7 @@ ol.control.Select.prototype.select = function(featuresByLayer, clear) { var clone = featureMap[uid]; if (clone) { // TODO: make toggle configurable - selectedFeatures.push(feature); + unselectedFeatures.push(feature); featuresToRemove.push(clone); delete featureMap[uid]; } @@ -210,14 +211,17 @@ ol.control.Select.prototype.select = function(featuresByLayer, clear) { if (!clone) { clone = feature.clone(); featureMap[uid] = clone; + clone.renderIntent = ol.layer.VectorLayerRenderIntent.SELECTED; selectedFeatures.push(feature); featuresToAdd.push(clone); } } if (goog.isFunction(layer.setRenderIntent)) { // TODO: Implement setRenderIntent for ol.Layer.Vector - layer.setRenderIntent('hidden', selectedFeatures); - layer.setRenderIntent('default', unselectedFeatures); + layer.setRenderIntent(ol.layer.VectorLayerRenderIntent.HIDDEN, + selectedFeatures); + layer.setRenderIntent(ol.layer.VectorLayerRenderIntent.DEFAULT, + unselectedFeatures); } selectionLayer.removeFeatures(featuresToRemove); selectionLayer.addFeatures(featuresToAdd); diff --git a/src/ol/feature.js b/src/ol/feature.js index aa19448f98..69ca5aea0d 100644 --- a/src/ol/feature.js +++ b/src/ol/feature.js @@ -2,6 +2,7 @@ goog.provide('ol.Feature'); goog.require('ol.Object'); goog.require('ol.geom.Geometry'); +goog.require('ol.layer.VectorLayerRenderIntent'); @@ -34,6 +35,12 @@ ol.Feature = function(opt_values) { */ this.geometryName_; + /** + * The render intent for this feature. + * @type {ol.layer.VectorLayerRenderIntent|string} + */ + this.renderIntent = ol.layer.VectorLayerRenderIntent.DEFAULT; + /** * @type {Array.} * @private diff --git a/src/ol/layer/vectorlayer.js b/src/ol/layer/vectorlayer.js index b79e26a329..fe010c7e18 100644 --- a/src/ol/layer/vectorlayer.js +++ b/src/ol/layer/vectorlayer.js @@ -236,7 +236,9 @@ ol.layer.FeatureCache.prototype.remove = function(feature) { */ ol.layer.VectorLayerEventType = { ADD: 'add', - REMOVE: 'remove' + CHANGE: goog.events.EventType.CHANGE, + REMOVE: 'remove', + SYMBOLIZER: 'symbolizer' }; @@ -336,7 +338,7 @@ ol.layer.Vector.prototype.addFeatures = function(features) { ol.layer.Vector.prototype.clear = function() { this.featureCache_.clear(); this.dispatchEvent(/** @type {ol.layer.VectorLayerEventObject} */ ({ - type: goog.events.EventType.CHANGE + type: ol.layer.VectorLayerEventType.CHANGE })); }; @@ -578,6 +580,30 @@ ol.layer.Vector.prototype.removeFeatures = function(features) { }; +/** + * Changes the renderIntent for an array of features. + * @param {string} renderIntent Render intent. + * @param {Array.} features Features to change the renderIntent for. + */ +ol.layer.Vector.prototype.setRenderIntent = function(renderIntent, features) { + var extent = ol.extent.createEmpty(), + feature, geometry; + for (var i = features.length - 1; i >= 0; --i) { + feature = features[i]; + feature.renderIntent = renderIntent; + geometry = feature.getGeometry(); + if (!goog.isNull(geometry)) { + ol.extent.extend(extent, geometry.getBounds()); + } + } + this.dispatchEvent(/** @type {ol.layer.VectorLayerEventObject} */ ({ + extent: extent, + features: features, + type: ol.layer.VectorLayerEventType.SYMBOLIZER + })); +}; + + /** * @param {Array.} features Features. * @return {string} Feature info. diff --git a/src/ol/layer/vectorlayerrenderintent.js b/src/ol/layer/vectorlayerrenderintent.js new file mode 100644 index 0000000000..757fef5aba --- /dev/null +++ b/src/ol/layer/vectorlayerrenderintent.js @@ -0,0 +1,11 @@ +goog.provide('ol.layer.VectorLayerRenderIntent'); + + +/** + * @enum {string} + */ +ol.layer.VectorLayerRenderIntent = { + DEFAULT: 'default', + HIDDEN: 'hidden', + SELECTED: 'selected' +}; diff --git a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js index 8d704eb2c0..fa6091f008 100644 --- a/src/ol/renderer/canvas/canvasvectorlayerrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorlayerrenderer.js @@ -88,7 +88,9 @@ ol.renderer.canvas.VectorLayer = function(mapRenderer, layer) { ol.renderer.canvas.VectorLayer.TILECACHE_SIZE); goog.events.listen(layer, [ ol.layer.VectorLayerEventType.ADD, - ol.layer.VectorLayerEventType.REMOVE + ol.layer.VectorLayerEventType.CHANGE, + ol.layer.VectorLayerEventType.REMOVE, + ol.layer.VectorLayerEventType.SYMBOLIZER ], this.handleLayerChange_, false, this); diff --git a/src/ol/renderer/canvas/canvasvectorrenderer.js b/src/ol/renderer/canvas/canvasvectorrenderer.js index 354a91803e..1e4543f446 100644 --- a/src/ol/renderer/canvas/canvasvectorrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorrenderer.js @@ -17,6 +17,7 @@ goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); +goog.require('ol.layer.VectorLayerRenderIntent'); goog.require('ol.style.IconLiteral'); goog.require('ol.style.LineLiteral'); goog.require('ol.style.Literal'); @@ -176,6 +177,9 @@ ol.renderer.canvas.VectorRenderer.prototype.renderLineStringFeatures_ = context.beginPath(); for (i = 0, ii = features.length; i < ii; ++i) { feature = features[i]; + if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) { + continue; + } id = goog.getUid(feature); currentSize = goog.isDef(this.symbolSizes_[id]) ? this.symbolSizes_[id] : [0]; @@ -253,6 +257,9 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPointFeatures_ = context.globalAlpha = alpha; for (i = 0, ii = features.length; i < ii; ++i) { feature = features[i]; + if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) { + continue; + } id = goog.getUid(feature); size = this.symbolSizes_[id]; this.symbolSizes_[id] = goog.isDef(size) ? @@ -296,7 +303,7 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPointFeatures_ = ol.renderer.canvas.VectorRenderer.prototype.renderText_ = function(features, text, texts) { var context = this.context_, - vecs, vec; + feature, vecs, vec; if (context.fillStyle !== text.color) { context.fillStyle = text.color; @@ -309,8 +316,12 @@ ol.renderer.canvas.VectorRenderer.prototype.renderText_ = context.textBaseline = 'middle'; for (var i = 0, ii = features.length; i < ii; ++i) { + feature = features[i]; + if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) { + continue; + } vecs = ol.renderer.canvas.VectorRenderer.getLabelVectors( - features[i].getGeometry()); + feature.getGeometry()); for (var j = 0, jj = vecs.length; j < jj; ++j) { vec = vecs[j]; goog.vec.Mat4.multVec3(this.transform_, vec, vec); @@ -336,7 +347,7 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPolygonFeatures_ = fillOpacity = symbolizer.fillOpacity, globalAlpha, i, ii, geometry, components, j, jj, poly, - rings, numRings, ring, dim, k, kk, vec; + rings, numRings, ring, dim, k, kk, vec, feature; if (strokeColor) { context.strokeStyle = strokeColor; @@ -359,7 +370,11 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPolygonFeatures_ = */ context.beginPath(); for (i = 0, ii = features.length; i < ii; ++i) { - geometry = features[i].getGeometry(); + feature = features[i]; + if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) { + continue; + } + geometry = feature.getGeometry(); if (geometry instanceof ol.geom.Polygon) { components = [geometry]; } else {