diff --git a/src/ol/source/vectorfilesource.js b/src/ol/source/vectorfilesource.js index 8e82084814..865f647e55 100644 --- a/src/ol/source/vectorfilesource.js +++ b/src/ol/source/vectorfilesource.js @@ -106,20 +106,17 @@ ol.source.VectorFile.prototype.readFeatures_ = function(source) { var format = this.format; var features = format.readFeatures(source); var featureProjection = format.readProjection(source); - var transform; if (!ol.proj.equivalent(featureProjection, this.reprojectTo_)) { - transform = ol.proj.getTransform(featureProjection, this.reprojectTo_); - } else { - transform = null; - } - var i, ii; - for (i = 0, ii = features.length; i < ii; ++i) { - var feature = features[i]; - var geometry = feature.getGeometry(); - if (!goog.isNull(geometry) && !goog.isNull(transform)) { - geometry.transform(transform); + var transform = ol.proj.getTransform(featureProjection, this.reprojectTo_); + var i, ii; + for (i = 0, ii = features.length; i < ii; ++i) { + var feature = features[i]; + var geometry = feature.getGeometry(); + if (!goog.isNull(geometry)) { + geometry.transform(transform); + } } - this.addFeature(feature); } + this.addFeaturesInternal(features); this.setState(ol.source.State.READY); }; diff --git a/src/ol/source/vectorsource.exports b/src/ol/source/vectorsource.exports index cc76d95621..1b55238538 100644 --- a/src/ol/source/vectorsource.exports +++ b/src/ol/source/vectorsource.exports @@ -1,5 +1,6 @@ @exportSymbol ol.source.Vector @exportProperty ol.source.Vector.prototype.addFeature +@exportProperty ol.source.Vector.prototype.addFeatures @exportProperty ol.source.Vector.prototype.getClosestFeatureToCoordinate @exportProperty ol.source.Vector.prototype.forEachFeature @exportProperty ol.source.Vector.prototype.getAllFeatures diff --git a/src/ol/source/vectorsource.js b/src/ol/source/vectorsource.js index 11079daf57..a69c70ca6d 100644 --- a/src/ol/source/vectorsource.js +++ b/src/ol/source/vectorsource.js @@ -63,11 +63,7 @@ ol.source.Vector = function(opt_options) { this.featureChangeKeys_ = {}; if (goog.isDef(options.features)) { - var features = options.features; - var i, ii; - for (i = 0, ii = features.length; i < ii; ++i) { - this.addFeature(features[i]); - } + this.addFeaturesInternal(options.features); } }; @@ -78,6 +74,17 @@ goog.inherits(ol.source.Vector, ol.source.Source); * @param {ol.Feature} feature Feature. */ ol.source.Vector.prototype.addFeature = function(feature) { + this.addFeatureInternal(feature); + this.dispatchChangeEvent(); +}; + + +/** + * Add a feature without firing a `change` event. + * @param {ol.Feature} feature Feature. + * @protected + */ +ol.source.Vector.prototype.addFeatureInternal = function(feature) { var featureKey = goog.getUid(feature) + ''; goog.asserts.assert(!(featureKey in this.featureChangeKeys_)); this.featureChangeKeys_[featureKey] = goog.events.listen(feature, @@ -91,16 +98,42 @@ ol.source.Vector.prototype.addFeature = function(feature) { } this.dispatchEvent( new ol.source.VectorEvent(ol.source.VectorEventType.ADDFEATURE, feature)); +}; + + +/** + * @param {Array.} features Features. + */ +ol.source.Vector.prototype.addFeatures = function(features) { + this.addFeaturesInternal(features); this.dispatchChangeEvent(); }; +/** + * Add features without firing a `change` event. + * @param {Array.} features Features. + * @protected + */ +ol.source.Vector.prototype.addFeaturesInternal = function(features) { + // FIXME use R-Bush bulk load when available + var i, ii; + for (i = 0, ii = features.length; i < ii; ++i) { + this.addFeatureInternal(features[i]); + } +}; + + /** * FIXME empty description for jsdoc */ ol.source.Vector.prototype.clear = function() { - this.rBush_.forEach(this.removeFeatureInternal_, this); + this.rBush_.forEach(this.removeFeatureInternal, this); this.rBush_.clear(); + goog.object.forEach( + this.nullGeometryFeatures_, this.removeFeatureInternal, this); + goog.object.clear(this.nullGeometryFeatures_); + goog.asserts.assert(goog.object.isEmpty(this.featureChangeKeys_)); this.dispatchChangeEvent(); }; @@ -268,16 +301,17 @@ ol.source.Vector.prototype.removeFeature = function(feature) { } else { this.rBush_.remove(feature); } - this.removeFeatureInternal_(feature); + this.removeFeatureInternal(feature); this.dispatchChangeEvent(); }; /** + * Remove feature without firing a `change` event. * @param {ol.Feature} feature Feature. - * @private + * @protected */ -ol.source.Vector.prototype.removeFeatureInternal_ = function(feature) { +ol.source.Vector.prototype.removeFeatureInternal = function(feature) { var featureKey = goog.getUid(feature) + ''; goog.asserts.assert(featureKey in this.featureChangeKeys_); goog.events.unlistenByKey(this.featureChangeKeys_[featureKey]); diff --git a/test/spec/ol/source/vectorsource.test.js b/test/spec/ol/source/vectorsource.test.js index 7037c86bbc..975a793af6 100644 --- a/test/spec/ol/source/vectorsource.test.js +++ b/test/spec/ol/source/vectorsource.test.js @@ -66,7 +66,7 @@ describe('ol.source.Vector', function() { }); - describe('when populated with 10 random points', function() { + describe('when populated with 10 random points and a null', function() { var features; var vectorSource; @@ -77,6 +77,7 @@ describe('ol.source.Vector', function() { features[i] = new ol.Feature(new ol.geom.Point([Math.random(), Math.random()])); } + features.push(new ol.Feature(null)); vectorSource = new ol.source.Vector({ features: features }); @@ -95,7 +96,7 @@ describe('ol.source.Vector', function() { expect(changeSpy).to.be.called(); expect(changeSpy.callCount).to.be(1); expect(removeFeatureSpy).to.be.called(); - expect(removeFeatureSpy.callCount).to.be(10); + expect(removeFeatureSpy.callCount).to.be(features.length); }); });