From d9fd45965480b3b9270402a45e86da3cb009d7ba Mon Sep 17 00:00:00 2001 From: ahocevar Date: Sat, 9 Nov 2013 14:07:08 +0100 Subject: [PATCH] Do not use a temporary layer for selected features --- src/ol/interaction/selectinteraction.js | 101 ++++-------------- .../ol/interaction/selectinteraction.test.js | 21 ++-- 2 files changed, 30 insertions(+), 92 deletions(-) diff --git a/src/ol/interaction/selectinteraction.js b/src/ol/interaction/selectinteraction.js index 6bfb1c303c..fa9edca216 100644 --- a/src/ol/interaction/selectinteraction.js +++ b/src/ol/interaction/selectinteraction.js @@ -1,14 +1,12 @@ goog.provide('ol.interaction.Select'); goog.require('goog.array'); -goog.require('goog.object'); goog.require('ol.Feature'); goog.require('ol.events.ConditionType'); goog.require('ol.events.condition'); goog.require('ol.interaction.Interaction'); goog.require('ol.layer.Vector'); goog.require('ol.layer.VectorLayerRenderIntent'); -goog.require('ol.source.Vector'); @@ -36,20 +34,6 @@ ol.interaction.Select = function(opt_options) { this.addCondition_ = goog.isDef(options.addCondition) ? options.addCondition : ol.events.condition.shiftKeyOnly; - /** - * Mapping between original features and cloned features on selection layers. - * @type {Object.<*,Object.<*,ol.Feature>>} - * @private - */ - this.featureMap_ = {}; - - /** - * Mapping between original layers and selection layers, by map. - * @type {Object.<*,{map:ol.Map,layers:Object.<*,ol.layer.Vector>}>} - * @protected - */ - this.selectionLayers = {}; - /** * @type {null|function(ol.layer.Layer):boolean} * @private @@ -99,77 +83,34 @@ ol.interaction.Select.prototype.handleMapBrowserEvent = */ ol.interaction.Select.prototype.select = function(map, featuresByLayer, layers, clear) { - var mapId = goog.getUid(map); - if (!(mapId in this.selectionLayers)) { - this.selectionLayers[mapId] = {map: map, layers: {}}; - } for (var i = 0, ii = featuresByLayer.length; i < ii; ++i) { var layer = layers[i]; - var layerId = goog.getUid(layer); - var selectionLayer = this.selectionLayers[mapId].layers[layerId]; - if (!goog.isDef(selectionLayer)) { - selectionLayer = new ol.layer.Vector({ - source: new ol.source.Vector({parser: null}), - style: layer instanceof ol.layer.Vector ? layer.getStyle() : null - }); - selectionLayer.setTemporary(true); - map.addLayer(selectionLayer); - this.selectionLayers[mapId].layers[layerId] = selectionLayer; - this.featureMap_[layerId] = {}; - } - var selectedFeatures, unselectedFeatures; - selectedFeatures = []; - unselectedFeatures = []; - var features = featuresByLayer[i]; - var numFeatures = features.length; - var featuresToAdd = []; - var featuresToRemove = []; - var featureMap = this.featureMap_[layerId]; - var oldFeatureMap = featureMap; + var featuresToSelect = featuresByLayer[i]; + var selectedFeatures = layer.getFeatures(this.selectedFeaturesFilter); if (clear) { - for (var f in featureMap) { - unselectedFeatures.push(layer.getFeatureWithUid(f)); - featuresToRemove.push(featureMap[f]); - } - featureMap = {}; - this.featureMap_[layerId] = featureMap; - } - for (var j = 0; j < numFeatures; ++j) { - var feature = features[j]; - var featureId = goog.getUid(feature); - var clone = featureMap[featureId]; - if (clone) { - // TODO: make toggle configurable - unselectedFeatures.push(feature); - delete featureMap[featureId]; - featuresToRemove.push(clone); - } else if (!(featureId in oldFeatureMap)) { - clone = new ol.Feature(feature.getAttributes()); - clone.setGeometry(feature.getGeometry().clone()); - clone.setId(feature.getId()); - clone.setSymbolizers(feature.getSymbolizers()); - clone.renderIntent = ol.layer.VectorLayerRenderIntent.SELECTED; - featureMap[featureId] = clone; - selectedFeatures.push(feature); - featuresToAdd.push(clone); + for (var j = selectedFeatures.length - 1; j >= 0; --j) { + selectedFeatures[j].setRenderIntent( + ol.layer.VectorLayerRenderIntent.DEFAULT); } } - for (var j = selectedFeatures.length - 1; j >= 0; --j) { - selectedFeatures[j].setRenderIntent( - ol.layer.VectorLayerRenderIntent.HIDDEN); - } - for (var j = unselectedFeatures.length - 1; j >= 0; --j) { - unselectedFeatures[j].setRenderIntent( - ol.layer.VectorLayerRenderIntent.DEFAULT); - } - selectionLayer.removeFeatures(featuresToRemove); - selectionLayer.addFeatures(featuresToAdd); - if (goog.object.getCount(featureMap) == 0) { - map.removeLayer(selectionLayer); - delete this.selectionLayers[mapId].layers[layerId]; - delete this.featureMap_[layerId]; + for (var j = featuresToSelect.length - 1; j >= 0; --j) { + var feature = featuresToSelect[j]; + // TODO: Make toggle configurable + feature.setRenderIntent( + feature.renderIntent == ol.layer.VectorLayerRenderIntent.SELECTED ? + ol.layer.VectorLayerRenderIntent.DEFAULT : + ol.layer.VectorLayerRenderIntent.SELECTED); } // TODO: Dispatch an event with selectedFeatures and unselectedFeatures } }; + + +/** + * @param {ol.Feature} feature Feature. + * @return {boolean} Whether the feature is selected. + */ +ol.interaction.Select.prototype.selectedFeaturesFilter = function(feature) { + return feature.renderIntent == ol.layer.VectorLayerRenderIntent.SELECTED; +}; diff --git a/test/spec/ol/interaction/selectinteraction.test.js b/test/spec/ol/interaction/selectinteraction.test.js index 12de3a07a6..330775b7a7 100644 --- a/test/spec/ol/interaction/selectinteraction.test.js +++ b/test/spec/ol/interaction/selectinteraction.test.js @@ -46,29 +46,27 @@ describe('ol.interaction.Select', function() { describe('#select', function() { + var selectedFeaturesFilter = function(feature) { + return feature.renderIntent == 'selected'; + }; + it('toggles selection of features', function() { select.select(map, [features], [vector]); - var layer = select.selectionLayers[goog.getUid(map)] - .layers[goog.getUid(vector)]; - expect(goog.object.getCount(layer.featureCache_.idLookup_)).to.be(2); + expect(vector.getFeatures(selectedFeaturesFilter).length).to.be(2); select.select(map, [features], [vector]); - expect(goog.object.getCount(layer.featureCache_.idLookup_)).to.be(0); + expect(vector.getFeatures(selectedFeaturesFilter).length).to.be(0); }); it('can append features to an existing selection', function() { - select.select(map, [[features[0]]], [vector]); + select.select(map, [[features[0]]], [vector], true); select.select(map, [[features[1]]], [vector]); - var layer = select.selectionLayers[goog.getUid(map)] - .layers[goog.getUid(vector)]; - expect(goog.object.getCount(layer.featureCache_.idLookup_)).to.be(2); + expect(vector.getFeatures(selectedFeaturesFilter).length).to.be(2); }); it('can clear a selection before selecting new features', function() { select.select(map, [[features[0]]], [vector], true); select.select(map, [[features[1]]], [vector], true); - var layer = select.selectionLayers[goog.getUid(map)] - .layers[goog.getUid(vector)]; - expect(goog.object.getCount(layer.featureCache_.idLookup_)).to.be(1); + expect(vector.getFeatures(selectedFeaturesFilter).length).to.be(1); }); }); @@ -76,7 +74,6 @@ describe('ol.interaction.Select', function() { }); goog.require('goog.dispose'); -goog.require('goog.object'); goog.require('ol.Map'); goog.require('ol.interaction.Select'); goog.require('ol.layer.Vector');