diff --git a/externs/olx.js b/externs/olx.js
index 09e1f63b39..c3fec4bade 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -2585,6 +2585,7 @@ olx.interaction.DragZoomOptions.prototype.out;
* type: ol.geom.GeometryType,
* maxPoints: (number|undefined),
* minPoints: (number|undefined),
+ * finishCondition: (ol.events.ConditionType|undefined),
* style: (ol.style.Style|Array.
|ol.style.StyleFunction|undefined),
* geometryFunction: (ol.interaction.DrawGeometryFunctionType|undefined),
* geometryName: (string|undefined),
@@ -2659,6 +2660,15 @@ olx.interaction.DrawOptions.prototype.maxPoints;
olx.interaction.DrawOptions.prototype.minPoints;
+/**
+ * A function that takes an {@link ol.MapBrowserEvent} and returns a boolean
+ * to indicate whether the drawing can be finished.
+ * @type {ol.events.ConditionType|undefined}
+ * @api
+ */
+olx.interaction.DrawOptions.prototype.finishCondition;
+
+
/**
* Style for sketch features.
* @type {ol.style.Style|Array.|ol.style.StyleFunction|undefined}
diff --git a/src/ol/interaction/drawinteraction.js b/src/ol/interaction/drawinteraction.js
index 0b38d43c77..c6e5bce257 100644
--- a/src/ol/interaction/drawinteraction.js
+++ b/src/ol/interaction/drawinteraction.js
@@ -160,6 +160,13 @@ ol.interaction.Draw = function(options) {
*/
this.maxPoints_ = options.maxPoints ? options.maxPoints : Infinity;
+ /**
+ * A function to decide if a potential finish coordinate is permissable
+ * @private
+ * @type {ol.events.ConditionType}
+ */
+ this.finishCondition_ = options.finishCondition ? options.finishCondition : goog.functions.TRUE;
+
var geometryFunction = options.geometryFunction;
if (!geometryFunction) {
if (this.type_ === ol.geom.GeometryType.CIRCLE) {
@@ -404,7 +411,9 @@ ol.interaction.Draw.handleUpEvent_ = function(event) {
} else if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
this.finishDrawing();
} else if (this.atFinish_(event)) {
- this.finishDrawing();
+ if (this.finishCondition_(event)) {
+ this.finishDrawing();
+ }
} else {
this.addToDrawing_(event);
}
diff --git a/test/spec/ol/interaction/drawinteraction.test.js b/test/spec/ol/interaction/drawinteraction.test.js
index 1a491caddc..1925892958 100644
--- a/test/spec/ol/interaction/drawinteraction.test.js
+++ b/test/spec/ol/interaction/drawinteraction.test.js
@@ -333,6 +333,55 @@ describe('ol.interaction.Draw', function() {
});
+ describe('drawing with a finishCondition', function() {
+ beforeEach(function() {
+ var draw = new ol.interaction.Draw({
+ source: source,
+ type: ol.geom.GeometryType.LINE_STRING,
+ finishCondition: function(event) {
+ if (ol.array.equals(event.coordinate,[30,-20])) {
+ return true;
+ }
+ return false;
+ }
+ });
+ map.addInteraction(draw);
+ });
+
+ it('draws a linestring failing to finish it first, the finishes it', function() {
+ var features;
+
+ // first point
+ simulateEvent('pointermove', 10, 20);
+ simulateEvent('pointerdown', 10, 20);
+ simulateEvent('pointerup', 10, 20);
+
+ // second point
+ simulateEvent('pointermove', 40, 30);
+ simulateEvent('pointerdown', 40, 30);
+ simulateEvent('pointerup', 40, 30);
+
+ // try to finish on this point
+ simulateEvent('pointerdown', 40, 30);
+ simulateEvent('pointerup', 40, 30);
+
+ features = source.getFeatures();
+ expect(features).to.have.length(0);
+
+ // third point
+ simulateEvent('pointermove', 30, 20);
+ simulateEvent('pointerdown', 30, 20);
+ simulateEvent('pointerup', 30, 20);
+
+ // finish on this point
+ simulateEvent('pointerdown', 30, 20);
+ simulateEvent('pointerup', 30, 20);
+
+ features = source.getFeatures();
+ expect(features).to.have.length(1);
+ });
+ });
+
describe('drawing multi-linestrings', function() {
beforeEach(function() {
@@ -811,6 +860,7 @@ describe('ol.interaction.Draw', function() {
});
});
+goog.require('ol.array');
goog.require('ol.events');
goog.require('ol.Feature');
goog.require('ol.Map');