Add a way to delete vertices with the Modify interaction
After this change, vertices can be deleted by simply clicking on them. This is the same behaviour as e.g. in geojson.io.
This commit is contained in:
@@ -63,6 +63,12 @@ ol.interaction.Modify = function(options) {
|
||||
*/
|
||||
this.modifiable_ = false;
|
||||
|
||||
/**
|
||||
* @type {ol.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.lastVertexCoordinate_;
|
||||
|
||||
/**
|
||||
* @type {ol.Pixel}
|
||||
* @private
|
||||
@@ -401,6 +407,7 @@ ol.interaction.Modify.prototype.handlePointerDown = function(evt) {
|
||||
for (i = insertVertices.length - 1; i >= 0; --i) {
|
||||
this.insertVertex_.apply(this, insertVertices[i]);
|
||||
}
|
||||
this.lastVertexCoordinate_ = goog.array.clone(vertex);
|
||||
}
|
||||
return this.modifiable_;
|
||||
};
|
||||
@@ -457,11 +464,18 @@ ol.interaction.Modify.prototype.handlePointerDrag = function(evt) {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.Modify.prototype.handlePointerUp = function(evt) {
|
||||
var segmentData;
|
||||
for (var i = this.dragSegments_.length - 1; i >= 0; --i) {
|
||||
segmentData = this.dragSegments_[i][0];
|
||||
this.rBush_.update(ol.extent.boundingExtent(segmentData.segment),
|
||||
segmentData);
|
||||
var geometry = this.vertexFeature_.getGeometry();
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Point);
|
||||
if (goog.array.equals(this.lastVertexCoordinate_,
|
||||
geometry.getCoordinates())) {
|
||||
this.removeVertex_();
|
||||
} else {
|
||||
var segmentData;
|
||||
for (var i = this.dragSegments_.length - 1; i >= 0; --i) {
|
||||
segmentData = this.dragSegments_[i][0];
|
||||
this.rBush_.update(ol.extent.boundingExtent(segmentData.segment),
|
||||
segmentData);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -599,23 +613,8 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) {
|
||||
var rTree = this.rBush_;
|
||||
goog.asserts.assert(goog.isDef(segment));
|
||||
rTree.remove(segmentData);
|
||||
var uid = goog.getUid(feature);
|
||||
var segmentDataMatches = [];
|
||||
this.rBush_.forEachInExtent(geometry.getExtent(),
|
||||
function(segmentData) {
|
||||
if (goog.getUid(segmentData.feature) === uid) {
|
||||
segmentDataMatches.push(segmentData);
|
||||
}
|
||||
});
|
||||
for (var i = 0, ii = segmentDataMatches.length; i < ii; ++i) {
|
||||
var segmentDataMatch = segmentDataMatches[i];
|
||||
if (segmentDataMatch.geometry === geometry &&
|
||||
(!goog.isDef(depth) ||
|
||||
goog.array.equals(segmentDataMatch.depth, depth)) &&
|
||||
segmentDataMatch.index > index) {
|
||||
++segmentDataMatch.index;
|
||||
}
|
||||
}
|
||||
goog.asserts.assert(goog.isDef(index));
|
||||
this.updateSegmentIndices_(geometry, index, depth, 1);
|
||||
var newSegmentData = /** @type {ol.interaction.SegmentDataType} */ ({
|
||||
segment: [segment[0], vertex],
|
||||
feature: feature,
|
||||
@@ -638,3 +637,113 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) {
|
||||
newSegmentData2);
|
||||
this.dragSegments_.push([newSegmentData2, 0]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a vertex from all matching features.
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.Modify.prototype.removeVertex_ = function() {
|
||||
var dragSegments = this.dragSegments_;
|
||||
var segmentsByFeature = {};
|
||||
var component, coordinates, deleted, dragSegment, geometry, i, index, left;
|
||||
var newIndex, newSegment, right, segmentData, uid;
|
||||
for (i = dragSegments.length - 1; i >= 0; --i) {
|
||||
dragSegment = dragSegments[i];
|
||||
segmentData = dragSegment[0];
|
||||
geometry = segmentData.geometry;
|
||||
coordinates = geometry.getCoordinates();
|
||||
uid = goog.getUid(segmentData.feature);
|
||||
left = right = index = undefined;
|
||||
if (dragSegment[1] == 0) {
|
||||
right = segmentData;
|
||||
index = segmentData.index;
|
||||
} else if (dragSegment[1] == 1) {
|
||||
left = segmentData;
|
||||
index = segmentData.index + 1;
|
||||
}
|
||||
if (!(uid in segmentsByFeature)) {
|
||||
segmentsByFeature[uid] = [left, right, index];
|
||||
}
|
||||
newSegment = segmentsByFeature[uid];
|
||||
if (goog.isDef(left)) {
|
||||
newSegment[0] = left;
|
||||
}
|
||||
if (goog.isDef(right)) {
|
||||
newSegment[1] = right;
|
||||
}
|
||||
if (goog.isDef(newSegment[0]) && goog.isDef(newSegment[1])) {
|
||||
component = coordinates;
|
||||
deleted = false;
|
||||
newIndex = index - 1;
|
||||
switch (geometry.getType()) {
|
||||
case ol.geom.GeometryType.MULTI_LINE_STRING:
|
||||
coordinates[segmentData.depth[0]].splice(index, 1);
|
||||
deleted = true;
|
||||
break;
|
||||
case ol.geom.GeometryType.LINE_STRING:
|
||||
coordinates.splice(index, 1);
|
||||
deleted = true;
|
||||
break;
|
||||
case ol.geom.GeometryType.MULTI_POLYGON:
|
||||
component = component[segmentData.depth[1]];
|
||||
case ol.geom.GeometryType.POLYGON:
|
||||
component = component[segmentData.depth[0]];
|
||||
if (component.length > 4) {
|
||||
if (index == component.length - 1) {
|
||||
index = 0;
|
||||
}
|
||||
component.splice(index, 1);
|
||||
deleted = true;
|
||||
if (index === 0) {
|
||||
// close the ring again
|
||||
component.pop();
|
||||
component.push(component[0]);
|
||||
newIndex = component.length - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (deleted) {
|
||||
this.rBush_.remove(newSegment[0]);
|
||||
this.rBush_.remove(newSegment[1]);
|
||||
geometry.setCoordinates(coordinates);
|
||||
goog.asserts.assert(newIndex >= 0);
|
||||
var newSegmentData = /** @type {ol.interaction.SegmentDataType} */ ({
|
||||
depth: segmentData.depth,
|
||||
feature: segmentData.feature,
|
||||
geometry: segmentData.geometry,
|
||||
index: newIndex,
|
||||
segment: [newSegment[0].segment[0], newSegment[1].segment[1]]
|
||||
});
|
||||
this.rBush_.insert(ol.extent.boundingExtent(newSegmentData.segment),
|
||||
newSegmentData);
|
||||
this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);
|
||||
|
||||
this.overlay_.removeFeature(this.vertexFeature_);
|
||||
this.vertexFeature_ = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.geom.SimpleGeometry} geometry Geometry.
|
||||
* @param {number} index Index.
|
||||
* @param {Array.<number>|undefined} depth Depth.
|
||||
* @param {number} delta Delta (1 or -1).
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.Modify.prototype.updateSegmentIndices_ = function(
|
||||
geometry, index, depth, delta) {
|
||||
this.rBush_.forEachInExtent(geometry.getExtent(), function(segmentDataMatch) {
|
||||
if (segmentDataMatch.geometry === geometry &&
|
||||
(!goog.isDef(depth) ||
|
||||
goog.array.equals(segmentDataMatch.depth, depth)) &&
|
||||
segmentDataMatch.index > index) {
|
||||
segmentDataMatch.index += delta;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user