diff --git a/examples/modify-test.js b/examples/modify-test.js
index 5c28dec341..0b7c31bf7f 100644
--- a/examples/modify-test.js
+++ b/examples/modify-test.js
@@ -222,7 +222,13 @@ var select = new ol.interaction.Select({
var modify = new ol.interaction.Modify({
features: select.getFeatures(),
- style: overlayStyle
+ style: overlayStyle,
+ insertVertexCondition: function() {
+ // prevent new vertices to be added to the polygons
+ return !this.features_.getArray().every(function(feature) {
+ return feature.getGeometry().getType().match(/Polygon/);
+ });
+ }
});
var map = new ol.Map({
diff --git a/externs/olx.js b/externs/olx.js
index a47e678e71..92e0314713 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -3164,12 +3164,15 @@ olx.interaction.KeyboardZoomOptions.prototype.delta;
/**
- * @typedef {{condition: (ol.EventsConditionType|undefined),
+ * @typedef {{
+ * condition: (ol.EventsConditionType|undefined),
* deleteCondition: (ol.EventsConditionType|undefined),
+ * insertVertexCondition: (ol.EventsConditionType|undefined),
* pixelTolerance: (number|undefined),
* style: (ol.style.Style|Array.
|ol.StyleFunction|undefined),
* features: ol.Collection.,
- * wrapX: (boolean|undefined)}}
+ * wrapX: (boolean|undefined)
+ * }}
*/
olx.interaction.ModifyOptions;
@@ -3196,6 +3199,16 @@ olx.interaction.ModifyOptions.prototype.condition;
olx.interaction.ModifyOptions.prototype.deleteCondition;
+/**
+ * A function that takes an {@link ol.MapBrowserEvent} and returns a boolean
+ * to indicate whether a new vertex can be added to the sketch features.
+ * Default is {@link ol.events.condition.always}
+ * @type {ol.EventsConditionType|undefined}
+ * @api
+ */
+olx.interaction.ModifyOptions.prototype.insertVertexCondition;
+
+
/**
* Pixel tolerance for considering the pointer close enough to a segment or
* vertex for editing. Default is `10`.
diff --git a/src/ol/interaction/modify.js b/src/ol/interaction/modify.js
index b9113451cd..54b9b79afe 100644
--- a/src/ol/interaction/modify.js
+++ b/src/ol/interaction/modify.js
@@ -67,6 +67,13 @@ ol.interaction.Modify = function(options) {
this.deleteCondition_ = options.deleteCondition ?
options.deleteCondition : this.defaultDeleteCondition_;
+ /**
+ * @type {ol.EventsConditionType}
+ * @private
+ */
+ this.insertVertexCondition_ = options.insertVertexCondition ?
+ options.insertVertexCondition : ol.events.condition.always;
+
/**
* Editing vertex.
* @type {ol.Feature}
@@ -600,7 +607,7 @@ ol.interaction.Modify.handleDownEvent_ = function(evt) {
this.dragSegments_.push([segmentDataMatch, 1]);
componentSegments[uid][1] = segmentDataMatch;
- } else if (ol.getUid(segment) in this.vertexSegments_ &&
+ } else if (this.insertVertexCondition_(evt) && ol.getUid(segment) in this.vertexSegments_ &&
(!componentSegments[uid][0] && !componentSegments[uid][1])) {
insertVertices.push([segmentDataMatch, vertex]);
}
diff --git a/test/spec/ol/interaction/modify.test.js b/test/spec/ol/interaction/modify.test.js
index 8ab79812b3..f22a10a9da 100644
--- a/test/spec/ol/interaction/modify.test.js
+++ b/test/spec/ol/interaction/modify.test.js
@@ -559,6 +559,40 @@ describe('ol.interaction.Modify', function() {
});
});
+ describe('insertVertexCondition', function() {
+ it('calls the callback function', function() {
+ var listenerSpy = sinon.spy(function(event) {
+ return false;
+ });
+
+ var modify = new ol.interaction.Modify({
+ features: new ol.Collection(features),
+ insertVertexCondition: listenerSpy
+ });
+ map.addInteraction(modify);
+ var feature = features[0];
+
+ // move first vertex
+ simulateEvent('pointermove', 0, 0, false, 0);
+ simulateEvent('pointerdown', 0, 0, false, 0);
+ simulateEvent('pointermove', -10, -10, false, 0);
+ simulateEvent('pointerdrag', -10, -10, false, 0);
+ simulateEvent('pointerup', -10, -10, false, 0);
+
+ expect(listenerSpy.callCount).to.be(0);
+ expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
+
+ // try to add vertex
+ simulateEvent('pointerdown', 40, -20, false, 0);
+ simulateEvent('pointerup', 40, -20, false, 0);
+ simulateEvent('click', 40, -20, false, 0);
+ simulateEvent('singleclick', 40, -20, false, 0);
+
+ expect(listenerSpy.callCount).to.be(1);
+ expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
+ });
+ });
+
describe('handle feature change', function() {
var getListeners;