Merge pull request #13745 from hargasinski/fix-modifying-polygons

Fix modifying polygons with overlapping vertices
This commit is contained in:
Andreas Hocevar
2022-06-12 13:44:15 +02:00
committed by GitHub
2 changed files with 68 additions and 5 deletions

View File

@@ -1042,15 +1042,32 @@ class Modify extends PointerInteraction {
coordinatesEqual(segment[1], vertex) && coordinatesEqual(segment[1], vertex) &&
!componentSegments[uid][1] !componentSegments[uid][1]
) { ) {
// prevent dragging closed linestrings by the connecting node
if ( if (
(segmentDataMatch.geometry.getType() === GeometryType.LINE_STRING ||
segmentDataMatch.geometry.getType() ===
GeometryType.MULTI_LINE_STRING) &&
componentSegments[uid][0] && componentSegments[uid][0] &&
componentSegments[uid][0].index === 0 componentSegments[uid][0].index === 0
) { ) {
let coordinates = segmentDataMatch.geometry.getCoordinates();
switch (segmentDataMatch.geometry.getType()) {
// prevent dragging closed linestrings by the connecting node
case GeometryType.LINE_STRING:
case GeometryType.MULTI_LINE_STRING:
continue; continue;
// if dragging the first vertex of a polygon, ensure the other segment
// belongs to the closing vertex of the linear ring
case GeometryType.MULTI_POLYGON:
coordinates = coordinates[depth[1]];
/* falls through */
case GeometryType.POLYGON:
if (
segmentDataMatch.index !==
coordinates[depth[0]].length - 2
) {
continue;
}
break;
default:
// pass
}
} }
this.dragSegments_.push([segmentDataMatch, 1]); this.dragSegments_.push([segmentDataMatch, 1]);

View File

@@ -419,6 +419,52 @@ describe('ol.interaction.Modify', function () {
expect(lineFeature.getGeometry().getCoordinates()[2][2]).to.equal(30); expect(lineFeature.getGeometry().getCoordinates()[2][2]).to.equal(30);
expect(lineFeature.getGeometry().getCoordinates()[4][2]).to.equal(50); expect(lineFeature.getGeometry().getCoordinates()[4][2]).to.equal(50);
}); });
it('keeps polygon geometries valid', function () {
const overlappingVertexFeature = new Feature({
geometry: new Polygon([
[
[10, 20],
[0, 20],
[0, 0],
[20, 0],
[20, 20],
[10, 20],
[15, 15],
[5, 15],
[10, 20],
],
]),
});
features.length = 0;
features.push(overlappingVertexFeature);
const modify = new Modify({
features: new Collection(features),
});
map.addInteraction(modify);
let coords, exteriorRing;
coords = overlappingVertexFeature.getGeometry().getCoordinates();
exteriorRing = coords[0];
expect(exteriorRing.length).to.equal(9);
expect(exteriorRing[0]).to.eql(exteriorRing[exteriorRing.length - 1]);
// move the overlapping vertice
simulateEvent('pointermove', 10, -20, null, 0);
simulateEvent('pointerdown', 10, -20, null, 0);
simulateEvent('pointermove', 10, -25, null, 0);
simulateEvent('pointerdrag', 10, -25, null, 0);
simulateEvent('pointerup', 10, -25, null, 0);
coords = overlappingVertexFeature.getGeometry().getCoordinates();
exteriorRing = coords[0];
expect(exteriorRing.length).to.equal(9);
expect(exteriorRing[0]).to.eql([10, 25]);
expect(exteriorRing[0]).to.eql(exteriorRing[exteriorRing.length - 1]);
});
}); });
describe('vertex insertion', function () { describe('vertex insertion', function () {