ol 10.6.2-dev.1753992384159 → 10.6.2-dev.1753992411402

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.
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @param {LineCoordType} coordinates The ring coordinates.
3
+ * @param {number} index The index. May be wrapped.
4
+ * @return {import("../coordinate.js").Coordinate} The coordinate.
5
+ */
6
+ export function getCoordinate(coordinates: LineCoordType, index: number): import("../coordinate.js").Coordinate;
7
+ /**
8
+ * @param {LineCoordType} coordinates The coordinates.
9
+ * @param {number} index The index. May be fractional and may wrap.
10
+ * @return {import("../coordinate.js").Coordinate} The interpolated coordinate.
11
+ */
12
+ export function interpolateCoordinate(coordinates: LineCoordType, index: number): import("../coordinate.js").Coordinate;
13
+ /**
14
+ * @param {import("../coordinate.js").Coordinate} coordinate The coordinate.
15
+ * @param {TraceState} traceState The trace state.
16
+ * @param {import("../Map.js").default} map The map.
17
+ * @param {number} snapTolerance The snap tolerance.
18
+ * @return {TraceTargetUpdateInfo} Information about the new trace target. The returned
19
+ * object is reused between calls and must not be modified by the caller.
20
+ */
21
+ export function getTraceTargetUpdate(coordinate: import("../coordinate.js").Coordinate, traceState: TraceState, map: import("../Map.js").default, snapTolerance: number): TraceTargetUpdateInfo;
22
+ /**
23
+ * @param {import("../coordinate.js").Coordinate} coordinate The coordinate.
24
+ * @param {Array<import("../Feature.js").default>} features The candidate features.
25
+ * @return {Array<TraceTarget>} The trace targets.
26
+ */
27
+ export function getTraceTargets(coordinate: import("../coordinate.js").Coordinate, features: Array<import("../Feature.js").default>): Array<TraceTarget>;
28
+ /**
29
+ * @param {number} x The point x.
30
+ * @param {number} y The point y.
31
+ * @param {import("../coordinate.js").Coordinate} start The segment start.
32
+ * @param {import("../coordinate.js").Coordinate} end The segment end.
33
+ * @return {PointSegmentRelationship} The point segment relationship. The returned object is
34
+ * shared between calls and must not be modified by the caller.
35
+ */
36
+ export function getPointSegmentRelationship(x: number, y: number, start: import("../coordinate.js").Coordinate, end: import("../coordinate.js").Coordinate): PointSegmentRelationship;
37
+ /**
38
+ * Coordinate type when drawing lines.
39
+ */
40
+ export type LineCoordType = Array<import("../coordinate.js").Coordinate>;
41
+ export type TraceTarget = {
42
+ /**
43
+ * Target coordinates.
44
+ */
45
+ coordinates: Array<import("../coordinate.js").Coordinate>;
46
+ /**
47
+ * The target coordinates are a linear ring.
48
+ */
49
+ ring: boolean;
50
+ /**
51
+ * The index of first traced coordinate. A fractional index represents an
52
+ * edge intersection. Index values for rings will wrap (may be negative or larger than coordinates length).
53
+ */
54
+ startIndex: number;
55
+ /**
56
+ * The index of last traced coordinate. Details from startIndex also apply here.
57
+ */
58
+ endIndex: number;
59
+ };
60
+ export type TraceState = {
61
+ /**
62
+ * Tracing active.
63
+ */
64
+ active: boolean;
65
+ /**
66
+ * The initially clicked coordinate.
67
+ */
68
+ startCoord?: import("../coordinate.js").Coordinate | undefined;
69
+ /**
70
+ * Targets available for tracing.
71
+ */
72
+ targets?: TraceTarget[] | undefined;
73
+ /**
74
+ * The index of the currently traced target. A value of -1 indicates
75
+ * that no trace target is active.
76
+ */
77
+ targetIndex?: number | undefined;
78
+ };
79
+ export type TraceTargetUpdateInfo = {
80
+ /**
81
+ * The new target index.
82
+ */
83
+ index: number;
84
+ /**
85
+ * The new segment end index.
86
+ */
87
+ endIndex: number;
88
+ /**
89
+ * The squared distance to the closest target.
90
+ */
91
+ closestTargetDistance: number;
92
+ };
93
+ export type PointSegmentRelationship = {
94
+ /**
95
+ * The closest point expressed as a fraction along the segment length.
96
+ */
97
+ along: number;
98
+ /**
99
+ * The squared distance of the point to the segment.
100
+ */
101
+ squaredDistance: number;
102
+ };
103
+ //# sourceMappingURL=tracing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["tracing.js"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,2CAJW,aAAa,SACb,MAAM,GACL,OAAO,kBAAkB,EAAE,UAAU,CAWhD;AAED;;;;GAIG;AACH,mDAJW,aAAa,SACb,MAAM,GACL,OAAO,kBAAkB,EAAE,UAAU,CA0BhD;AAoCD;;;;;;;GAOG;AACH,iDAPW,OAAO,kBAAkB,EAAE,UAAU,cACrC,UAAU,OACV,OAAO,WAAW,EAAE,OAAO,iBAC3B,MAAM,GACL,qBAAqB,CAqHhC;AAED;;;;GAIG;AACH,4CAJW,OAAO,kBAAkB,EAAE,UAAU,YACrC,KAAK,CAAC,OAAO,eAAe,EAAE,OAAO,CAAC,GACrC,KAAK,CAAC,WAAW,CAAC,CAe7B;AA+ID;;;;;;;GAOG;AACH,+CAPW,MAAM,KACN,MAAM,SACN,OAAO,kBAAkB,EAAE,UAAU,OACrC,OAAO,kBAAkB,EAAE,UAAU,GACpC,wBAAwB,CAsBnC;;;;4BAtZY,KAAK,CAAC,OAAO,kBAAkB,EAAE,UAAU,CAAC;;;;;iBA8D3C,KAAK,CAAC,OAAO,kBAAkB,EAAE,UAAU,CAAC;;;;UAC5C,OAAO;;;;;gBACP,MAAM;;;;cAEN,MAAM;;;;;;YAKN,OAAO;;;;;;;;;;;;;;;;;;;WASP,MAAM;;;;cACN,MAAM;;;;2BACN,MAAM;;;;;;WAgSN,MAAM;;;;qBACN,MAAM"}
@@ -0,0 +1,409 @@
1
+ /**
2
+ * Coordinate type when drawing lines.
3
+ * @typedef {Array<import("../coordinate.js").Coordinate>} LineCoordType
4
+ */
5
+
6
+ import {distance} from '../coordinate.js';
7
+ import {
8
+ GeometryCollection,
9
+ LineString,
10
+ MultiLineString,
11
+ MultiPolygon,
12
+ Polygon,
13
+ } from '../geom.js';
14
+ import {clamp, squaredDistance, toFixed} from '../math.js';
15
+
16
+ /**
17
+ * @param {LineCoordType} coordinates The ring coordinates.
18
+ * @param {number} index The index. May be wrapped.
19
+ * @return {import("../coordinate.js").Coordinate} The coordinate.
20
+ */
21
+ export function getCoordinate(coordinates, index) {
22
+ const count = coordinates.length;
23
+ if (index < 0) {
24
+ return coordinates[index + count];
25
+ }
26
+ if (index >= count) {
27
+ return coordinates[index - count];
28
+ }
29
+ return coordinates[index];
30
+ }
31
+
32
+ /**
33
+ * @param {LineCoordType} coordinates The coordinates.
34
+ * @param {number} index The index. May be fractional and may wrap.
35
+ * @return {import("../coordinate.js").Coordinate} The interpolated coordinate.
36
+ */
37
+ export function interpolateCoordinate(coordinates, index) {
38
+ const count = coordinates.length;
39
+
40
+ let startIndex = Math.floor(index);
41
+ const along = index - startIndex;
42
+ if (startIndex >= count) {
43
+ startIndex -= count;
44
+ } else if (startIndex < 0) {
45
+ startIndex += count;
46
+ }
47
+
48
+ let endIndex = startIndex + 1;
49
+ if (endIndex >= count) {
50
+ endIndex -= count;
51
+ }
52
+
53
+ const start = coordinates[startIndex];
54
+ const x0 = start[0];
55
+ const y0 = start[1];
56
+ const end = coordinates[endIndex];
57
+ const dx = end[0] - x0;
58
+ const dy = end[1] - y0;
59
+
60
+ return [x0 + dx * along, y0 + dy * along];
61
+ }
62
+
63
+ /**
64
+ * @typedef {Object} TraceTarget
65
+ * @property {Array<import("../coordinate.js").Coordinate>} coordinates Target coordinates.
66
+ * @property {boolean} ring The target coordinates are a linear ring.
67
+ * @property {number} startIndex The index of first traced coordinate. A fractional index represents an
68
+ * edge intersection. Index values for rings will wrap (may be negative or larger than coordinates length).
69
+ * @property {number} endIndex The index of last traced coordinate. Details from startIndex also apply here.
70
+ */
71
+
72
+ /**
73
+ * @typedef {Object} TraceState
74
+ * @property {boolean} active Tracing active.
75
+ * @property {import("../coordinate.js").Coordinate} [startCoord] The initially clicked coordinate.
76
+ * @property {Array<TraceTarget>} [targets] Targets available for tracing.
77
+ * @property {number} [targetIndex] The index of the currently traced target. A value of -1 indicates
78
+ * that no trace target is active.
79
+ */
80
+
81
+ /**
82
+ * @typedef {Object} TraceTargetUpdateInfo
83
+ * @property {number} index The new target index.
84
+ * @property {number} endIndex The new segment end index.
85
+ * @property {number} closestTargetDistance The squared distance to the closest target.
86
+ */
87
+
88
+ /**
89
+ * @type {TraceTargetUpdateInfo}
90
+ */
91
+ const sharedUpdateInfo = {
92
+ index: -1,
93
+ endIndex: NaN,
94
+ closestTargetDistance: Infinity,
95
+ };
96
+
97
+ /**
98
+ * @param {import("../coordinate.js").Coordinate} coordinate The coordinate.
99
+ * @param {TraceState} traceState The trace state.
100
+ * @param {import("../Map.js").default} map The map.
101
+ * @param {number} snapTolerance The snap tolerance.
102
+ * @return {TraceTargetUpdateInfo} Information about the new trace target. The returned
103
+ * object is reused between calls and must not be modified by the caller.
104
+ */
105
+ export function getTraceTargetUpdate(
106
+ coordinate,
107
+ traceState,
108
+ map,
109
+ snapTolerance,
110
+ ) {
111
+ const x = coordinate[0];
112
+ const y = coordinate[1];
113
+
114
+ let closestTargetDistance = Infinity;
115
+
116
+ let newTargetIndex = -1;
117
+ let newEndIndex = NaN;
118
+
119
+ for (
120
+ let targetIndex = 0;
121
+ targetIndex < traceState.targets.length;
122
+ ++targetIndex
123
+ ) {
124
+ const target = traceState.targets[targetIndex];
125
+ const coordinates = target.coordinates;
126
+
127
+ let minSegmentDistance = Infinity;
128
+ let endIndex;
129
+ for (
130
+ let coordinateIndex = 0;
131
+ coordinateIndex < coordinates.length - 1;
132
+ ++coordinateIndex
133
+ ) {
134
+ const start = coordinates[coordinateIndex];
135
+ const end = coordinates[coordinateIndex + 1];
136
+ const rel = getPointSegmentRelationship(x, y, start, end);
137
+ if (rel.squaredDistance < minSegmentDistance) {
138
+ minSegmentDistance = rel.squaredDistance;
139
+ endIndex = coordinateIndex + rel.along;
140
+ }
141
+ }
142
+
143
+ if (minSegmentDistance < closestTargetDistance) {
144
+ closestTargetDistance = minSegmentDistance;
145
+ if (target.ring && traceState.targetIndex === targetIndex) {
146
+ // same target, maintain the same trace direction
147
+ if (target.endIndex > target.startIndex) {
148
+ // forward trace
149
+ if (endIndex < target.startIndex) {
150
+ endIndex += coordinates.length;
151
+ }
152
+ } else if (target.endIndex < target.startIndex) {
153
+ // reverse trace
154
+ if (endIndex > target.startIndex) {
155
+ endIndex -= coordinates.length;
156
+ }
157
+ }
158
+ }
159
+ newEndIndex = endIndex;
160
+ newTargetIndex = targetIndex;
161
+ }
162
+ }
163
+
164
+ const newTarget = traceState.targets[newTargetIndex];
165
+ let considerBothDirections = newTarget.ring;
166
+ if (traceState.targetIndex === newTargetIndex && considerBothDirections) {
167
+ // only consider switching trace direction if close to the start
168
+ const newCoordinate = interpolateCoordinate(
169
+ newTarget.coordinates,
170
+ newEndIndex,
171
+ );
172
+ const pixel = map.getPixelFromCoordinate(newCoordinate);
173
+ const startPx = map.getPixelFromCoordinate(traceState.startCoord);
174
+ if (distance(pixel, startPx) > snapTolerance) {
175
+ considerBothDirections = false;
176
+ }
177
+ }
178
+
179
+ if (considerBothDirections) {
180
+ const coordinates = newTarget.coordinates;
181
+ const count = coordinates.length;
182
+ const startIndex = newTarget.startIndex;
183
+ const endIndex = newEndIndex;
184
+ if (startIndex < endIndex) {
185
+ const forwardDistance = getCumulativeSquaredDistance(
186
+ coordinates,
187
+ startIndex,
188
+ endIndex,
189
+ );
190
+ const reverseDistance = getCumulativeSquaredDistance(
191
+ coordinates,
192
+ startIndex,
193
+ endIndex - count,
194
+ );
195
+ if (reverseDistance < forwardDistance) {
196
+ newEndIndex -= count;
197
+ }
198
+ } else {
199
+ const reverseDistance = getCumulativeSquaredDistance(
200
+ coordinates,
201
+ startIndex,
202
+ endIndex,
203
+ );
204
+ const forwardDistance = getCumulativeSquaredDistance(
205
+ coordinates,
206
+ startIndex,
207
+ endIndex + count,
208
+ );
209
+ if (forwardDistance < reverseDistance) {
210
+ newEndIndex += count;
211
+ }
212
+ }
213
+ }
214
+
215
+ sharedUpdateInfo.index = newTargetIndex;
216
+ sharedUpdateInfo.endIndex = newEndIndex;
217
+ sharedUpdateInfo.closestTargetDistance = closestTargetDistance;
218
+ return sharedUpdateInfo;
219
+ }
220
+
221
+ /**
222
+ * @param {import("../coordinate.js").Coordinate} coordinate The coordinate.
223
+ * @param {Array<import("../Feature.js").default>} features The candidate features.
224
+ * @return {Array<TraceTarget>} The trace targets.
225
+ */
226
+ export function getTraceTargets(coordinate, features) {
227
+ /**
228
+ * @type {Array<TraceTarget>}
229
+ */
230
+ const targets = [];
231
+
232
+ for (let i = 0; i < features.length; ++i) {
233
+ const feature = features[i];
234
+ const geometry = feature.getGeometry();
235
+ appendGeometryTraceTargets(coordinate, geometry, targets);
236
+ }
237
+
238
+ return targets;
239
+ }
240
+
241
+ /**
242
+ * @param {import("../coordinate.js").Coordinate} coordinate The coordinate.
243
+ * @param {import("../geom/Geometry.js").default} geometry The candidate geometry.
244
+ * @param {Array<TraceTarget>} targets The trace targets.
245
+ */
246
+ function appendGeometryTraceTargets(coordinate, geometry, targets) {
247
+ if (geometry instanceof LineString) {
248
+ appendTraceTarget(coordinate, geometry.getCoordinates(), false, targets);
249
+ return;
250
+ }
251
+ if (geometry instanceof MultiLineString) {
252
+ const coordinates = geometry.getCoordinates();
253
+ for (let i = 0, ii = coordinates.length; i < ii; ++i) {
254
+ appendTraceTarget(coordinate, coordinates[i], false, targets);
255
+ }
256
+ return;
257
+ }
258
+ if (geometry instanceof Polygon) {
259
+ const coordinates = geometry.getCoordinates();
260
+ for (let i = 0, ii = coordinates.length; i < ii; ++i) {
261
+ appendTraceTarget(coordinate, coordinates[i], true, targets);
262
+ }
263
+ return;
264
+ }
265
+ if (geometry instanceof MultiPolygon) {
266
+ const polys = geometry.getCoordinates();
267
+ for (let i = 0, ii = polys.length; i < ii; ++i) {
268
+ const coordinates = polys[i];
269
+ for (let j = 0, jj = coordinates.length; j < jj; ++j) {
270
+ appendTraceTarget(coordinate, coordinates[j], true, targets);
271
+ }
272
+ }
273
+ return;
274
+ }
275
+ if (geometry instanceof GeometryCollection) {
276
+ const geometries = geometry.getGeometries();
277
+ for (let i = 0; i < geometries.length; ++i) {
278
+ appendGeometryTraceTargets(coordinate, geometries[i], targets);
279
+ }
280
+ return;
281
+ }
282
+ // other types cannot be traced
283
+ }
284
+
285
+ /**
286
+ * @param {import("../coordinate.js").Coordinate} coordinate The clicked coordinate.
287
+ * @param {Array<import("../coordinate.js").Coordinate>} coordinates The geometry component coordinates.
288
+ * @param {boolean} ring The coordinates represent a linear ring.
289
+ * @param {Array<TraceTarget>} targets The trace targets.
290
+ */
291
+ function appendTraceTarget(coordinate, coordinates, ring, targets) {
292
+ const x = coordinate[0];
293
+ const y = coordinate[1];
294
+ for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {
295
+ const start = coordinates[i];
296
+ const end = coordinates[i + 1];
297
+ const rel = getPointSegmentRelationship(x, y, start, end);
298
+ if (rel.squaredDistance === 0) {
299
+ const index = i + rel.along;
300
+ targets.push({
301
+ coordinates: coordinates,
302
+ ring: ring,
303
+ startIndex: index,
304
+ endIndex: index,
305
+ });
306
+ return;
307
+ }
308
+ }
309
+ }
310
+
311
+ /**
312
+ * @param {import("../coordinate.js").Coordinate} a One coordinate.
313
+ * @param {import("../coordinate.js").Coordinate} b Another coordinate.
314
+ * @return {number} The squared distance between the two coordinates.
315
+ */
316
+ function getSquaredDistance(a, b) {
317
+ return squaredDistance(a[0], a[1], b[0], b[1]);
318
+ }
319
+
320
+ /**
321
+ * Get the cumulative squared distance along a ring path. The end index index may be "wrapped" and it may
322
+ * be less than the start index to indicate the direction of travel. The start and end index may have
323
+ * a fractional part to indicate a point between two coordinates.
324
+ * @param {LineCoordType} coordinates Ring coordinates.
325
+ * @param {number} startIndex The start index.
326
+ * @param {number} endIndex The end index.
327
+ * @return {number} The cumulative squared distance along the ring path.
328
+ */
329
+ function getCumulativeSquaredDistance(coordinates, startIndex, endIndex) {
330
+ let lowIndex, highIndex;
331
+ if (startIndex < endIndex) {
332
+ lowIndex = startIndex;
333
+ highIndex = endIndex;
334
+ } else {
335
+ lowIndex = endIndex;
336
+ highIndex = startIndex;
337
+ }
338
+ const lowWholeIndex = Math.ceil(lowIndex);
339
+ const highWholeIndex = Math.floor(highIndex);
340
+
341
+ if (lowWholeIndex > highWholeIndex) {
342
+ // both start and end are on the same segment
343
+ const start = interpolateCoordinate(coordinates, lowIndex);
344
+ const end = interpolateCoordinate(coordinates, highIndex);
345
+ return getSquaredDistance(start, end);
346
+ }
347
+
348
+ let sd = 0;
349
+
350
+ if (lowIndex < lowWholeIndex) {
351
+ const start = interpolateCoordinate(coordinates, lowIndex);
352
+ const end = getCoordinate(coordinates, lowWholeIndex);
353
+ sd += getSquaredDistance(start, end);
354
+ }
355
+
356
+ if (highWholeIndex < highIndex) {
357
+ const start = getCoordinate(coordinates, highWholeIndex);
358
+ const end = interpolateCoordinate(coordinates, highIndex);
359
+ sd += getSquaredDistance(start, end);
360
+ }
361
+
362
+ for (let i = lowWholeIndex; i < highWholeIndex - 1; ++i) {
363
+ const start = getCoordinate(coordinates, i);
364
+ const end = getCoordinate(coordinates, i + 1);
365
+ sd += getSquaredDistance(start, end);
366
+ }
367
+
368
+ return sd;
369
+ }
370
+
371
+ /**
372
+ * @typedef {Object} PointSegmentRelationship
373
+ * @property {number} along The closest point expressed as a fraction along the segment length.
374
+ * @property {number} squaredDistance The squared distance of the point to the segment.
375
+ */
376
+
377
+ /**
378
+ * @type {PointSegmentRelationship}
379
+ */
380
+ const sharedRel = {along: 0, squaredDistance: 0};
381
+
382
+ /**
383
+ * @param {number} x The point x.
384
+ * @param {number} y The point y.
385
+ * @param {import("../coordinate.js").Coordinate} start The segment start.
386
+ * @param {import("../coordinate.js").Coordinate} end The segment end.
387
+ * @return {PointSegmentRelationship} The point segment relationship. The returned object is
388
+ * shared between calls and must not be modified by the caller.
389
+ */
390
+ export function getPointSegmentRelationship(x, y, start, end) {
391
+ const x1 = start[0];
392
+ const y1 = start[1];
393
+ const x2 = end[0];
394
+ const y2 = end[1];
395
+ const dx = x2 - x1;
396
+ const dy = y2 - y1;
397
+ let along = 0;
398
+ let px = x1;
399
+ let py = y1;
400
+ if (dx !== 0 || dy !== 0) {
401
+ along = clamp(((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy), 0, 1);
402
+ px += dx * along;
403
+ py += dy * along;
404
+ }
405
+
406
+ sharedRel.along = along;
407
+ sharedRel.squaredDistance = toFixed(squaredDistance(x, y, px, py), 10);
408
+ return sharedRel;
409
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ol",
3
- "version": "10.6.2-dev.1753992384159",
3
+ "version": "10.6.2-dev.1753992411402",
4
4
  "description": "OpenLayers mapping library",
5
5
  "keywords": [
6
6
  "map",
package/util.js CHANGED
@@ -33,4 +33,4 @@ export function getUid(obj) {
33
33
  * OpenLayers version.
34
34
  * @type {string}
35
35
  */
36
- export const VERSION = '10.6.2-dev.1753992384159';
36
+ export const VERSION = '10.6.2-dev.1753992411402';