ol 10.4.1-dev.1738658260831 → 10.4.1-dev.1738698469111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ol.d.ts +2 -0
- package/dist/ol.d.ts.map +1 -1
- package/dist/ol.js +1 -1
- package/dist/ol.js.map +1 -1
- package/geom/flat/segments.d.ts +8 -0
- package/geom/flat/segments.d.ts.map +1 -1
- package/geom/flat/segments.js +24 -0
- package/interaction/Snap.d.ts +13 -0
- package/interaction/Snap.d.ts.map +1 -1
- package/interaction/Snap.js +92 -13
- package/package.json +1 -1
- package/util.js +1 -1
package/geom/flat/segments.d.ts
CHANGED
|
@@ -15,4 +15,12 @@
|
|
|
15
15
|
* @template T
|
|
16
16
|
*/
|
|
17
17
|
export function forEach<T>(flatCoordinates: Array<number>, offset: number, end: number, stride: number, callback: (arg0: import("../../coordinate.js").Coordinate, arg1: import("../../coordinate.js").Coordinate) => T): T | boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Calculate the intersection point of two line segments.
|
|
20
|
+
* Reference: https://stackoverflow.com/a/72474223/2389327
|
|
21
|
+
* @param {Array<import("../../coordinate.js").Coordinate>} segment1 The first line segment as an array of two points.
|
|
22
|
+
* @param {Array<import("../../coordinate.js").Coordinate>} segment2 The second line segment as an array of two points.
|
|
23
|
+
* @return {import("../../coordinate.js").Coordinate|undefined} The intersection point or `undefined` if no intersection.
|
|
24
|
+
*/
|
|
25
|
+
export function getIntersectionPoint(segment1: Array<import("../../coordinate.js").Coordinate>, segment2: Array<import("../../coordinate.js").Coordinate>): import("../../coordinate.js").Coordinate | undefined;
|
|
18
26
|
//# sourceMappingURL=segments.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["segments.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAFa,CAAC,mBAPH,KAAK,CAAC,MAAM,CAAC,UACb,MAAM,OACN,MAAM,UACN,MAAM,YACN,CAAS,IAAwC,EAAxC,OAAO,qBAAqB,EAAE,UAAU,EAAE,IAAwC,EAAxC,OAAO,qBAAqB,EAAE,UAAU,KAAG,CAAC,GAE9F,CAAC,GAAC,OAAO,CAgBpB"}
|
|
1
|
+
{"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["segments.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAFa,CAAC,mBAPH,KAAK,CAAC,MAAM,CAAC,UACb,MAAM,OACN,MAAM,UACN,MAAM,YACN,CAAS,IAAwC,EAAxC,OAAO,qBAAqB,EAAE,UAAU,EAAE,IAAwC,EAAxC,OAAO,qBAAqB,EAAE,UAAU,KAAG,CAAC,GAE9F,CAAC,GAAC,OAAO,CAgBpB;AAED;;;;;;GAMG;AACH,+CAJW,KAAK,CAAC,OAAO,qBAAqB,EAAE,UAAU,CAAC,YAC/C,KAAK,CAAC,OAAO,qBAAqB,EAAE,UAAU,CAAC,GAC9C,OAAO,qBAAqB,EAAE,UAAU,GAAC,SAAS,CAiB7D"}
|
package/geom/flat/segments.js
CHANGED
|
@@ -29,3 +29,27 @@ export function forEach(flatCoordinates, offset, end, stride, callback) {
|
|
|
29
29
|
}
|
|
30
30
|
return false;
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Calculate the intersection point of two line segments.
|
|
35
|
+
* Reference: https://stackoverflow.com/a/72474223/2389327
|
|
36
|
+
* @param {Array<import("../../coordinate.js").Coordinate>} segment1 The first line segment as an array of two points.
|
|
37
|
+
* @param {Array<import("../../coordinate.js").Coordinate>} segment2 The second line segment as an array of two points.
|
|
38
|
+
* @return {import("../../coordinate.js").Coordinate|undefined} The intersection point or `undefined` if no intersection.
|
|
39
|
+
*/
|
|
40
|
+
export function getIntersectionPoint(segment1, segment2) {
|
|
41
|
+
const [a, b] = segment1;
|
|
42
|
+
const [c, d] = segment2;
|
|
43
|
+
const t =
|
|
44
|
+
((a[0] - c[0]) * (c[1] - d[1]) - (a[1] - c[1]) * (c[0] - d[0])) /
|
|
45
|
+
((a[0] - b[0]) * (c[1] - d[1]) - (a[1] - b[1]) * (c[0] - d[0]));
|
|
46
|
+
const u =
|
|
47
|
+
((a[0] - c[0]) * (a[1] - b[1]) - (a[1] - c[1]) * (a[0] - b[0])) /
|
|
48
|
+
((a[0] - b[0]) * (c[1] - d[1]) - (a[1] - b[1]) * (c[0] - d[0]));
|
|
49
|
+
|
|
50
|
+
// Check if lines actually intersect
|
|
51
|
+
if (0 <= t && t <= 1 && 0 <= u && u <= 1) {
|
|
52
|
+
return [a[0] + t * (b[0] - a[0]), a[1] + t * (b[1] - a[1])];
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
package/interaction/Snap.d.ts
CHANGED
|
@@ -26,6 +26,10 @@ export type SegmentData = {
|
|
|
26
26
|
* Segment.
|
|
27
27
|
*/
|
|
28
28
|
segment: Array<import("../coordinate.js").Coordinate>;
|
|
29
|
+
/**
|
|
30
|
+
* Is intersection.
|
|
31
|
+
*/
|
|
32
|
+
isIntersection?: boolean | undefined;
|
|
29
33
|
};
|
|
30
34
|
export type Options = {
|
|
31
35
|
/**
|
|
@@ -40,6 +44,10 @@ export type Options = {
|
|
|
40
44
|
* Snap to vertices.
|
|
41
45
|
*/
|
|
42
46
|
vertex?: boolean | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Snap to intersections between segments.
|
|
49
|
+
*/
|
|
50
|
+
intersection?: boolean | undefined;
|
|
43
51
|
/**
|
|
44
52
|
* Pixel tolerance for considering the pointer close enough to a segment or
|
|
45
53
|
* vertex for snapping.
|
|
@@ -140,6 +148,11 @@ declare class Snap extends PointerInteraction {
|
|
|
140
148
|
* @type {boolean}
|
|
141
149
|
*/
|
|
142
150
|
private edge_;
|
|
151
|
+
/**
|
|
152
|
+
* @private
|
|
153
|
+
* @type {boolean}
|
|
154
|
+
*/
|
|
155
|
+
private intersection_;
|
|
143
156
|
/**
|
|
144
157
|
* @type {import("../Collection.js").default<import("../Feature.js").default>|null}
|
|
145
158
|
* @private
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snap.d.ts","sourceRoot":"","sources":["Snap.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"Snap.d.ts","sourceRoot":"","sources":["Snap.js"],"names":[],"mappings":"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"}
|
package/interaction/Snap.js
CHANGED
|
@@ -10,9 +10,15 @@ import {
|
|
|
10
10
|
import EventType from '../events/EventType.js';
|
|
11
11
|
import {SnapEvent, SnapEventType} from '../events/SnapEvent.js';
|
|
12
12
|
import {listen, unlistenByKey} from '../events.js';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
boundingExtent,
|
|
15
|
+
buffer,
|
|
16
|
+
createEmpty,
|
|
17
|
+
intersects as intersectsExtent,
|
|
18
|
+
} from '../extent.js';
|
|
14
19
|
import {FALSE, TRUE} from '../functions.js';
|
|
15
20
|
import {fromCircle} from '../geom/Polygon.js';
|
|
21
|
+
import {getIntersectionPoint} from '../geom/flat/segments.js';
|
|
16
22
|
import {
|
|
17
23
|
fromUserCoordinate,
|
|
18
24
|
getUserProjection,
|
|
@@ -36,6 +42,7 @@ import PointerInteraction from './Pointer.js';
|
|
|
36
42
|
* @typedef {Object} SegmentData
|
|
37
43
|
* @property {import("../Feature.js").default} feature Feature.
|
|
38
44
|
* @property {Array<import("../coordinate.js").Coordinate>} segment Segment.
|
|
45
|
+
* @property {boolean} [isIntersection] Is intersection.
|
|
39
46
|
*/
|
|
40
47
|
|
|
41
48
|
/**
|
|
@@ -43,6 +50,7 @@ import PointerInteraction from './Pointer.js';
|
|
|
43
50
|
* @property {import("../Collection.js").default<import("../Feature.js").default>} [features] Snap to these features. Either this option or source should be provided.
|
|
44
51
|
* @property {boolean} [edge=true] Snap to edges.
|
|
45
52
|
* @property {boolean} [vertex=true] Snap to vertices.
|
|
53
|
+
* @property {boolean} [intersection=false] Snap to intersections between segments.
|
|
46
54
|
* @property {number} [pixelTolerance=10] Pixel tolerance for considering the pointer close enough to a segment or
|
|
47
55
|
* vertex for snapping.
|
|
48
56
|
* @property {import("../source/Vector.js").default} [source] Snap to features from this source. Either this option or features should be provided
|
|
@@ -81,6 +89,10 @@ function getFeatureFromEvent(evt) {
|
|
|
81
89
|
}
|
|
82
90
|
|
|
83
91
|
const tempSegment = [];
|
|
92
|
+
/** @type {Array<import('../extent.js').Extent>} */
|
|
93
|
+
const tempExtents = [];
|
|
94
|
+
/** @type {Array<SegmentData>} */
|
|
95
|
+
const tempSegmentData = [];
|
|
84
96
|
|
|
85
97
|
/***
|
|
86
98
|
* @template Return
|
|
@@ -170,6 +182,13 @@ class Snap extends PointerInteraction {
|
|
|
170
182
|
*/
|
|
171
183
|
this.edge_ = options.edge !== undefined ? options.edge : true;
|
|
172
184
|
|
|
185
|
+
/**
|
|
186
|
+
* @private
|
|
187
|
+
* @type {boolean}
|
|
188
|
+
*/
|
|
189
|
+
this.intersection_ =
|
|
190
|
+
options.intersection !== undefined ? options.intersection : false;
|
|
191
|
+
|
|
173
192
|
/**
|
|
174
193
|
* @type {import("../Collection.js").default<import("../Feature.js").default>|null}
|
|
175
194
|
* @private
|
|
@@ -263,18 +282,72 @@ class Snap extends PointerInteraction {
|
|
|
263
282
|
const segments =
|
|
264
283
|
/** @type {Array<Array<import('../coordinate.js').Coordinate>>} */ ([]);
|
|
265
284
|
segmenter(segments, geometry);
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
} else if (segments.length > 1) {
|
|
272
|
-
const extents = segments.map((s) => boundingExtent(s));
|
|
273
|
-
const segmentsData = segments.map((segment) => ({
|
|
285
|
+
let segmentCount = segments.length;
|
|
286
|
+
for (let i = 0; i < segmentCount; ++i) {
|
|
287
|
+
const segment = segments[i];
|
|
288
|
+
tempExtents[i] = boundingExtent(segment);
|
|
289
|
+
tempSegmentData[i] = {
|
|
274
290
|
feature: feature,
|
|
275
291
|
segment: segment,
|
|
276
|
-
}
|
|
277
|
-
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
tempExtents.length = segmentCount;
|
|
295
|
+
tempSegmentData.length = segmentCount;
|
|
296
|
+
|
|
297
|
+
if (this.intersection_) {
|
|
298
|
+
for (let j = 0, jj = segments.length; j < jj; ++j) {
|
|
299
|
+
const segment = segments[j];
|
|
300
|
+
if (segment.length === 1) {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
const extent = tempExtents[j];
|
|
304
|
+
// Calculate intersections with own segments
|
|
305
|
+
for (let k = 0, kk = segments.length; k < kk; ++k) {
|
|
306
|
+
if (j === k || j - 1 === k || j + 1 === k) {
|
|
307
|
+
// Exclude self and neighbours
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const otherSegment = segments[k];
|
|
311
|
+
if (!intersectsExtent(extent, tempExtents[k])) {
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
const intersection = getIntersectionPoint(segment, otherSegment);
|
|
315
|
+
if (!intersection) {
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
const intersectionSegment = [intersection];
|
|
319
|
+
tempExtents[segmentCount] = boundingExtent(intersectionSegment);
|
|
320
|
+
tempSegmentData[segmentCount++] = {
|
|
321
|
+
feature,
|
|
322
|
+
segment: intersectionSegment,
|
|
323
|
+
isIntersection: true,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
// Calculate intersections with existing segments
|
|
327
|
+
const otherSegments = this.rBush_.getInExtent(tempExtents[j]);
|
|
328
|
+
for (const {segment: otherSegment} of otherSegments) {
|
|
329
|
+
if (otherSegment.length === 1) {
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
const intersection = getIntersectionPoint(segment, otherSegment);
|
|
333
|
+
if (!intersection) {
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
const intersectionSegment = [intersection];
|
|
337
|
+
tempExtents[segmentCount] = boundingExtent(intersectionSegment);
|
|
338
|
+
tempSegmentData[segmentCount++] = {
|
|
339
|
+
feature,
|
|
340
|
+
segment: intersectionSegment,
|
|
341
|
+
isIntersection: true,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (segmentCount === 1) {
|
|
348
|
+
this.rBush_.insert(tempExtents[0], tempSegmentData[0]);
|
|
349
|
+
} else {
|
|
350
|
+
this.rBush_.load(tempExtents, tempSegmentData);
|
|
278
351
|
}
|
|
279
352
|
}
|
|
280
353
|
}
|
|
@@ -521,13 +594,18 @@ class Snap extends PointerInteraction {
|
|
|
521
594
|
let minSquaredDistance = Infinity;
|
|
522
595
|
let closestFeature;
|
|
523
596
|
let closestSegment = null;
|
|
597
|
+
let isIntersection;
|
|
524
598
|
|
|
525
599
|
const squaredPixelTolerance = this.pixelTolerance_ * this.pixelTolerance_;
|
|
526
600
|
const getResult = () => {
|
|
527
601
|
if (closestVertex) {
|
|
528
602
|
const vertexPixel = map.getPixelFromCoordinate(closestVertex);
|
|
529
603
|
const squaredPixelDistance = squaredDistance(pixel, vertexPixel);
|
|
530
|
-
if (
|
|
604
|
+
if (
|
|
605
|
+
squaredPixelDistance <= squaredPixelTolerance &&
|
|
606
|
+
((isIntersection && this.intersection_) ||
|
|
607
|
+
(!isIntersection && (this.vertex_ || this.edge_)))
|
|
608
|
+
) {
|
|
531
609
|
return {
|
|
532
610
|
vertex: closestVertex,
|
|
533
611
|
vertexPixel: [
|
|
@@ -542,7 +620,7 @@ class Snap extends PointerInteraction {
|
|
|
542
620
|
return null;
|
|
543
621
|
};
|
|
544
622
|
|
|
545
|
-
if (this.vertex_) {
|
|
623
|
+
if (this.vertex_ || this.intersection_) {
|
|
546
624
|
for (let i = 0; i < segmentsLength; ++i) {
|
|
547
625
|
const segmentData = segments[i];
|
|
548
626
|
if (segmentData.feature.getGeometry().getType() !== 'Circle') {
|
|
@@ -553,6 +631,7 @@ class Snap extends PointerInteraction {
|
|
|
553
631
|
closestVertex = vertex;
|
|
554
632
|
minSquaredDistance = delta;
|
|
555
633
|
closestFeature = segmentData.feature;
|
|
634
|
+
isIntersection = segmentData.isIntersection;
|
|
556
635
|
}
|
|
557
636
|
});
|
|
558
637
|
}
|
package/package.json
CHANGED
package/util.js
CHANGED