Work with clones rather than the original features
This commit is contained in:
@@ -38,6 +38,12 @@ ol.control.Select = function(opt_options) {
|
||||
*/
|
||||
this.active_ = false;
|
||||
|
||||
/**
|
||||
* @type {Object.<string, ol.Feature>}
|
||||
* @private
|
||||
*/
|
||||
this.featureMap_ = {};
|
||||
|
||||
/**
|
||||
* @type {ol.layer.Vector}
|
||||
* @protected
|
||||
@@ -150,31 +156,44 @@ ol.control.Select.prototype.handleClick = function(evt) {
|
||||
*/
|
||||
ol.control.Select.prototype.select = function(featuresByLayer, clear) {
|
||||
for (var i = 0, ii = featuresByLayer.length; i < ii; ++i) {
|
||||
var layer = this.layers_[i];
|
||||
var features = featuresByLayer[i];
|
||||
var numFeatures = features.length;
|
||||
var selectedFeatures = [];
|
||||
var featuresToAdd = [];
|
||||
var unselectedFeatures = [];
|
||||
var featuresToRemove = [];
|
||||
for (var j = 0; j < numFeatures; ++j) {
|
||||
var feature = features[j];
|
||||
var selectedFeature = this.layer.getFeatureWithUid(goog.getUid(feature));
|
||||
if (selectedFeature) {
|
||||
var uid = goog.getUid(feature);
|
||||
var clone = this.featureMap_[uid];
|
||||
if (clone) {
|
||||
// TODO: make toggle configurable
|
||||
unselectedFeatures.push(selectedFeature);
|
||||
} else {
|
||||
selectedFeatures.push(feature);
|
||||
featuresToRemove.push(clone);
|
||||
delete this.featureMap_[uid];
|
||||
}
|
||||
if (clear) {
|
||||
for (var f in this.featureMap_) {
|
||||
unselectedFeatures.push(layer.getFeatureWithUid(f));
|
||||
featuresToRemove.push(this.featureMap_[f]);
|
||||
}
|
||||
this.featureMap_ = {};
|
||||
}
|
||||
if (!clone) {
|
||||
clone = feature.clone();
|
||||
this.featureMap_[uid] = clone;
|
||||
selectedFeatures.push(feature);
|
||||
featuresToAdd.push(clone);
|
||||
}
|
||||
}
|
||||
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);
|
||||
this.layer.removeFeatures(featuresToRemove);
|
||||
this.layer.addFeatures(featuresToAdd);
|
||||
this.dispatchEvent(/** @type {ol.control.SelectEventObject} */ ({
|
||||
layer: layer,
|
||||
selected: selectedFeatures,
|
||||
|
||||
@@ -44,6 +44,20 @@ ol.Feature = function(opt_values) {
|
||||
goog.inherits(ol.Feature, ol.Object);
|
||||
|
||||
|
||||
/**
|
||||
* Create a clone of this feature. Both the feature and its geometry will be
|
||||
* cloned.
|
||||
* @return {ol.Feature} A clone of this feature, with a cloned geometry.
|
||||
*/
|
||||
ol.Feature.prototype.clone = function() {
|
||||
var clone = new ol.Feature(this.getAttributes());
|
||||
clone.setGeometry(this.getGeometry().clone());
|
||||
clone.featureId_ = this.featureId_;
|
||||
clone.symbolizers_ = this.symbolizers_;
|
||||
return clone;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets a copy of the attributes of this feature.
|
||||
* @return {Object.<string, *>} Attributes object.
|
||||
|
||||
@@ -27,6 +27,19 @@ ol.geom.Geometry = function() {
|
||||
ol.geom.Geometry.prototype.dimension;
|
||||
|
||||
|
||||
/**
|
||||
* Create a clone of this geometry. The clone will not be represented in any
|
||||
* shared structure.
|
||||
* @return {ol.geom.Geometry} The cloned geometry.
|
||||
*/
|
||||
ol.geom.Geometry.prototype.clone = function() {
|
||||
var clone = new this.constructor(this.getCoordinates());
|
||||
clone.bounds_ = this.bounds_;
|
||||
clone.dimension = this.dimension;
|
||||
return clone;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the rectangular 2D envelope for this geoemtry.
|
||||
* @return {ol.Extent} The bounding rectangular envelope.
|
||||
|
||||
@@ -120,8 +120,8 @@ describe('ol.control.Select', function() {
|
||||
it('can clear a selection before selecting new features', function() {
|
||||
select.select([[features[0]]], true);
|
||||
select.select([[features[1]]], true);
|
||||
expect(goog.object.getValues(select.layer.featureCache_.idLookup_)[0])
|
||||
.to.eql(features[1]);
|
||||
expect(goog.object.getCount(select.layer.featureCache_.idLookup_))
|
||||
.to.be(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -34,6 +34,24 @@ describe('ol.Feature', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#clone()', function() {
|
||||
|
||||
it('creates a clone with a cloned geometry', function() {
|
||||
var feature = new ol.Feature({
|
||||
loc: new ol.geom.Point([10, 20]),
|
||||
foo: 'bar'
|
||||
});
|
||||
feature.setFeatureId('foo');
|
||||
var clone = feature.clone();
|
||||
expect(clone).to.not.be(feature);
|
||||
expect(clone.get('foo')).to.be('bar');
|
||||
expect(clone.getFeatureId()).to.be('foo');
|
||||
expect(clone.getGeometry()).to.not.be(feature.getGeometry());
|
||||
expect(clone.getGeometry().getCoordinates()).to.eql([10, 20]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#get()', function() {
|
||||
|
||||
it('returns values set at construction', function() {
|
||||
|
||||
@@ -55,6 +55,23 @@ describe('ol.geom.GeometryCollection', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#clone()', function() {
|
||||
|
||||
it('has a working clone method', function() {
|
||||
var point = new ol.geom.Point([10, 20]);
|
||||
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
var multi = new ol.geom.GeometryCollection([point, line, poly]);
|
||||
var clone = multi.clone();
|
||||
expect(clone).to.not.be(multi);
|
||||
var components = clone.components;
|
||||
expect(components[0]).to.eql([10, 20]);
|
||||
expect(components[1]).to.eql([[10, 20], [30, 40]]);
|
||||
expect(components[2]).to.eql([outer, inner1, inner2]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getBounds()', function() {
|
||||
|
||||
it('returns the bounding extent', function() {
|
||||
|
||||
Reference in New Issue
Block a user