Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

return last snapTo feature #14676

Merged
merged 5 commits into from Jul 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 51 additions & 0 deletions src/ol/events/SnapEvent.js
@@ -0,0 +1,51 @@
/**
* @module ol/events/SnapEvent
*/
import Event from './Event.js';

/**
* @enum {string}
*/
export const SnapEventType = {
/**
* Triggered upon snapping to vertex or edge
* @event SnapEvent#snap
* @api
*/
SNAP: 'snap',
};

/**
* @classdesc
* Events emitted by {@link module:ol/interaction/Snap~Snap} instances are instances of this
*/
export class SnapEvent extends Event {
/**
* @param {SnapEventType} type Type.
* @param {Object} options Options.
* @param {import("../coordinate.js").Coordinate} options.vertex The snapped vertex.
* @param {import("../coordinate.js").Coordinate} options.vertexPixel The pixel of the snapped vertex.
* @param {import("../Feature.js").default} options.feature The feature being snapped.
*/
constructor(type, options) {
super(type);
/**
* The Map coordinate of the snapped point.
* @type {import("../coordinate.js").Coordinate}
* @api
*/
this.vertex = options.vertex;
/**
* The Map pixel of the snapped point.
* @type {Array<number>&Array<number>}
* @api
*/
this.vertexPixel = options.vertexPixel;
/**
* The feature closest to the snapped point.
* @type {import("../Feature.js").default<import("../geom/Geometry.js").default>}
* @api
*/
this.feature = options.feature;
}
}
40 changes: 39 additions & 1 deletion src/ol/interaction/Snap.js
Expand Up @@ -7,6 +7,7 @@ import PointerInteraction from './Pointer.js';
import RBush from '../structs/RBush.js';
import VectorEventType from '../source/VectorEventType.js';
import {FALSE, TRUE} from '../functions.js';
import {SnapEvent, SnapEventType} from '../events/SnapEvent.js';
import {boundingExtent, buffer, createEmpty} from '../extent.js';
import {
closestOnCircle,
Expand All @@ -27,6 +28,7 @@ import {listen, unlistenByKey} from '../events.js';
* @typedef {Object} Result
* @property {import("../coordinate.js").Coordinate|null} vertex Vertex.
* @property {import("../pixel.js").Pixel|null} vertexPixel VertexPixel.
* @property {import("../Feature.js").default|null} feature Feature.
*/

/**
Expand Down Expand Up @@ -70,6 +72,16 @@ function getFeatureFromEvent(evt) {

const tempSegment = [];

/***
* @template Return
* @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
* import("../Observable").OnSignature<import("../ObjectEventType").Types|
* 'change:active', import("../Object").ObjectEvent, Return> &
* import("../Observable").OnSignature<'snap', SnapEvent, Return> &
* import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("../ObjectEventType").Types|
* 'change:active'|'snap', Return>} SnapOnSignature
*/

/**
* @classdesc
* Handles snapping of vector features while modifying or drawing them. The
Expand All @@ -91,6 +103,7 @@ const tempSegment = [];
*
* map.addInteraction(snap);
*
* @fires SnapEvent
* @api
*/
class Snap extends PointerInteraction {
Expand All @@ -114,6 +127,21 @@ class Snap extends PointerInteraction {

super(pointerOptions);

/***
* @type {SnapOnSignature<import("../events").EventsKey>}
*/
this.on;

/***
* @type {SnapOnSignature<import("../events").EventsKey>}
*/
this.once;

/***
* @type {SnapOnSignature<void>}
*/
this.un;

/**
* @type {import("../source/Vector.js").default|null}
* @private
Expand Down Expand Up @@ -263,12 +291,20 @@ class Snap extends PointerInteraction {
/**
* @param {import("../MapBrowserEvent.js").default} evt Map browser event.
* @return {boolean} `false` to stop event propagation.
* @api
*/
handleEvent(evt) {
const result = this.snapTo(evt.pixel, evt.coordinate, evt.map);
if (result) {
evt.coordinate = result.vertex.slice(0, 2);
evt.pixel = result.vertexPixel;
this.dispatchEvent(
new SnapEvent(SnapEventType.SNAP, {
vertex: evt.coordinate,
vertexPixel: evt.pixel,
feature: result.feature,
})
);
}
return super.handleEvent(evt);
}
Expand Down Expand Up @@ -432,14 +468,14 @@ class Snap extends PointerInteraction {
);

const segments = this.rBush_.getInExtent(box);

const segmentsLength = segments.length;
if (segmentsLength === 0) {
return null;
}

let closestVertex;
let minSquaredDistance = Infinity;
let closestFeature;
ahocevar marked this conversation as resolved.
Show resolved Hide resolved

const squaredPixelTolerance = this.pixelTolerance_ * this.pixelTolerance_;
const getResult = () => {
Expand All @@ -453,6 +489,7 @@ class Snap extends PointerInteraction {
Math.round(vertexPixel[0]),
Math.round(vertexPixel[1]),
],
feature: closestFeature,
ahocevar marked this conversation as resolved.
Show resolved Hide resolved
};
}
}
Expand All @@ -469,6 +506,7 @@ class Snap extends PointerInteraction {
if (delta < minSquaredDistance) {
closestVertex = vertex;
minSquaredDistance = delta;
closestFeature = segmentData.feature;
ahocevar marked this conversation as resolved.
Show resolved Hide resolved
}
});
}
Expand Down