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;
|
this.modifiable_ = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ol.Coordinate}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.lastVertexCoordinate_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {ol.Pixel}
|
* @type {ol.Pixel}
|
||||||
* @private
|
* @private
|
||||||
@@ -401,6 +407,7 @@ ol.interaction.Modify.prototype.handlePointerDown = function(evt) {
|
|||||||
for (i = insertVertices.length - 1; i >= 0; --i) {
|
for (i = insertVertices.length - 1; i >= 0; --i) {
|
||||||
this.insertVertex_.apply(this, insertVertices[i]);
|
this.insertVertex_.apply(this, insertVertices[i]);
|
||||||
}
|
}
|
||||||
|
this.lastVertexCoordinate_ = goog.array.clone(vertex);
|
||||||
}
|
}
|
||||||
return this.modifiable_;
|
return this.modifiable_;
|
||||||
};
|
};
|
||||||
@@ -457,11 +464,18 @@ ol.interaction.Modify.prototype.handlePointerDrag = function(evt) {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.interaction.Modify.prototype.handlePointerUp = function(evt) {
|
ol.interaction.Modify.prototype.handlePointerUp = function(evt) {
|
||||||
var segmentData;
|
var geometry = this.vertexFeature_.getGeometry();
|
||||||
for (var i = this.dragSegments_.length - 1; i >= 0; --i) {
|
goog.asserts.assertInstanceof(geometry, ol.geom.Point);
|
||||||
segmentData = this.dragSegments_[i][0];
|
if (goog.array.equals(this.lastVertexCoordinate_,
|
||||||
this.rBush_.update(ol.extent.boundingExtent(segmentData.segment),
|
geometry.getCoordinates())) {
|
||||||
segmentData);
|
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;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -599,23 +613,8 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) {
|
|||||||
var rTree = this.rBush_;
|
var rTree = this.rBush_;
|
||||||
goog.asserts.assert(goog.isDef(segment));
|
goog.asserts.assert(goog.isDef(segment));
|
||||||
rTree.remove(segmentData);
|
rTree.remove(segmentData);
|
||||||
var uid = goog.getUid(feature);
|
goog.asserts.assert(goog.isDef(index));
|
||||||
var segmentDataMatches = [];
|
this.updateSegmentIndices_(geometry, index, depth, 1);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var newSegmentData = /** @type {ol.interaction.SegmentDataType} */ ({
|
var newSegmentData = /** @type {ol.interaction.SegmentDataType} */ ({
|
||||||
segment: [segment[0], vertex],
|
segment: [segment[0], vertex],
|
||||||
feature: feature,
|
feature: feature,
|
||||||
@@ -638,3 +637,113 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) {
|
|||||||
newSegmentData2);
|
newSegmentData2);
|
||||||
this.dragSegments_.push([newSegmentData2, 0]);
|
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