diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index f3b1a22684..717416a1ba 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -487,8 +487,12 @@ /** * @typedef {Object} olx.interaction.ModifyOptions + * @property {ol.events.ConditionType|undefined} deleteCondition Condition that + * determines which event results in a vertex deletion. Default is a + * `singleclick` event with no modifier keys. * @property {number|undefined} pixelTolerance Pixel tolerance for considering - * the pointer close enough to a vertex for editing. Default is 10 pixels. + * the pointer close enough to a segment or vertex for editing. Default is + * 10 pixels. * @property {ol.style.Style|Array.|ol.feature.StyleFunction|undefined} style FeatureOverlay style. * @property {ol.Collection} features The features the interaction works on. */ diff --git a/src/ol/events/condition.js b/src/ol/events/condition.js index f04add9eaa..285298b486 100644 --- a/src/ol/events/condition.js +++ b/src/ol/events/condition.js @@ -66,7 +66,7 @@ ol.events.condition.never = goog.functions.FALSE; /** * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event. - * @return {boolean} True if the event is a click event. + * @return {boolean} True if the event is a `singleclick` event. * @todo stability experimental */ ol.events.condition.singleClick = function(mapBrowserEvent) { diff --git a/src/ol/interaction/modifyinteraction.js b/src/ol/interaction/modifyinteraction.js index d133822d22..75979b419e 100644 --- a/src/ol/interaction/modifyinteraction.js +++ b/src/ol/interaction/modifyinteraction.js @@ -3,6 +3,7 @@ goog.provide('ol.interaction.Modify'); goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.events'); +goog.require('goog.functions'); goog.require('ol.Collection'); goog.require('ol.CollectionEventType'); goog.require('ol.Feature'); @@ -10,6 +11,7 @@ goog.require('ol.FeatureOverlay'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.ViewHint'); goog.require('ol.coordinate'); +goog.require('ol.events.condition'); goog.require('ol.extent'); goog.require('ol.feature'); goog.require('ol.geom.GeometryType'); @@ -44,6 +46,16 @@ ol.interaction.Modify = function(options) { goog.base(this); + /** + * @type {ol.events.ConditionType} + * @private + */ + this.deleteCondition_ = goog.isDef(options.deleteCondition) ? + options.deleteCondition : + /** @type {ol.events.ConditionType} */ (goog.functions.and( + ol.events.condition.noModifierKeys, + ol.events.condition.singleClick)); + /** * Editing vertex. * @type {ol.Feature} @@ -58,18 +70,6 @@ ol.interaction.Modify = function(options) { */ this.vertexSegments_ = null; - /** - * @type {boolean} - * @private - */ - this.modifiable_ = false; - - /** - * @type {ol.Coordinate} - * @private - */ - this.lastVertexCoordinate_; - /** * @type {ol.Pixel} * @private @@ -90,6 +90,12 @@ ol.interaction.Modify = function(options) { this.pixelTolerance_ = goog.isDef(options.pixelTolerance) ? options.pixelTolerance : 10; + /** + * @type {boolean} + * @private + */ + this.snappedToVertex_ = false; + /** * @type {Array} * @private @@ -404,9 +410,8 @@ ol.interaction.Modify.prototype.handlePointerDown = function(evt) { for (i = insertVertices.length - 1; i >= 0; --i) { this.insertVertex_.apply(this, insertVertices[i]); } - this.lastVertexCoordinate_ = goog.array.clone(vertex); } - return this.modifiable_; + return !goog.isNull(this.vertexFeature_); }; @@ -461,20 +466,12 @@ ol.interaction.Modify.prototype.handlePointerDrag = function(evt) { * @inheritDoc */ ol.interaction.Modify.prototype.handlePointerUp = function(evt) { - var geometry = this.vertexFeature_.getGeometry(); - goog.asserts.assertInstanceof(geometry, ol.geom.Point); - if (goog.array.equals(this.lastVertexCoordinate_, - geometry.getCoordinates())) { - this.removeVertex_(); - } else { - var segmentData; - for (var i = this.dragSegments_.length - 1; i >= 0; --i) { - segmentData = this.dragSegments_[i][0]; - this.rBush_.update(ol.extent.boundingExtent(segmentData.segment), - segmentData); - } + var segmentData; + for (var i = this.dragSegments_.length - 1; i >= 0; --i) { + segmentData = this.dragSegments_[i][0]; + this.rBush_.update(ol.extent.boundingExtent(segmentData.segment), + segmentData); } - return false; }; @@ -483,12 +480,18 @@ ol.interaction.Modify.prototype.handlePointerUp = function(evt) { */ ol.interaction.Modify.prototype.handleMapBrowserEvent = function(mapBrowserEvent) { + var handled; if (!mapBrowserEvent.map.getView().getHints()[ol.ViewHint.INTERACTING] && mapBrowserEvent.type == ol.MapBrowserEvent.EventType.POINTERMOVE) { this.handlePointerMove_(mapBrowserEvent); } - return (goog.base(this, 'handleMapBrowserEvent', mapBrowserEvent) && - !this.modifiable_); + if (!goog.isNull(this.vertexFeature_) && this.snappedToVertex_ && + this.deleteCondition_(mapBrowserEvent)) { + var geometry = this.vertexFeature_.getGeometry(); + goog.asserts.assertInstanceof(geometry, ol.geom.Point); + handled = this.removeVertex_(); + } + return goog.base(this, 'handleMapBrowserEvent', mapBrowserEvent) && !handled; }; @@ -520,7 +523,6 @@ ol.interaction.Modify.prototype.handlePointerAtPixel_ = function(pixel, map) { [pixel[0] + this.pixelTolerance_, pixel[1] - this.pixelTolerance_]); var box = ol.extent.boundingExtent([lowerLeft, upperRight]); - this.modifiable_ = false; var rBush = this.rBush_; var nodes = rBush.getInExtent(box); if (nodes.length > 0) { @@ -537,7 +539,8 @@ ol.interaction.Modify.prototype.handlePointerAtPixel_ = function(pixel, map) { var squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1); var squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2); var dist = Math.sqrt(Math.min(squaredDist1, squaredDist2)); - if (dist <= 10) { + this.snappedToVertex_ = dist <= this.pixelTolerance_; + if (this.snappedToVertex_) { vertex = squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0]; } @@ -557,7 +560,6 @@ ol.interaction.Modify.prototype.handlePointerAtPixel_ = function(pixel, map) { } } this.vertexSegments_ = vertexSegments; - this.modifiable_ = true; return; } } @@ -638,12 +640,14 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) { /** * Removes a vertex from all matching features. + * @return {boolean} True when a vertex was removed. * @private */ ol.interaction.Modify.prototype.removeVertex_ = function() { var dragSegments = this.dragSegments_; var segmentsByFeature = {}; - var component, coordinates, deleted, dragSegment, geometry, i, index, left; + var deleted = false; + var component, coordinates, dragSegment, geometry, i, index, left; var newIndex, newSegment, right, segmentData, uid; for (i = dragSegments.length - 1; i >= 0; --i) { dragSegment = dragSegments[i]; @@ -724,6 +728,15 @@ ol.interaction.Modify.prototype.removeVertex_ = function() { } } } + return deleted; +}; + + +/** + * @inheritDoc + */ +ol.interaction.Modify.prototype.shouldStopEvent = function(handled) { + return handled; };