diff --git a/src/ol/interaction/Modify.js b/src/ol/interaction/Modify.js index 24dbde582b..d27ed3a154 100644 --- a/src/ol/interaction/Modify.js +++ b/src/ol/interaction/Modify.js @@ -112,7 +112,10 @@ const ModifyEventType = { * be the affected vertex, for circles a point along the circle, and for points the actual * point. If not configured, the default edit style is used (see {@link module:ol/style}). * When using a style function, the point feature passed to the function will have a `features` - * property - an array whose entries are the features that are being modified. + * property - an array whose entries are the features that are being modified, and a `geometries` + * property - an array whose entries are the geometries that are being modified. Both arrays are + * in the same order. The `geometries` are only useful when modifying geometry collections, where + * the geometry will be the particular geometry from the collection that is being modified. * @property {VectorSource} [source] The vector source with * features to modify. If a vector source is not provided, a layer or feature collection * must be provided with the `layer` or `features` option. @@ -769,10 +772,11 @@ class Modify extends PointerInteraction { /** * @param {import("../coordinate.js").Coordinate} coordinates Coordinates. * @param {Array} features The features being modified. + * @param {Array} geometries The geometries being modified. * @return {Feature} Vertex feature. * @private */ - createOrUpdateVertexFeature_(coordinates, features) { + createOrUpdateVertexFeature_(coordinates, features, geometries) { let vertexFeature = this.vertexFeature_; if (!vertexFeature) { vertexFeature = new Feature(new Point(coordinates)); @@ -783,6 +787,7 @@ class Modify extends PointerInteraction { geometry.setCoordinates(coordinates); } vertexFeature.set('features', features); + vertexFeature.set('geometries', geometries); return vertexFeature; } @@ -836,6 +841,7 @@ class Modify extends PointerInteraction { evt.coordinate[1] + this.delta_[1], ]; const features = []; + const geometries = []; for (let i = 0, ii = this.dragSegments_.length; i < ii; ++i) { const dragSegment = this.dragSegments_[i]; const segmentData = dragSegment[0]; @@ -843,8 +849,11 @@ class Modify extends PointerInteraction { if (features.indexOf(feature) === -1) { features.push(feature); } - const depth = segmentData.depth; const geometry = segmentData.geometry; + if (geometries.indexOf(geometry) === -1) { + geometries.push(geometry); + } + const depth = segmentData.depth; let coordinates; const segment = segmentData.segment; const index = dragSegment[1]; @@ -922,7 +931,7 @@ class Modify extends PointerInteraction { this.setGeometryCoordinates_(geometry, coordinates); } } - this.createOrUpdateVertexFeature_(vertex, features); + this.createOrUpdateVertexFeature_(vertex, features, geometries); } /** @@ -1170,7 +1179,11 @@ class Modify extends PointerInteraction { node.index === CIRCLE_CIRCUMFERENCE_INDEX ) { this.snappedToVertex_ = true; - this.createOrUpdateVertexFeature_(vertex, [node.feature]); + this.createOrUpdateVertexFeature_( + vertex, + [node.feature], + [node.geometry] + ); } else { const pixel1 = map.getPixelFromCoordinate(closestSegment[0]); const pixel2 = map.getPixelFromCoordinate(closestSegment[1]); @@ -1184,7 +1197,11 @@ class Modify extends PointerInteraction { ? closestSegment[1] : closestSegment[0]; } - this.createOrUpdateVertexFeature_(vertex, [node.feature]); + this.createOrUpdateVertexFeature_( + vertex, + [node.feature], + [node.geometry] + ); const geometries = {}; geometries[getUid(geometry)] = true; for (let i = 1, ii = nodes.length; i < ii; ++i) { diff --git a/test/spec/ol/interaction/modify.test.js b/test/spec/ol/interaction/modify.test.js index 0bd406eb74..3b9b383d35 100644 --- a/test/spec/ol/interaction/modify.test.js +++ b/test/spec/ol/interaction/modify.test.js @@ -8,11 +8,12 @@ import Map from '../../../../src/ol/Map.js'; import MapBrowserEvent from '../../../../src/ol/MapBrowserEvent.js'; import Modify, {ModifyEvent} from '../../../../src/ol/interaction/Modify.js'; import Point from '../../../../src/ol/geom/Point.js'; -import Polygon from '../../../../src/ol/geom/Polygon.js'; +import Polygon, {fromExtent} from '../../../../src/ol/geom/Polygon.js'; import Snap from '../../../../src/ol/interaction/Snap.js'; import VectorLayer from '../../../../src/ol/layer/Vector.js'; import VectorSource from '../../../../src/ol/source/Vector.js'; import View from '../../../../src/ol/View.js'; +import {MultiPoint} from '../../../../src/ol/geom.js'; import { clearUserProjection, setUserProjection, @@ -943,9 +944,10 @@ describe('ol.interaction.Modify', function () { }); describe('Vertex feature', function () { - it('tracks features and removes the vertexFeature on deactivation', function () { + it('tracks features and geometries and removes the vertexFeature on deactivation', function () { + const collection = new Collection(features); const modify = new Modify({ - features: new Collection(features), + features: collection, }); map.addInteraction(modify); expect(modify.vertexFeature_).to.be(null); @@ -953,9 +955,49 @@ describe('ol.interaction.Modify', function () { simulateEvent('pointermove', 10, -20, null, 0); expect(modify.vertexFeature_).to.not.be(null); expect(modify.vertexFeature_.get('features').length).to.be(1); + expect(modify.vertexFeature_.get('geometries').length).to.be(1); modify.setActive(false); expect(modify.vertexFeature_).to.be(null); + map.removeInteraction(modify); + }); + + it('tracks features and geometries - multi geometry', function () { + const collection = new Collection(); + const modify = new Modify({ + features: collection, + }); + map.addInteraction(modify); + const feature = new Feature( + new MultiPoint([ + [10, 10], + [10, 20], + ]) + ); + collection.push(feature); + simulateEvent('pointermove', 10, -20, null, 0); + expect(modify.vertexFeature_.get('features')[0]).to.eql(feature); + expect(modify.vertexFeature_.get('geometries')[0]).to.eql( + feature.getGeometry() + ); + map.removeInteraction(modify); + }); + + it('tracks features and geometries - geometry collection', function () { + const collection = new Collection(); + const modify = new Modify({ + features: collection, + }); + map.addInteraction(modify); + const feature = new Feature( + new GeometryCollection([fromExtent([0, 0, 10, 10]), new Point([5, 5])]) + ); + collection.push(feature); + simulateEvent('pointermove', 5, -5, null, 0); + expect(modify.vertexFeature_.get('features')[0]).to.eql(feature); + expect(modify.vertexFeature_.get('geometries')[0]).to.eql( + feature.getGeometry().getGeometriesArray()[1] + ); }); });