diff --git a/src/ol/source/Vector.js b/src/ol/source/Vector.js index 5ce5f70029..98e30bdf81 100644 --- a/src/ol/source/Vector.js +++ b/src/ol/source/Vector.js @@ -544,7 +544,10 @@ class VectorSource extends Source { } } else { if (this.featuresRtree_) { - this.featuresRtree_.forEach(this.removeFeatureInternal.bind(this)); + // use Array forEach to ignore return + this.featuresRtree_ + .getAll() + .forEach(this.removeFeatureInternal.bind(this)); for (const id in this.nullGeometryFeatures_) { this.removeFeatureInternal(this.nullGeometryFeatures_[id]); } @@ -1019,6 +1022,9 @@ class VectorSource extends Source { * @api */ removeFeature(feature) { + if (!feature) { + return; + } const featureKey = getUid(feature); if (featureKey in this.nullGeometryFeatures_) { delete this.nullGeometryFeatures_[featureKey]; @@ -1027,18 +1033,29 @@ class VectorSource extends Source { this.featuresRtree_.remove(feature); } } - this.removeFeatureInternal(feature); - this.changed(); + const result = this.removeFeatureInternal(feature); + if (result) { + this.changed(); + } + // TODO at full version for consistency with other remove methods + // (would be breaking change if used as callback in forEachFeatureAtPixel) + //return result; } /** * Remove feature without firing a `change` event. * @param {import("../Feature.js").default} feature Feature. + * @return {import("../Feature.js").default|undefined} The removed feature + * (or undefined if the feature was not found). * @protected */ removeFeatureInternal(feature) { const featureKey = getUid(feature); - this.featureChangeKeys_[featureKey].forEach(unlistenByKey); + const featureChangeKeys = this.featureChangeKeys_[featureKey]; + if (!featureChangeKeys) { + return; + } + featureChangeKeys.forEach(unlistenByKey); delete this.featureChangeKeys_[featureKey]; const id = feature.getId(); if (id !== undefined) { @@ -1048,6 +1065,7 @@ class VectorSource extends Source { this.dispatchEvent( new VectorSourceEvent(VectorEventType.REMOVEFEATURE, feature) ); + return feature; } /**