Allow to delete the starting or ending vertex

* Allow to delete the starting or ending vertex

* Test if starting and ending vertex are removed
This commit is contained in:
Renaud Michaëlis
2016-04-06 13:47:37 +02:00
committed by Andreas Hocevar
parent 18e9ff98ee
commit 53a9341ef0
2 changed files with 148 additions and 57 deletions

View File

@@ -883,93 +883,111 @@ ol.interaction.Modify.prototype.removeVertex_ = function() {
var dragSegments = this.dragSegments_;
var segmentsByFeature = {};
var component, coordinates, dragSegment, geometry, i, index, left;
var newIndex, newSegment, right, segmentData, uid, deleted;
var newIndex, right, segmentData, uid, deleted;
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);
if (segmentData.depth) {
// separate feature components
uid += '-' + segmentData.depth.join('-');
}
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];
segmentsByFeature[uid] = {};
}
newSegment = segmentsByFeature[uid];
if (dragSegment[1] === 0) {
segmentsByFeature[uid].right = segmentData;
segmentsByFeature[uid].index = segmentData.index;
} else if (dragSegment[1] == 1) {
segmentsByFeature[uid].left = segmentData;
segmentsByFeature[uid].index = segmentData.index + 1;
}
}
for (uid in segmentsByFeature) {
right = segmentsByFeature[uid].right;
left = segmentsByFeature[uid].left;
index = segmentsByFeature[uid].index;
newIndex = index - 1;
if (left !== undefined) {
newSegment[0] = left;
segmentData = left;
} else {
segmentData = right;
}
if (right !== undefined) {
newSegment[1] = right;
if (newIndex < 0) {
newIndex = 0;
}
if (newSegment[0] !== undefined && newSegment[1] !== undefined) {
component = coordinates;
deleted = false;
newIndex = index - 1;
switch (geometry.getType()) {
case ol.geom.GeometryType.MULTI_LINE_STRING:
geometry = segmentData.geometry;
coordinates = geometry.getCoordinates();
component = coordinates;
deleted = false;
switch (geometry.getType()) {
case ol.geom.GeometryType.MULTI_LINE_STRING:
if (coordinates[segmentData.depth[0]].length > 2) {
coordinates[segmentData.depth[0]].splice(index, 1);
deleted = true;
break;
case ol.geom.GeometryType.LINE_STRING:
}
break;
case ol.geom.GeometryType.LINE_STRING:
if (coordinates.length > 2) {
coordinates.splice(index, 1);
deleted = true;
break;
case ol.geom.GeometryType.MULTI_POLYGON:
component = component[segmentData.depth[1]];
/* falls through */
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;
case ol.geom.GeometryType.MULTI_POLYGON:
component = component[segmentData.depth[1]];
/* falls through */
case ol.geom.GeometryType.POLYGON:
component = component[segmentData.depth[0]];
if (component.length > 4) {
if (index == component.length - 1) {
index = 0;
}
break;
default:
// pass
}
component.splice(index, 1);
deleted = true;
if (index === 0) {
// close the ring again
component.pop();
component.push(component[0]);
newIndex = component.length - 1;
}
}
break;
default:
// pass
}
if (deleted) {
this.rBush_.remove(newSegment[0]);
this.rBush_.remove(newSegment[1]);
this.setGeometryCoordinates_(geometry, coordinates);
if (deleted) {
this.setGeometryCoordinates_(geometry, coordinates);
var segments = [];
if (left !== undefined) {
this.rBush_.remove(left);
segments.push(left.segment[0]);
}
if (right !== undefined) {
this.rBush_.remove(right);
segments.push(right.segment[1]);
}
if (left !== undefined && right !== undefined) {
goog.asserts.assert(newIndex >= 0, 'newIndex should be larger than 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]]
segment: segments
});
this.rBush_.insert(ol.extent.boundingExtent(newSegmentData.segment),
newSegmentData);
this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);
if (this.vertexFeature_) {
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
}
this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);
if (this.vertexFeature_) {
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
}
}
return true;
};

View File

@@ -180,6 +180,78 @@ describe('ol.interaction.Modify', function() {
validateEvents(events, features);
});
it('deletes first vertex of a LineString', function() {
var lineFeature = new ol.Feature({
geometry: new ol.geom.LineString(
[[0, 0], [10, 20], [0, 40], [40, 40], [40, 0]]
)
});
features.length = 0;
features.push(lineFeature);
features.push(lineFeature.clone());
var first = features[0];
var firstRevision = first.getGeometry().getRevision();
var modify = new ol.interaction.Modify({
features: new ol.Collection(features)
});
map.addInteraction(modify);
var events = trackEvents(first, modify);
expect(first.getGeometry().getRevision()).to.equal(firstRevision);
expect(first.getGeometry().getCoordinates()).to.have.length(5);
simulateEvent('pointerdown', 0, 0, false, 0);
simulateEvent('pointerup', 0, 0, false, 0);
simulateEvent('click', 0, 0, false, 0);
simulateEvent('singleclick', 0, 0, false, 0);
expect(first.getGeometry().getRevision()).to.equal(firstRevision + 1);
expect(first.getGeometry().getCoordinates()).to.have.length(4);
expect(first.getGeometry().getCoordinates()[0][0]).to.equal(10);
expect(first.getGeometry().getCoordinates()[0][1]).to.equal(20);
validateEvents(events, features);
});
it('deletes last vertex of a LineString', function() {
var lineFeature = new ol.Feature({
geometry: new ol.geom.LineString(
[[0, 0], [10, 20], [0, 40], [40, 40], [40, 0]]
)
});
features.length = 0;
features.push(lineFeature);
features.push(lineFeature.clone());
var first = features[0];
var firstRevision = first.getGeometry().getRevision();
var modify = new ol.interaction.Modify({
features: new ol.Collection(features)
});
map.addInteraction(modify);
var events = trackEvents(first, modify);
expect(first.getGeometry().getRevision()).to.equal(firstRevision);
expect(first.getGeometry().getCoordinates()).to.have.length(5);
simulateEvent('pointerdown', 40, 0, false, 0);
simulateEvent('pointerup', 40, 0, false, 0);
simulateEvent('click', 40, 0, false, 0);
simulateEvent('singleclick', 40, 0, false, 0);
expect(first.getGeometry().getRevision()).to.equal(firstRevision + 1);
expect(first.getGeometry().getCoordinates()).to.have.length(4);
expect(first.getGeometry().getCoordinates()[3][0]).to.equal(40);
expect(first.getGeometry().getCoordinates()[3][1]).to.equal(40);
validateEvents(events, features);
});
});
describe('boundary modification', function() {
@@ -382,6 +454,7 @@ goog.require('ol.Map');
goog.require('ol.MapBrowserPointerEvent');
goog.require('ol.View');
goog.require('ol.events.condition');
goog.require('ol.geom.LineString');
goog.require('ol.geom.Point');
goog.require('ol.geom.Polygon');
goog.require('ol.interaction.Modify');