ol 10.6.2-dev.1753985579298 → 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.
- package/dist/ol.js +1 -1
- package/dist/ol.js.map +1 -1
- package/interaction/Draw.d.ts +3 -62
- package/interaction/Draw.d.ts.map +1 -1
- package/interaction/Draw.js +12 -387
- package/interaction/Modify.d.ts +93 -59
- package/interaction/Modify.d.ts.map +1 -1
- package/interaction/Modify.js +486 -94
- package/interaction/tracing.d.ts +103 -0
- package/interaction/tracing.d.ts.map +1 -0
- package/interaction/tracing.js +409 -0
- package/layer/Group.d.ts +7 -5
- package/layer/Group.d.ts.map +1 -1
- package/layer/Group.js +33 -10
- package/package.json +1 -1
- package/util.js +1 -1
|
@@ -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/layer/Group.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {'addlayer'|'removelayer'} GroupEventType
|
|
3
|
-
*/
|
|
4
1
|
/**
|
|
5
2
|
* @classdesc
|
|
6
3
|
* A layer group triggers 'addlayer' and 'removelayer' events when layers are added to or removed from
|
|
@@ -21,11 +18,10 @@ export class GroupEvent extends Event {
|
|
|
21
18
|
layer: BaseLayer;
|
|
22
19
|
}
|
|
23
20
|
export default LayerGroup;
|
|
24
|
-
export type GroupEventType = "addlayer" | "removelayer";
|
|
25
21
|
/**
|
|
26
22
|
* *
|
|
27
23
|
*/
|
|
28
|
-
export type GroupOnSignature<Return> = import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> & import("../Observable").OnSignature<import("./Base").BaseLayerObjectEventTypes | "change:layers", import("../Object").ObjectEvent, Return> & import("../Observable").CombinedOnSignature<import("../Observable").EventTypes | import("./Base").BaseLayerObjectEventTypes | "change:layers", Return>;
|
|
24
|
+
export type GroupOnSignature<Return> = import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> & import("../Observable").OnSignature<import("./Base").BaseLayerObjectEventTypes | "change:layers", import("../Object").ObjectEvent, Return> & import("../Observable").OnSignature<"addlayer" | "removelayer", GroupEvent, Return> & import("../Observable").CombinedOnSignature<import("../Observable").EventTypes | import("./Base").BaseLayerObjectEventTypes | "addlayer" | "removelayer" | "change:layers", Return>;
|
|
29
25
|
export type Options = {
|
|
30
26
|
/**
|
|
31
27
|
* Opacity (0, 1).
|
|
@@ -80,12 +76,18 @@ export type Options = {
|
|
|
80
76
|
};
|
|
81
77
|
import Event from '../events/Event.js';
|
|
82
78
|
import BaseLayer from './Base.js';
|
|
79
|
+
type GroupEventType = string;
|
|
80
|
+
declare namespace GroupEventType {
|
|
81
|
+
let ADDLAYER: string;
|
|
82
|
+
let REMOVELAYER: string;
|
|
83
|
+
}
|
|
83
84
|
/**
|
|
84
85
|
* @classdesc
|
|
85
86
|
* A {@link module:ol/Collection~Collection} of layers that are handled together.
|
|
86
87
|
*
|
|
87
88
|
* A generic `change` event is triggered when the group/Collection changes.
|
|
88
89
|
*
|
|
90
|
+
* @fires GroupEvent
|
|
89
91
|
* @api
|
|
90
92
|
*/
|
|
91
93
|
declare class LayerGroup extends BaseLayer {
|
package/layer/Group.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Group.d.ts","sourceRoot":"","sources":["Group.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Group.d.ts","sourceRoot":"","sources":["Group.js"],"names":[],"mappings":"AAiCA;;;;;GAKG;AACH;IACE;;;OAGG;IACH,kBAHW,cAAc,SACd,SAAS,EAWnB;IANC;;;;OAIG;IACH,OAHU,SAAS,CAGD;CAErB;;;;;6BAGY,MAAM,IACN,OAAO,eAAe,EAAE,WAAW,CAAC,OAAO,eAAe,EAAE,UAAU,EAAE,OAAO,oBAAoB,EAAE,OAAO,EAAE,MAAM,CAAC,GACjI,OAAW,eAAe,EAAE,WAAW,CAAC,OAAO,QAAQ,EAAE,yBAAyB,GAClF,eAAqB,EAAE,OAAO,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,GAC/D,OAAW,eAAe,EAAE,WAAW,CAAC,UAAU,GAAC,aAAa,EAAE,UAAU,EAAE,MAAM,CAAC,GACrF,OAAW,eAAe,EAAE,mBAAmB,CAAC,OAAO,eAAe,EAAE,UAAU,GAAC,OAAO,QAAQ,EAAE,yBAAyB,GAAC,UAAU,GAAC,aAAa,GAAC,eAAe,EAAE,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAvD9J,oBAAoB;sBAMhB,WAAW;sBAGvB,MAAM;;;;;AA+EhB;;;;;;;;GAQG;AACH;IACE;;OAEG;IACH,sBAFW,OAAO,EAsDjB;IA3CC;;OAEG;IACH,IAFU,gBAAgB,CAAC,OAAO,WAAW,EAAE,SAAS,CAAC,CAElD;IAEP;;OAEG;IACH,MAFU,gBAAgB,CAAC,OAAO,WAAW,EAAE,SAAS,CAAC,CAEhD;IAET;;OAEG;IACH,IAFU,gBAAgB,CAAC,IAAI,CAAC,CAEzB;IAEP;;;OAGG;IACH,4BAA6B;IAE7B;;;OAGG;IACH,sBAAuB;IAoBzB;;OAEG;IACH,2BAEC;IAED;;OAEG;IACH,6BA2BC;IAED;;OAEG;IACH,+BAFW,SAAS,QA0BnB;IAED;;OAEG;IACH,4BAFW,UAAU,QAIpB;IAED;;OAEG;IACH,+BAFW,UAAU,QAIpB;IAED;;;OAGG;IACH,yBAKC;IAED;;;OAGG;IACH,4BAOC;IAED;;;;;;;OAOG;IACH,aALa,UAAU,CAAC,OAAO,WAAW,EAAE,OAAO,CAAC,CASnD;IAED;;;;;;;OAOG;IACH,kBALY,UAAU,CAAC,OAAO,WAAW,EAAE,OAAO,CAAC,QAiBlD;CA6EF;uBAxXsB,kBAAkB"}
|
package/layer/Group.js
CHANGED
|
@@ -14,8 +14,22 @@ import {getUid} from '../util.js';
|
|
|
14
14
|
import BaseLayer from './Base.js';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* @
|
|
17
|
+
* @enum {string}
|
|
18
18
|
*/
|
|
19
|
+
const GroupEventType = {
|
|
20
|
+
/**
|
|
21
|
+
* Triggered when a layer is added
|
|
22
|
+
* @event GroupEvent#addlayer
|
|
23
|
+
* @api
|
|
24
|
+
*/
|
|
25
|
+
ADDLAYER: 'addlayer',
|
|
26
|
+
/**
|
|
27
|
+
* Triggered when a layer is removed
|
|
28
|
+
* @event GroupEvent#removelayer
|
|
29
|
+
* @api
|
|
30
|
+
*/
|
|
31
|
+
REMOVELAYER: 'removelayer',
|
|
32
|
+
};
|
|
19
33
|
|
|
20
34
|
/**
|
|
21
35
|
* @classdesc
|
|
@@ -45,7 +59,8 @@ export class GroupEvent extends Event {
|
|
|
45
59
|
* @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
|
|
46
60
|
* import("../Observable").OnSignature<import("./Base").BaseLayerObjectEventTypes|
|
|
47
61
|
* 'change:layers', import("../Object").ObjectEvent, Return> &
|
|
48
|
-
* import("../Observable").
|
|
62
|
+
* import("../Observable").OnSignature<'addlayer'|'removelayer', GroupEvent, Return> &
|
|
63
|
+
* import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("./Base").BaseLayerObjectEventTypes|'addlayer'|'removelayer'|'change:layers', Return>} GroupOnSignature
|
|
49
64
|
*/
|
|
50
65
|
|
|
51
66
|
/**
|
|
@@ -84,6 +99,7 @@ const Property = {
|
|
|
84
99
|
*
|
|
85
100
|
* A generic `change` event is triggered when the group/Collection changes.
|
|
86
101
|
*
|
|
102
|
+
* @fires GroupEvent
|
|
87
103
|
* @api
|
|
88
104
|
*/
|
|
89
105
|
class LayerGroup extends BaseLayer {
|
|
@@ -178,7 +194,7 @@ class LayerGroup extends BaseLayer {
|
|
|
178
194
|
for (let i = 0, ii = layersArray.length; i < ii; i++) {
|
|
179
195
|
const layer = layersArray[i];
|
|
180
196
|
this.registerLayerListeners_(layer);
|
|
181
|
-
this.dispatchEvent(new GroupEvent(
|
|
197
|
+
this.dispatchEvent(new GroupEvent(GroupEventType.ADDLAYER, layer));
|
|
182
198
|
}
|
|
183
199
|
this.changed();
|
|
184
200
|
}
|
|
@@ -199,8 +215,13 @@ class LayerGroup extends BaseLayer {
|
|
|
199
215
|
|
|
200
216
|
if (layer instanceof LayerGroup) {
|
|
201
217
|
listenerKeys.push(
|
|
202
|
-
listen(layer,
|
|
203
|
-
listen(
|
|
218
|
+
listen(layer, GroupEventType.ADDLAYER, this.handleLayerGroupAdd_, this),
|
|
219
|
+
listen(
|
|
220
|
+
layer,
|
|
221
|
+
GroupEventType.REMOVELAYER,
|
|
222
|
+
this.handleLayerGroupRemove_,
|
|
223
|
+
this,
|
|
224
|
+
),
|
|
204
225
|
);
|
|
205
226
|
}
|
|
206
227
|
|
|
@@ -211,14 +232,14 @@ class LayerGroup extends BaseLayer {
|
|
|
211
232
|
* @param {GroupEvent} event The layer group event.
|
|
212
233
|
*/
|
|
213
234
|
handleLayerGroupAdd_(event) {
|
|
214
|
-
this.dispatchEvent(new GroupEvent(
|
|
235
|
+
this.dispatchEvent(new GroupEvent(GroupEventType.ADDLAYER, event.layer));
|
|
215
236
|
}
|
|
216
237
|
|
|
217
238
|
/**
|
|
218
239
|
* @param {GroupEvent} event The layer group event.
|
|
219
240
|
*/
|
|
220
241
|
handleLayerGroupRemove_(event) {
|
|
221
|
-
this.dispatchEvent(new GroupEvent(
|
|
242
|
+
this.dispatchEvent(new GroupEvent(GroupEventType.REMOVELAYER, event.layer));
|
|
222
243
|
}
|
|
223
244
|
|
|
224
245
|
/**
|
|
@@ -228,7 +249,7 @@ class LayerGroup extends BaseLayer {
|
|
|
228
249
|
handleLayersAdd_(collectionEvent) {
|
|
229
250
|
const layer = collectionEvent.element;
|
|
230
251
|
this.registerLayerListeners_(layer);
|
|
231
|
-
this.dispatchEvent(new GroupEvent(
|
|
252
|
+
this.dispatchEvent(new GroupEvent(GroupEventType.ADDLAYER, layer));
|
|
232
253
|
this.changed();
|
|
233
254
|
}
|
|
234
255
|
|
|
@@ -241,7 +262,7 @@ class LayerGroup extends BaseLayer {
|
|
|
241
262
|
const key = getUid(layer);
|
|
242
263
|
this.listenerKeys_[key].forEach(unlistenByKey);
|
|
243
264
|
delete this.listenerKeys_[key];
|
|
244
|
-
this.dispatchEvent(new GroupEvent(
|
|
265
|
+
this.dispatchEvent(new GroupEvent(GroupEventType.REMOVELAYER, layer));
|
|
245
266
|
this.changed();
|
|
246
267
|
}
|
|
247
268
|
|
|
@@ -272,7 +293,9 @@ class LayerGroup extends BaseLayer {
|
|
|
272
293
|
if (collection) {
|
|
273
294
|
const currentLayers = collection.getArray();
|
|
274
295
|
for (let i = 0, ii = currentLayers.length; i < ii; ++i) {
|
|
275
|
-
this.dispatchEvent(
|
|
296
|
+
this.dispatchEvent(
|
|
297
|
+
new GroupEvent(GroupEventType.REMOVELAYER, currentLayers[i]),
|
|
298
|
+
);
|
|
276
299
|
}
|
|
277
300
|
}
|
|
278
301
|
|
package/package.json
CHANGED
package/util.js
CHANGED