From 67fab12fefc7aaeeb4c52b22e3cdea146ebd30ed Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 3 Oct 2013 15:16:34 -0600 Subject: [PATCH] Listen for feature events and fire layer events --- src/ol/layer/vectorlayer.js | 37 +++++++++++++++++++++++--- test/spec/ol/layer/vectorlayer.test.js | 31 +++++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/ol/layer/vectorlayer.js b/src/ol/layer/vectorlayer.js index 362e34de12..d6dea95c45 100644 --- a/src/ol/layer/vectorlayer.js +++ b/src/ol/layer/vectorlayer.js @@ -3,9 +3,11 @@ goog.provide('ol.layer.VectorEventType'); goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('goog.events'); goog.require('goog.events.Event'); goog.require('goog.object'); goog.require('ol.Feature'); +goog.require('ol.FeatureEventType'); goog.require('ol.extent'); goog.require('ol.layer.Layer'); goog.require('ol.proj'); @@ -114,16 +116,18 @@ ol.layer.FeatureCache.prototype.getFeatureWithUid = function(uid) { /** * Remove a feature from the cache. * @param {ol.Feature} feature Feature. + * @param {ol.Extent=} opt_extent Optional extent (used when the current feature + * extent is different than the one in the index). */ -ol.layer.FeatureCache.prototype.remove = function(feature) { +ol.layer.FeatureCache.prototype.remove = function(feature, opt_extent) { var id = goog.getUid(feature).toString(), geometry = feature.getGeometry(); delete this.idLookup_[id]; - // index by bounding box if (!goog.isNull(geometry)) { - this.rTree_.remove(geometry.getBounds(), feature); + var extent = goog.isDef(opt_extent) ? opt_extent : geometry.getBounds(); + this.rTree_.remove(extent, feature); } }; @@ -181,19 +185,44 @@ ol.layer.Vector.prototype.addFeatures = function(features) { if (!goog.isNull(geometry)) { ol.extent.extend(extent, geometry.getBounds()); } + goog.events.listen(feature, ol.FeatureEventType.CHANGE, + this.handleFeatureChange_, false, this); } this.dispatchEvent(new ol.layer.VectorEvent(ol.layer.VectorEventType.ADD, features, [extent])); }; +/** + * Listener for feature change events. + * @param {ol.FeatureEvent} evt The feature change event. + * @private + */ +ol.layer.Vector.prototype.handleFeatureChange_ = function(evt) { + goog.asserts.assertInstanceof(evt.target, ol.Feature); + var feature = /** @type {ol.Feature} */ (evt.target); + var extents = []; + if (!goog.isNull(evt.oldExtent)) { + extents.push(evt.oldExtent); + } + var geometry = feature.getGeometry(); + if (!goog.isNull(geometry)) { + this.featureCache_.remove(feature, evt.oldExtent); + this.featureCache_.add(feature); + extents.push(geometry.getBounds()); + } + this.dispatchEvent(new ol.layer.VectorEvent(ol.layer.VectorEventType.CHANGE, + [feature], extents)); +}; + + /** * Remove all features from the layer. */ ol.layer.Vector.prototype.clear = function() { this.featureCache_.clear(); this.dispatchEvent( - new ol.layer.VectorEvent(ol.layer.VectorEventType.CHANGE, [], [])); + new ol.layer.VectorEvent(ol.layer.VectorEventType.REMOVE, [], [])); }; diff --git a/test/spec/ol/layer/vectorlayer.test.js b/test/spec/ol/layer/vectorlayer.test.js index 84435a6d72..ea6977736e 100644 --- a/test/spec/ol/layer/vectorlayer.test.js +++ b/test/spec/ol/layer/vectorlayer.test.js @@ -147,6 +147,37 @@ describe('ol.layer.Vector', function() { }); + describe('ol.layer.VectorEvent', function() { + + var layer, features; + + beforeEach(function() { + features = [ + new ol.Feature({ + g: new ol.geom.Point([16.0, 48.0]) + }), + new ol.Feature({ + g: new ol.geom.LineString([[17.0, 49.0], [17.1, 49.1]]) + }) + ]; + layer = new ol.layer.Vector({ + source: new ol.source.Vector({}) + }); + layer.addFeatures(features); + }); + + it('dispatches events on feature change', function(done) { + layer.on('featurechange', function(evt) { + expect(evt.features[0]).to.be(features[0]); + expect(evt.extents[0]).to.eql(features[0].getGeometry().getBounds()); + done(); + }); + features[0].set('foo', 'bar'); + + }); + + }); + }); goog.require('goog.dispose');