From 871388d2c0fff028d4ed1b4533c72bd9fe557879 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Fri, 9 Aug 2013 20:11:33 +0200 Subject: [PATCH] Adding selection layer and implementing basic click selection --- examples/select-features.html | 2 +- src/objectliterals.jsdoc | 1 + src/ol/control/selectcontrol.js | 55 ++++++++++++++++++++++++++++++--- src/ol/layer/vectorlayer.js | 40 ++++++++++++++++++++++-- 4 files changed, 91 insertions(+), 7 deletions(-) diff --git a/examples/select-features.html b/examples/select-features.html index 8e34f3422b..048f603d13 100644 --- a/examples/select-features.html +++ b/examples/select-features.html @@ -8,7 +8,7 @@ - Select featuers example + Select features example diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 04cda33390..7c2d5488d6 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -367,6 +367,7 @@ * @property {number|undefined} opacity Opacity. 0-1. Default is 1. * @property {ol.source.Source} source Source for this layer. * @property {ol.style.Style|undefined} style Style. + * @property {boolean} temp True for temporary layers. For internal use only. * @property {boolean|undefined} visible Visibility. Default is true (visible). */ diff --git a/src/ol/control/selectcontrol.js b/src/ol/control/selectcontrol.js index 20c5b34933..326f5115cd 100644 --- a/src/ol/control/selectcontrol.js +++ b/src/ol/control/selectcontrol.js @@ -9,6 +9,9 @@ goog.require('goog.events.EventType'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.control.Control'); goog.require('ol.css'); +goog.require('ol.interaction.condition'); +goog.require('ol.layer.Vector'); +goog.require('ol.source.Vector'); @@ -20,8 +23,14 @@ goog.require('ol.css'); ol.control.Select = function(opt_options) { var options = goog.isDef(opt_options) ? opt_options : {}; + this.layer = new ol.layer.Vector({ + source: new ol.source.Vector({parser: null}), + temp: true + }); + this.layers_ = options.layers; + // TODO: css var className = goog.isDef(options.className) ? options.className : 'ol-select'; @@ -67,7 +76,8 @@ ol.control.Select.prototype.toggleActive_ = function(browserEvent) { */ ol.control.Select.prototype.activate = function() { goog.dom.classes.add(this.element, 'active'); - // TODO: Add box selection + this.getMap().addLayer(this.layer); + // TODO: Implement box selection this.listenerKeys.push( goog.events.listen(this.getMap(), ol.MapBrowserEvent.EventType.CLICK, this.handleClick, true, this)); @@ -82,6 +92,7 @@ ol.control.Select.prototype.deactivate = function() { goog.array.forEach(this.listenerKeys, goog.events.unlistenByKey); this.listenerKeys.length = 0; } + this.getMap().removeLayer(this.layer); goog.dom.classes.remove(this.element, 'active'); }; @@ -90,17 +101,53 @@ ol.control.Select.prototype.deactivate = function() { * @param {ol.MapBrowserEvent} evt Event. */ ol.control.Select.prototype.handleClick = function(evt) { + var clear = true; + if (ol.interaction.condition.shiftKeyOnly(evt.browserEvent)) { + clear = false; + } + + function select(featuresByLayer) { + this.select(featuresByLayer, clear); + } + this.getMap().getFeatures({ layers: this.layers_, pixel: evt.getPixel(), - success: this.select + success: goog.bind(select, this) }); }; /** * @param {Array.>} featuresByLayer Features by layer. + * @param {boolean} clear Whether the current layer content should be cleared. */ -ol.control.Select.prototype.select = function(featuresByLayer) { - // TODO: Do something with the features. +ol.control.Select.prototype.select = function(featuresByLayer, clear) { + for (var i = 0, ii = featuresByLayer.length; i < ii; ++i) { + var features = featuresByLayer[i]; + var numFeatures = features.length; + var selectedFeatures = []; + var unselectedFeatures = []; + for (var j = 0; j < numFeatures; ++j) { + var feature = features[j]; + var selectedFeature = this.layer.getFeatureWithUid(goog.getUid(feature)); + if (selectedFeature) { + // TODO: make toggle configurable + unselectedFeatures.push(selectedFeature); + } else { + selectedFeatures.push(feature); + } + } + var layer = this.layers_[i]; + if (goog.isFunction(layer.setRenderIntent)) { + // TODO: Implement setRenderIntent for ol.layer.Vector + layer.setRenderIntent('hidden', selectedFeatures); + layer.setRenderIntent('default', unselectedFeatures); + } + if (clear) { + this.layer.clear(); + } + this.layer.removeFeatures(unselectedFeatures); + this.layer.addFeatures(selectedFeatures); + } }; diff --git a/src/ol/layer/vectorlayer.js b/src/ol/layer/vectorlayer.js index 397d6768e1..3055d98b20 100644 --- a/src/ol/layer/vectorlayer.js +++ b/src/ol/layer/vectorlayer.js @@ -201,6 +201,16 @@ ol.layer.FeatureCache.prototype.getFeaturesByIds_ = function(ids) { }; +/** + * @param {string} uid Feature uid. + * @return {ol.Feature|undefined} The feature with the provided uid if it is in + * the cache, otherwise undefined. + */ +ol.layer.FeatureCache.prototype.getFeatureWithUid = function(uid) { + return this.idLookup_[uid]; +}; + + /** * Remove a feature from the cache. * @param {ol.Feature} feature Feature. @@ -287,6 +297,11 @@ ol.layer.Vector = function(options) { */ this.polygonVertices_ = new ol.geom.SharedVertices(); + /** + * @type {boolean} Whether this is a temporary layer + */ + this.temp = goog.isDef(options.temp) ? options.temp : false; + }; goog.inherits(ol.layer.Vector, ol.layer.Layer); @@ -313,6 +328,17 @@ ol.layer.Vector.prototype.addFeatures = function(features) { }; +/** + * Remove all features from the layer. + */ +ol.layer.Vector.prototype.clear = function() { + this.featureCache_.clear(); + this.dispatchEvent(/** @type {ol.layer.VectorLayerEventObject} */ ({ + type: goog.events.EventType.CHANGE + })); +}; + + /** * @return {ol.source.Vector} Source. */ @@ -426,6 +452,16 @@ ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral = }; +/** + * @param {string|number} uid Feature uid. + * @return {ol.Feature|undefined} The feature with the provided uid if it is on + * the layer, otherwise undefined. + */ +ol.layer.Vector.prototype.getFeatureWithUid = function(uid) { + return this.featureCache_.getFeatureWithUid(/** @type {string} */ (uid)); +}; + + /** * @param {Object|Element|Document|string} data Feature data. * @param {ol.parser.Parser} parser Feature parser. @@ -537,7 +573,7 @@ ol.layer.Vector.prototype.removeFeatures = function(features) { * @return {string} Feature info. */ ol.layer.Vector.uidTransformFeatureInfo = function(features) { - var featureIds = goog.array.map(features, + var uids = goog.array.map(features, function(feature) { return goog.getUid(feature); }); - return featureIds.join(', '); + return uids.join(', '); };