Make Modify interaction listen to feature changes

This commit makes the Modify interaction modify its segment data when the candidate features change.
This commit is contained in:
Éric Lemoine
2015-08-18 16:39:49 +02:00
parent d042b4c277
commit 5f7e6ac61a
2 changed files with 137 additions and 20 deletions

View File

@@ -4,6 +4,7 @@ goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.events.EventType');
goog.require('goog.functions');
goog.require('ol.Collection');
goog.require('ol.CollectionEventType');
@@ -168,6 +169,14 @@ ol.interaction.Modify = function(options) {
*/
this.snappedToVertex_ = false;
/**
* Indicate whether the interaction is currently changing a feature's
* coordinates.
* @type {boolean}
* @private
*/
this.changingFeature_ = false;
/**
* @type {Array}
* @private
@@ -235,6 +244,48 @@ ol.interaction.Modify.prototype.addFeature_ = function(feature) {
if (!goog.isNull(map)) {
this.handlePointerAtPixel_(this.lastPixel_, map);
}
goog.events.listen(feature, goog.events.EventType.CHANGE,
this.handleFeatureChange_, false, this);
};
/**
* @param {ol.Feature} feature Feature.
* @private
*/
ol.interaction.Modify.prototype.removeFeature_ = function(feature) {
this.removeFeatureSegmentData_(feature);
// Remove the vertex feature if the collection of canditate features
// is empty.
if (!goog.isNull(this.vertexFeature_) &&
this.features_.getLength() === 0) {
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
goog.events.unlisten(feature, goog.events.EventType.CHANGE,
this.handleFeatureChange_, false, this);
};
/**
* @param {ol.Feature} feature Feature.
* @private
*/
ol.interaction.Modify.prototype.removeFeatureSegmentData_ = function(feature) {
var rBush = this.rBush_;
var /** @type {Array.<ol.interaction.SegmentDataType>} */ nodesToRemove = [];
rBush.forEach(
/**
* @param {ol.interaction.SegmentDataType} node RTree node.
*/
function(node) {
if (feature === node.feature) {
nodesToRemove.push(node);
}
});
for (var i = nodesToRemove.length - 1; i >= 0; --i) {
rBush.remove(nodesToRemove[i]);
}
};
@@ -259,28 +310,26 @@ ol.interaction.Modify.prototype.handleFeatureAdd_ = function(evt) {
};
/**
* @param {goog.events.Event} evt Event.
* @private
*/
ol.interaction.Modify.prototype.handleFeatureChange_ = function(evt) {
if (!this.changingFeature_) {
var feature = /** @type {ol.Feature} */ (evt.target);
this.removeFeature_(feature);
this.addFeature_(feature);
}
};
/**
* @param {ol.CollectionEvent} evt Event.
* @private
*/
ol.interaction.Modify.prototype.handleFeatureRemove_ = function(evt) {
var feature = evt.element;
var rBush = this.rBush_;
var i, nodesToRemove = [];
rBush.forEachInExtent(feature.getGeometry().getExtent(), function(node) {
if (feature === node.feature) {
nodesToRemove.push(node);
}
});
for (i = nodesToRemove.length - 1; i >= 0; --i) {
rBush.remove(nodesToRemove[i]);
}
// There remains only vertexFeature…
if (!goog.isNull(this.vertexFeature_) &&
this.features_.getLength() === 0) {
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
var feature = /** @type {ol.Feature} */ (evt.element);
this.removeFeature_(feature);
};
@@ -585,7 +634,7 @@ ol.interaction.Modify.handleDragEvent_ = function(evt) {
break;
}
geometry.setCoordinates(coordinates);
this.setGeometryCoordinates_(geometry, coordinates);
}
this.createOrUpdateVertexFeature_(vertex);
};
@@ -768,7 +817,7 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) {
return;
}
geometry.setCoordinates(coordinates);
this.setGeometryCoordinates_(geometry, coordinates);
var rTree = this.rBush_;
goog.asserts.assert(goog.isDef(segment), 'segment should be defined');
rTree.remove(segmentData);
@@ -874,7 +923,7 @@ ol.interaction.Modify.prototype.removeVertex_ = function() {
if (deleted) {
this.rBush_.remove(newSegment[0]);
this.rBush_.remove(newSegment[1]);
geometry.setCoordinates(coordinates);
this.setGeometryCoordinates_(geometry, coordinates);
goog.asserts.assert(newIndex >= 0, 'newIndex should be larger than 0');
var newSegmentData = /** @type {ol.interaction.SegmentDataType} */ ({
depth: segmentData.depth,
@@ -898,6 +947,19 @@ ol.interaction.Modify.prototype.removeVertex_ = function() {
};
/**
* @param {ol.geom.SimpleGeometry} geometry Geometry.
* @param {Array} coordinates Coordinates.
* @private
*/
ol.interaction.Modify.prototype.setGeometryCoordinates_ =
function(geometry, coordinates) {
this.changingFeature_ = true;
geometry.setCoordinates(coordinates);
this.changingFeature_ = false;
};
/**
* @param {ol.geom.SimpleGeometry} geometry Geometry.
* @param {number} index Index.