From 651c1aa6c479f01c931d7fa8cda83b0c372ea3f9 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 3 Dec 2020 19:10:57 +0100 Subject: [PATCH 1/4] Fix removeLastPoint when removing last point --- src/ol/interaction/Draw.js | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/ol/interaction/Draw.js b/src/ol/interaction/Draw.js index 5539a624cc..9ab8a24ff6 100644 --- a/src/ol/interaction/Draw.js +++ b/src/ol/interaction/Draw.js @@ -585,7 +585,7 @@ class Draw extends PointerInteraction { if (this.freehand_) { this.downPx_ = event.pixel; if (!this.finishCoordinate_) { - this.startDrawing_(event); + this.startDrawing_(event.coordinate); } return true; } else if (this.condition_(event)) { @@ -630,7 +630,7 @@ class Draw extends PointerInteraction { if (this.shouldHandle_) { if (!this.finishCoordinate_) { - this.startDrawing_(event); + this.startDrawing_(event.coordinate); if (this.mode_ === Mode.POINT) { this.finishDrawing(); } @@ -771,12 +771,11 @@ class Draw extends PointerInteraction { /** * Start the drawing. - * @param {import("../MapBrowserEvent.js").default} event Event. + * @param {import("../coordinate.js").Coordinate} start Start coordinate. * @private */ - startDrawing_(event) { - const start = event.coordinate; - const projection = event.map.getView().getProjection(); + startDrawing_(start) { + const projection = this.getMap().getView().getProjection(); this.finishCoordinate_ = start; if (this.mode_ === Mode.POINT) { this.sketchCoords_ = start.slice(); @@ -937,7 +936,7 @@ class Draw extends PointerInteraction { this.geometryFunction_(this.sketchCoords_, geometry, projection); } - if (coordinates.length === 0) { + if (coordinates.length === 1) { this.abortDrawing(); } @@ -1026,21 +1025,32 @@ class Draw extends PointerInteraction { * Append coordinates to the end of the geometry that is currently being drawn. * This can be used when drawing LineStrings or Polygons. Coordinates will * either be appended to the current LineString or the outer ring of the current - * Polygon. - * @param {!LineCoordType} coordinates Linear coordinates to be appended into + * Polygon. If no geometry is being drawn, a new one will be created. + * @param {!LineCoordType} coordinates Linear coordinates to be appended to * the coordinate array. * @api */ appendCoordinates(coordinates) { const mode = this.mode_; - let sketchCoords = []; + const newDrawing = !this.sketchFeature_; + if (newDrawing) { + this.startDrawing_(coordinates[0]); + } + /** @type {LineCoordType} */ + let sketchCoords; if (mode === Mode.LINE_STRING || mode === Mode.CIRCLE) { - sketchCoords = /** @type {LineCoordType} */ this.sketchCoords_; + sketchCoords = /** @type {LineCoordType} */ (this.sketchCoords_); } else if (mode === Mode.POLYGON) { sketchCoords = this.sketchCoords_ && this.sketchCoords_.length ? /** @type {PolyCoordType} */ (this.sketchCoords_)[0] : []; + } else { + return; + } + + if (newDrawing) { + sketchCoords.shift(); } // Remove last coordinate from sketch drawing (this coordinate follows cursor position) From ec53d4fc57ed03a91de6efdcf94ee9d498593ed0 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 3 Dec 2020 23:29:33 +0100 Subject: [PATCH 2/4] Remove no longer needed checks for coordinates.length --- examples/draw-shapes.js | 44 ++++++------ src/ol/interaction/Draw.js | 143 ++++++++++++++++++------------------- 2 files changed, 89 insertions(+), 98 deletions(-) diff --git a/examples/draw-shapes.js b/examples/draw-shapes.js index 5d7d013265..d652d81765 100644 --- a/examples/draw-shapes.js +++ b/examples/draw-shapes.js @@ -43,30 +43,28 @@ function addInteraction() { } else if (value === 'Star') { value = 'Circle'; geometryFunction = function (coordinates, geometry) { - if (coordinates.length) { - const center = coordinates[0]; - const last = coordinates[coordinates.length - 1]; - const dx = center[0] - last[0]; - const dy = center[1] - last[1]; - const radius = Math.sqrt(dx * dx + dy * dy); - const rotation = Math.atan2(dy, dx); - const newCoordinates = []; - const numPoints = 12; - for (let i = 0; i < numPoints; ++i) { - const angle = rotation + (i * 2 * Math.PI) / numPoints; - const fraction = i % 2 === 0 ? 1 : 0.5; - const offsetX = radius * fraction * Math.cos(angle); - const offsetY = radius * fraction * Math.sin(angle); - newCoordinates.push([center[0] + offsetX, center[1] + offsetY]); - } - newCoordinates.push(newCoordinates[0].slice()); - if (!geometry) { - geometry = new Polygon([newCoordinates]); - } else { - geometry.setCoordinates([newCoordinates]); - } - return geometry; + const center = coordinates[0]; + const last = coordinates[coordinates.length - 1]; + const dx = center[0] - last[0]; + const dy = center[1] - last[1]; + const radius = Math.sqrt(dx * dx + dy * dy); + const rotation = Math.atan2(dy, dx); + const newCoordinates = []; + const numPoints = 12; + for (let i = 0; i < numPoints; ++i) { + const angle = rotation + (i * 2 * Math.PI) / numPoints; + const fraction = i % 2 === 0 ? 1 : 0.5; + const offsetX = radius * fraction * Math.cos(angle); + const offsetY = radius * fraction * Math.sin(angle); + newCoordinates.push([center[0] + offsetX, center[1] + offsetY]); } + newCoordinates.push(newCoordinates[0].slice()); + if (!geometry) { + geometry = new Polygon([newCoordinates]); + } else { + geometry.setCoordinates([newCoordinates]); + } + return geometry; }; } draw = new Draw({ diff --git a/src/ol/interaction/Draw.js b/src/ol/interaction/Draw.js index 9ab8a24ff6..193240cb2e 100644 --- a/src/ol/interaction/Draw.js +++ b/src/ol/interaction/Draw.js @@ -59,7 +59,8 @@ import {squaredDistance as squaredCoordinateDistance} from '../coordinate.js'; * polygon rings and `2` for line strings. * @property {import("../events/condition.js").Condition} [finishCondition] A function * that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a - * boolean to indicate whether the drawing can be finished. + * boolean to indicate whether the drawing can be finished. Not used when drawing + * POINT or MULTI_POINT geometries. * @property {import("../style/Style.js").StyleLike} [style] * Style for sketch features. * @property {GeometryFunction} [geometryFunction] @@ -317,25 +318,20 @@ class Draw extends PointerInteraction { * @return {import("../geom/SimpleGeometry.js").default} A geometry. */ geometryFunction = function (coordinates, geometry, projection) { - if (coordinates.length) { - const circle = geometry - ? /** @type {Circle} */ (geometry) - : new Circle([NaN, NaN]); - const center = fromUserCoordinate(coordinates[0], projection); - const squaredLength = squaredCoordinateDistance( - center, - fromUserCoordinate( - coordinates[coordinates.length - 1], - projection - ) - ); - circle.setCenterAndRadius(center, Math.sqrt(squaredLength)); - const userProjection = getUserProjection(); - if (userProjection) { - circle.transform(projection, userProjection); - } - return circle; + const circle = geometry + ? /** @type {Circle} */ (geometry) + : new Circle([NaN, NaN]); + const center = fromUserCoordinate(coordinates[0], projection); + const squaredLength = squaredCoordinateDistance( + center, + fromUserCoordinate(coordinates[coordinates.length - 1], projection) + ); + circle.setCenterAndRadius(center, Math.sqrt(squaredLength)); + const userProjection = getUserProjection(); + if (userProjection) { + circle.transform(projection, userProjection); } + return circle; }; } else { let Constructor; @@ -895,7 +891,8 @@ class Draw extends PointerInteraction { } /** - * Remove last point of the feature currently being drawn. + * Remove last point of the feature currently being drawn. Does not do anything when + * drawing POINT or MULTI_POINT geometries. * @api */ removeLastPoint() { @@ -1150,34 +1147,32 @@ function getDefaultStyleFunction() { */ export function createRegularPolygon(opt_sides, opt_angle) { return function (coordinates, opt_geometry, projection) { - if (coordinates.length) { - const center = fromUserCoordinate( - /** @type {LineCoordType} */ (coordinates)[0], - projection - ); - const end = fromUserCoordinate( - /** @type {LineCoordType} */ (coordinates)[coordinates.length - 1], - projection - ); - const radius = Math.sqrt(squaredCoordinateDistance(center, end)); - const geometry = opt_geometry - ? /** @type {Polygon} */ (opt_geometry) - : fromCircle(new Circle(center), opt_sides); + const center = fromUserCoordinate( + /** @type {LineCoordType} */ (coordinates)[0], + projection + ); + const end = fromUserCoordinate( + /** @type {LineCoordType} */ (coordinates)[coordinates.length - 1], + projection + ); + const radius = Math.sqrt(squaredCoordinateDistance(center, end)); + const geometry = opt_geometry + ? /** @type {Polygon} */ (opt_geometry) + : fromCircle(new Circle(center), opt_sides); - let angle = opt_angle; - if (!opt_angle && opt_angle !== 0) { - const x = end[0] - center[0]; - const y = end[1] - center[1]; - angle = Math.atan2(y, x); - } - makeRegular(geometry, center, radius, angle); - - const userProjection = getUserProjection(); - if (userProjection) { - geometry.transform(projection, userProjection); - } - return geometry; + let angle = opt_angle; + if (!opt_angle && opt_angle !== 0) { + const x = end[0] - center[0]; + const y = end[1] - center[1]; + angle = Math.atan2(y, x); } + makeRegular(geometry, center, radius, angle); + + const userProjection = getUserProjection(); + if (userProjection) { + geometry.transform(projection, userProjection); + } + return geometry; }; } @@ -1190,36 +1185,34 @@ export function createRegularPolygon(opt_sides, opt_angle) { */ export function createBox() { return function (coordinates, opt_geometry, projection) { - if (coordinates.length) { - const extent = boundingExtent( - /** @type {LineCoordType} */ ([ - coordinates[0], - coordinates[coordinates.length - 1], - ]).map(function (coordinate) { - return fromUserCoordinate(coordinate, projection); - }) - ); - const boxCoordinates = [ - [ - getBottomLeft(extent), - getBottomRight(extent), - getTopRight(extent), - getTopLeft(extent), - getBottomLeft(extent), - ], - ]; - let geometry = opt_geometry; - if (geometry) { - geometry.setCoordinates(boxCoordinates); - } else { - geometry = new Polygon(boxCoordinates); - } - const userProjection = getUserProjection(); - if (userProjection) { - geometry.transform(projection, userProjection); - } - return geometry; + const extent = boundingExtent( + /** @type {LineCoordType} */ ([ + coordinates[0], + coordinates[coordinates.length - 1], + ]).map(function (coordinate) { + return fromUserCoordinate(coordinate, projection); + }) + ); + const boxCoordinates = [ + [ + getBottomLeft(extent), + getBottomRight(extent), + getTopRight(extent), + getTopLeft(extent), + getBottomLeft(extent), + ], + ]; + let geometry = opt_geometry; + if (geometry) { + geometry.setCoordinates(boxCoordinates); + } else { + geometry = new Polygon(boxCoordinates); } + const userProjection = getUserProjection(); + if (userProjection) { + geometry.transform(projection, userProjection); + } + return geometry; }; } From 0bd04eafe015e61e1df28b1c3c7d52239c9a57ca Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Fri, 4 Dec 2020 14:35:53 +0100 Subject: [PATCH 3/4] Pass around pixels/coords to fix appendCoordinates --- src/ol/interaction/Draw.js | 39 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/ol/interaction/Draw.js b/src/ol/interaction/Draw.js index 193240cb2e..36f6f612c3 100644 --- a/src/ol/interaction/Draw.js +++ b/src/ol/interaction/Draw.js @@ -632,7 +632,7 @@ class Draw extends PointerInteraction { } } else if (this.freehand_) { this.finishDrawing(); - } else if (this.atFinish_(event)) { + } else if (this.atFinish_(event.pixel)) { if (this.finishCondition_(event)) { this.finishDrawing(); } @@ -648,6 +648,7 @@ class Draw extends PointerInteraction { if (!pass && this.stopClick_) { event.stopPropagation(); } + this.downPx_ = null; return pass; } @@ -677,7 +678,7 @@ class Draw extends PointerInteraction { } if (this.finishCoordinate_) { - this.modifyDrawing_(event); + this.modifyDrawing_(event.coordinate); } else { this.createOrUpdateSketchPoint_(event); } @@ -685,11 +686,11 @@ class Draw extends PointerInteraction { /** * Determine if an event is within the snapping tolerance of the start coord. - * @param {import("../MapBrowserEvent.js").default} event Event. + * @param {import("../pixel.js").Pixel} pixel Pixel. * @return {boolean} The event is within the snapping tolerance of the start. * @private */ - atFinish_(event) { + atFinish_(pixel) { let at = false; if (this.sketchFeature_) { let potentiallyDone = false; @@ -706,11 +707,10 @@ class Draw extends PointerInteraction { ]; } if (potentiallyDone) { - const map = event.map; + const map = this.getMap(); for (let i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) { const finishCoordinate = potentiallyFinishCoordinates[i]; const finishPixel = map.getPixelFromCoordinate(finishCoordinate); - const pixel = event.pixel; const dx = pixel[0] - finishPixel[0]; const dy = pixel[1] - finishPixel[1]; const snapTolerance = this.freehand_ ? 1 : this.snapTolerance_; @@ -802,20 +802,20 @@ class Draw extends PointerInteraction { /** * Modify the drawing. - * @param {import("../MapBrowserEvent.js").default} event Event. + * @param {import("../coordinate.js").Coordinate} coordinate Coordinate. * @private */ - modifyDrawing_(event) { - let coordinate = event.coordinate; + modifyDrawing_(coordinate) { + const map = this.getMap(); const geometry = this.sketchFeature_.getGeometry(); - const projection = event.map.getView().getProjection(); + const projection = map.getView().getProjection(); let coordinates, last; if (this.mode_ === Mode.POINT) { last = this.sketchCoords_; } else if (this.mode_ === Mode.POLYGON) { coordinates = /** @type {PolyCoordType} */ (this.sketchCoords_)[0]; last = coordinates[coordinates.length - 1]; - if (this.atFinish_(event)) { + if (this.atFinish_(map.getPixelFromCoordinate(coordinate))) { // snap to finish coordinate = this.finishCoordinate_.slice(); } @@ -908,12 +908,9 @@ class Draw extends PointerInteraction { coordinates.splice(-2, 1); if (coordinates.length >= 2) { this.finishCoordinate_ = coordinates[coordinates.length - 2].slice(); - if (this.pointerType_ !== 'mouse') { - const finishCoordinate = this.finishCoordinate_.slice(); - coordinates.pop(); - coordinates.push(finishCoordinate); - this.sketchPoint_.setGeometry(new Point(finishCoordinate)); - } + const finishCoordinate = this.finishCoordinate_.slice(); + coordinates[coordinates.length - 1] = finishCoordinate; + this.sketchPoint_.setGeometry(new Point(finishCoordinate)); } this.geometryFunction_(coordinates, geometry, projection); if (geometry.getType() === GeometryType.POLYGON && this.sketchLine_) { @@ -923,10 +920,9 @@ class Draw extends PointerInteraction { coordinates = /** @type {PolyCoordType} */ (this.sketchCoords_)[0]; coordinates.splice(-2, 1); const sketchLineGeom = this.sketchLine_.getGeometry(); - if (coordinates.length >= 2 && this.pointerType_ !== 'mouse') { + if (coordinates.length >= 2) { const finishCoordinate = coordinates[coordinates.length - 2].slice(); - coordinates.pop(); - coordinates.push(finishCoordinate); + coordinates[coordinates.length - 1] = finishCoordinate; this.sketchPoint_.setGeometry(new Point(finishCoordinate)); } sketchLineGeom.setCoordinates(coordinates); @@ -1060,6 +1056,9 @@ class Draw extends PointerInteraction { // Duplicate last coordinate for sketch drawing this.addToDrawing_(ending); + this.modifyDrawing_( + this.downPx_ ? this.getMap().getCoordinateFromPixel(this.downPx_) : ending + ); } /** From ecb9778fbfe33ee42b04af25af2424a68475cae9 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 8 Dec 2020 16:16:14 +0100 Subject: [PATCH 4/4] Set sketch cursor to last appended coordinate --- src/ol/interaction/Draw.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ol/interaction/Draw.js b/src/ol/interaction/Draw.js index 36f6f612c3..58a550d5af 100644 --- a/src/ol/interaction/Draw.js +++ b/src/ol/interaction/Draw.js @@ -1047,18 +1047,17 @@ class Draw extends PointerInteraction { } // Remove last coordinate from sketch drawing (this coordinate follows cursor position) - const ending = sketchCoords.pop(); + sketchCoords.pop(); // Append coordinate list for (let i = 0; i < coordinates.length; i++) { this.addToDrawing_(coordinates[i]); } - // Duplicate last coordinate for sketch drawing + const ending = coordinates[coordinates.length - 1]; + // Duplicate last coordinate for sketch drawing (cursor position) this.addToDrawing_(ending); - this.modifyDrawing_( - this.downPx_ ? this.getMap().getCoordinateFromPixel(this.downPx_) : ending - ); + this.modifyDrawing_(ending); } /**