Merge pull request #11800 from ahocevar/remove-last-point

Fix removeLastPoint when removing last point
This commit is contained in:
Andreas Hocevar
2020-12-08 16:23:30 +01:00
committed by GitHub
2 changed files with 130 additions and 131 deletions
+21 -23
View File
@@ -43,30 +43,28 @@ function addInteraction() {
} else if (value === 'Star') { } else if (value === 'Star') {
value = 'Circle'; value = 'Circle';
geometryFunction = function (coordinates, geometry) { geometryFunction = function (coordinates, geometry) {
if (coordinates.length) { const center = coordinates[0];
const center = coordinates[0]; const last = coordinates[coordinates.length - 1];
const last = coordinates[coordinates.length - 1]; const dx = center[0] - last[0];
const dx = center[0] - last[0]; const dy = center[1] - last[1];
const dy = center[1] - last[1]; const radius = Math.sqrt(dx * dx + dy * dy);
const radius = Math.sqrt(dx * dx + dy * dy); const rotation = Math.atan2(dy, dx);
const rotation = Math.atan2(dy, dx); const newCoordinates = [];
const newCoordinates = []; const numPoints = 12;
const numPoints = 12; for (let i = 0; i < numPoints; ++i) {
for (let i = 0; i < numPoints; ++i) { const angle = rotation + (i * 2 * Math.PI) / numPoints;
const angle = rotation + (i * 2 * Math.PI) / numPoints; const fraction = i % 2 === 0 ? 1 : 0.5;
const fraction = i % 2 === 0 ? 1 : 0.5; const offsetX = radius * fraction * Math.cos(angle);
const offsetX = radius * fraction * Math.cos(angle); const offsetY = radius * fraction * Math.sin(angle);
const offsetY = radius * fraction * Math.sin(angle); newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
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;
} }
newCoordinates.push(newCoordinates[0].slice());
if (!geometry) {
geometry = new Polygon([newCoordinates]);
} else {
geometry.setCoordinates([newCoordinates]);
}
return geometry;
}; };
} }
draw = new Draw({ draw = new Draw({
+109 -108
View File
@@ -59,7 +59,8 @@ import {squaredDistance as squaredCoordinateDistance} from '../coordinate.js';
* polygon rings and `2` for line strings. * polygon rings and `2` for line strings.
* @property {import("../events/condition.js").Condition} [finishCondition] A function * @property {import("../events/condition.js").Condition} [finishCondition] A function
* that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a * 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] * @property {import("../style/Style.js").StyleLike} [style]
* Style for sketch features. * Style for sketch features.
* @property {GeometryFunction} [geometryFunction] * @property {GeometryFunction} [geometryFunction]
@@ -317,25 +318,20 @@ class Draw extends PointerInteraction {
* @return {import("../geom/SimpleGeometry.js").default} A geometry. * @return {import("../geom/SimpleGeometry.js").default} A geometry.
*/ */
geometryFunction = function (coordinates, geometry, projection) { geometryFunction = function (coordinates, geometry, projection) {
if (coordinates.length) { const circle = geometry
const circle = geometry ? /** @type {Circle} */ (geometry)
? /** @type {Circle} */ (geometry) : new Circle([NaN, NaN]);
: new Circle([NaN, NaN]); const center = fromUserCoordinate(coordinates[0], projection);
const center = fromUserCoordinate(coordinates[0], projection); const squaredLength = squaredCoordinateDistance(
const squaredLength = squaredCoordinateDistance( center,
center, fromUserCoordinate(coordinates[coordinates.length - 1], projection)
fromUserCoordinate( );
coordinates[coordinates.length - 1], circle.setCenterAndRadius(center, Math.sqrt(squaredLength));
projection const userProjection = getUserProjection();
) if (userProjection) {
); circle.transform(projection, userProjection);
circle.setCenterAndRadius(center, Math.sqrt(squaredLength));
const userProjection = getUserProjection();
if (userProjection) {
circle.transform(projection, userProjection);
}
return circle;
} }
return circle;
}; };
} else { } else {
let Constructor; let Constructor;
@@ -585,7 +581,7 @@ class Draw extends PointerInteraction {
if (this.freehand_) { if (this.freehand_) {
this.downPx_ = event.pixel; this.downPx_ = event.pixel;
if (!this.finishCoordinate_) { if (!this.finishCoordinate_) {
this.startDrawing_(event); this.startDrawing_(event.coordinate);
} }
return true; return true;
} else if (this.condition_(event)) { } else if (this.condition_(event)) {
@@ -630,13 +626,13 @@ class Draw extends PointerInteraction {
if (this.shouldHandle_) { if (this.shouldHandle_) {
if (!this.finishCoordinate_) { if (!this.finishCoordinate_) {
this.startDrawing_(event); this.startDrawing_(event.coordinate);
if (this.mode_ === Mode.POINT) { if (this.mode_ === Mode.POINT) {
this.finishDrawing(); this.finishDrawing();
} }
} else if (this.freehand_) { } else if (this.freehand_) {
this.finishDrawing(); this.finishDrawing();
} else if (this.atFinish_(event)) { } else if (this.atFinish_(event.pixel)) {
if (this.finishCondition_(event)) { if (this.finishCondition_(event)) {
this.finishDrawing(); this.finishDrawing();
} }
@@ -652,6 +648,7 @@ class Draw extends PointerInteraction {
if (!pass && this.stopClick_) { if (!pass && this.stopClick_) {
event.stopPropagation(); event.stopPropagation();
} }
this.downPx_ = null;
return pass; return pass;
} }
@@ -681,7 +678,7 @@ class Draw extends PointerInteraction {
} }
if (this.finishCoordinate_) { if (this.finishCoordinate_) {
this.modifyDrawing_(event); this.modifyDrawing_(event.coordinate);
} else { } else {
this.createOrUpdateSketchPoint_(event); this.createOrUpdateSketchPoint_(event);
} }
@@ -689,11 +686,11 @@ class Draw extends PointerInteraction {
/** /**
* Determine if an event is within the snapping tolerance of the start coord. * 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. * @return {boolean} The event is within the snapping tolerance of the start.
* @private * @private
*/ */
atFinish_(event) { atFinish_(pixel) {
let at = false; let at = false;
if (this.sketchFeature_) { if (this.sketchFeature_) {
let potentiallyDone = false; let potentiallyDone = false;
@@ -710,11 +707,10 @@ class Draw extends PointerInteraction {
]; ];
} }
if (potentiallyDone) { if (potentiallyDone) {
const map = event.map; const map = this.getMap();
for (let i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) { for (let i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) {
const finishCoordinate = potentiallyFinishCoordinates[i]; const finishCoordinate = potentiallyFinishCoordinates[i];
const finishPixel = map.getPixelFromCoordinate(finishCoordinate); const finishPixel = map.getPixelFromCoordinate(finishCoordinate);
const pixel = event.pixel;
const dx = pixel[0] - finishPixel[0]; const dx = pixel[0] - finishPixel[0];
const dy = pixel[1] - finishPixel[1]; const dy = pixel[1] - finishPixel[1];
const snapTolerance = this.freehand_ ? 1 : this.snapTolerance_; const snapTolerance = this.freehand_ ? 1 : this.snapTolerance_;
@@ -771,12 +767,11 @@ class Draw extends PointerInteraction {
/** /**
* Start the drawing. * Start the drawing.
* @param {import("../MapBrowserEvent.js").default} event Event. * @param {import("../coordinate.js").Coordinate} start Start coordinate.
* @private * @private
*/ */
startDrawing_(event) { startDrawing_(start) {
const start = event.coordinate; const projection = this.getMap().getView().getProjection();
const projection = event.map.getView().getProjection();
this.finishCoordinate_ = start; this.finishCoordinate_ = start;
if (this.mode_ === Mode.POINT) { if (this.mode_ === Mode.POINT) {
this.sketchCoords_ = start.slice(); this.sketchCoords_ = start.slice();
@@ -807,20 +802,20 @@ class Draw extends PointerInteraction {
/** /**
* Modify the drawing. * Modify the drawing.
* @param {import("../MapBrowserEvent.js").default} event Event. * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @private * @private
*/ */
modifyDrawing_(event) { modifyDrawing_(coordinate) {
let coordinate = event.coordinate; const map = this.getMap();
const geometry = this.sketchFeature_.getGeometry(); const geometry = this.sketchFeature_.getGeometry();
const projection = event.map.getView().getProjection(); const projection = map.getView().getProjection();
let coordinates, last; let coordinates, last;
if (this.mode_ === Mode.POINT) { if (this.mode_ === Mode.POINT) {
last = this.sketchCoords_; last = this.sketchCoords_;
} else if (this.mode_ === Mode.POLYGON) { } else if (this.mode_ === Mode.POLYGON) {
coordinates = /** @type {PolyCoordType} */ (this.sketchCoords_)[0]; coordinates = /** @type {PolyCoordType} */ (this.sketchCoords_)[0];
last = coordinates[coordinates.length - 1]; last = coordinates[coordinates.length - 1];
if (this.atFinish_(event)) { if (this.atFinish_(map.getPixelFromCoordinate(coordinate))) {
// snap to finish // snap to finish
coordinate = this.finishCoordinate_.slice(); coordinate = this.finishCoordinate_.slice();
} }
@@ -896,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 * @api
*/ */
removeLastPoint() { removeLastPoint() {
@@ -912,12 +908,9 @@ class Draw extends PointerInteraction {
coordinates.splice(-2, 1); coordinates.splice(-2, 1);
if (coordinates.length >= 2) { if (coordinates.length >= 2) {
this.finishCoordinate_ = coordinates[coordinates.length - 2].slice(); this.finishCoordinate_ = coordinates[coordinates.length - 2].slice();
if (this.pointerType_ !== 'mouse') { const finishCoordinate = this.finishCoordinate_.slice();
const finishCoordinate = this.finishCoordinate_.slice(); coordinates[coordinates.length - 1] = finishCoordinate;
coordinates.pop(); this.sketchPoint_.setGeometry(new Point(finishCoordinate));
coordinates.push(finishCoordinate);
this.sketchPoint_.setGeometry(new Point(finishCoordinate));
}
} }
this.geometryFunction_(coordinates, geometry, projection); this.geometryFunction_(coordinates, geometry, projection);
if (geometry.getType() === GeometryType.POLYGON && this.sketchLine_) { if (geometry.getType() === GeometryType.POLYGON && this.sketchLine_) {
@@ -927,17 +920,16 @@ class Draw extends PointerInteraction {
coordinates = /** @type {PolyCoordType} */ (this.sketchCoords_)[0]; coordinates = /** @type {PolyCoordType} */ (this.sketchCoords_)[0];
coordinates.splice(-2, 1); coordinates.splice(-2, 1);
const sketchLineGeom = this.sketchLine_.getGeometry(); const sketchLineGeom = this.sketchLine_.getGeometry();
if (coordinates.length >= 2 && this.pointerType_ !== 'mouse') { if (coordinates.length >= 2) {
const finishCoordinate = coordinates[coordinates.length - 2].slice(); const finishCoordinate = coordinates[coordinates.length - 2].slice();
coordinates.pop(); coordinates[coordinates.length - 1] = finishCoordinate;
coordinates.push(finishCoordinate);
this.sketchPoint_.setGeometry(new Point(finishCoordinate)); this.sketchPoint_.setGeometry(new Point(finishCoordinate));
} }
sketchLineGeom.setCoordinates(coordinates); sketchLineGeom.setCoordinates(coordinates);
this.geometryFunction_(this.sketchCoords_, geometry, projection); this.geometryFunction_(this.sketchCoords_, geometry, projection);
} }
if (coordinates.length === 0) { if (coordinates.length === 1) {
this.abortDrawing(); this.abortDrawing();
} }
@@ -1026,33 +1018,46 @@ class Draw extends PointerInteraction {
* Append coordinates to the end of the geometry that is currently being drawn. * Append coordinates to the end of the geometry that is currently being drawn.
* This can be used when drawing LineStrings or Polygons. Coordinates will * 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 * either be appended to the current LineString or the outer ring of the current
* Polygon. * Polygon. If no geometry is being drawn, a new one will be created.
* @param {!LineCoordType} coordinates Linear coordinates to be appended into * @param {!LineCoordType} coordinates Linear coordinates to be appended to
* the coordinate array. * the coordinate array.
* @api * @api
*/ */
appendCoordinates(coordinates) { appendCoordinates(coordinates) {
const mode = this.mode_; 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) { if (mode === Mode.LINE_STRING || mode === Mode.CIRCLE) {
sketchCoords = /** @type {LineCoordType} */ this.sketchCoords_; sketchCoords = /** @type {LineCoordType} */ (this.sketchCoords_);
} else if (mode === Mode.POLYGON) { } else if (mode === Mode.POLYGON) {
sketchCoords = sketchCoords =
this.sketchCoords_ && this.sketchCoords_.length this.sketchCoords_ && this.sketchCoords_.length
? /** @type {PolyCoordType} */ (this.sketchCoords_)[0] ? /** @type {PolyCoordType} */ (this.sketchCoords_)[0]
: []; : [];
} else {
return;
}
if (newDrawing) {
sketchCoords.shift();
} }
// Remove last coordinate from sketch drawing (this coordinate follows cursor position) // Remove last coordinate from sketch drawing (this coordinate follows cursor position)
const ending = sketchCoords.pop(); sketchCoords.pop();
// Append coordinate list // Append coordinate list
for (let i = 0; i < coordinates.length; i++) { for (let i = 0; i < coordinates.length; i++) {
this.addToDrawing_(coordinates[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.addToDrawing_(ending);
this.modifyDrawing_(ending);
} }
/** /**
@@ -1140,34 +1145,32 @@ function getDefaultStyleFunction() {
*/ */
export function createRegularPolygon(opt_sides, opt_angle) { export function createRegularPolygon(opt_sides, opt_angle) {
return function (coordinates, opt_geometry, projection) { return function (coordinates, opt_geometry, projection) {
if (coordinates.length) { const center = fromUserCoordinate(
const center = fromUserCoordinate( /** @type {LineCoordType} */ (coordinates)[0],
/** @type {LineCoordType} */ (coordinates)[0], projection
projection );
); const end = fromUserCoordinate(
const end = fromUserCoordinate( /** @type {LineCoordType} */ (coordinates)[coordinates.length - 1],
/** @type {LineCoordType} */ (coordinates)[coordinates.length - 1], projection
projection );
); const radius = Math.sqrt(squaredCoordinateDistance(center, end));
const radius = Math.sqrt(squaredCoordinateDistance(center, end)); const geometry = opt_geometry
const geometry = opt_geometry ? /** @type {Polygon} */ (opt_geometry)
? /** @type {Polygon} */ (opt_geometry) : fromCircle(new Circle(center), opt_sides);
: fromCircle(new Circle(center), opt_sides);
let angle = opt_angle; let angle = opt_angle;
if (!opt_angle && opt_angle !== 0) { if (!opt_angle && opt_angle !== 0) {
const x = end[0] - center[0]; const x = end[0] - center[0];
const y = end[1] - center[1]; const y = end[1] - center[1];
angle = Math.atan2(y, x); angle = Math.atan2(y, x);
}
makeRegular(geometry, center, radius, angle);
const userProjection = getUserProjection();
if (userProjection) {
geometry.transform(projection, userProjection);
}
return geometry;
} }
makeRegular(geometry, center, radius, angle);
const userProjection = getUserProjection();
if (userProjection) {
geometry.transform(projection, userProjection);
}
return geometry;
}; };
} }
@@ -1180,36 +1183,34 @@ export function createRegularPolygon(opt_sides, opt_angle) {
*/ */
export function createBox() { export function createBox() {
return function (coordinates, opt_geometry, projection) { return function (coordinates, opt_geometry, projection) {
if (coordinates.length) { const extent = boundingExtent(
const extent = boundingExtent( /** @type {LineCoordType} */ ([
/** @type {LineCoordType} */ ([ coordinates[0],
coordinates[0], coordinates[coordinates.length - 1],
coordinates[coordinates.length - 1], ]).map(function (coordinate) {
]).map(function (coordinate) { return fromUserCoordinate(coordinate, projection);
return fromUserCoordinate(coordinate, projection); })
}) );
); const boxCoordinates = [
const boxCoordinates = [ [
[ getBottomLeft(extent),
getBottomLeft(extent), getBottomRight(extent),
getBottomRight(extent), getTopRight(extent),
getTopRight(extent), getTopLeft(extent),
getTopLeft(extent), getBottomLeft(extent),
getBottomLeft(extent), ],
], ];
]; let geometry = opt_geometry;
let geometry = opt_geometry; if (geometry) {
if (geometry) { geometry.setCoordinates(boxCoordinates);
geometry.setCoordinates(boxCoordinates); } else {
} else { geometry = new Polygon(boxCoordinates);
geometry = new Polygon(boxCoordinates);
}
const userProjection = getUserProjection();
if (userProjection) {
geometry.transform(projection, userProjection);
}
return geometry;
} }
const userProjection = getUserProjection();
if (userProjection) {
geometry.transform(projection, userProjection);
}
return geometry;
}; };
} }