ol 7.0.1-dev.1661277132609 → 7.0.1-dev.1661440420569
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/interaction/Draw.d.ts +131 -0
- package/interaction/Draw.d.ts.map +1 -1
- package/interaction/Draw.js +721 -58
- package/package.json +1 -1
- package/renderer/canvas/TileLayer.d.ts.map +1 -1
- package/renderer/canvas/TileLayer.js +4 -1
- package/renderer/webgl/TileLayer.d.ts +2 -1
- package/renderer/webgl/TileLayer.d.ts.map +1 -1
- package/renderer/webgl/TileLayer.js +44 -6
- package/util.js +1 -1
package/interaction/Draw.d.ts
CHANGED
|
@@ -131,6 +131,17 @@ export type Options = {
|
|
|
131
131
|
* Shift key activates freehand drawing.
|
|
132
132
|
*/
|
|
133
133
|
freehandCondition?: import("../events/condition.js").Condition | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* Trace a portion of another geometry.
|
|
136
|
+
* Ignored when in freehand mode.
|
|
137
|
+
*/
|
|
138
|
+
trace?: boolean | import("../events/condition.js").Condition | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* Source for features to trace. If tracing is active and a `traceSource` is
|
|
141
|
+
* not provided, the interaction's `source` will be used. Tracing requires that the interaction is configured with
|
|
142
|
+
* either a `traceSource` or a `source`.
|
|
143
|
+
*/
|
|
144
|
+
traceSource?: VectorSource<import("../geom/Geometry.js").default> | undefined;
|
|
134
145
|
/**
|
|
135
146
|
* Wrap the world horizontally on the sketch
|
|
136
147
|
* overlay.
|
|
@@ -158,6 +169,44 @@ export type PolyCoordType = Array<Array<import("../coordinate.js").Coordinate>>;
|
|
|
158
169
|
* Types used for drawing coordinates.
|
|
159
170
|
*/
|
|
160
171
|
export type SketchCoordType = number[] | LineCoordType | PolyCoordType;
|
|
172
|
+
export type TraceState = {
|
|
173
|
+
/**
|
|
174
|
+
* Tracing active.
|
|
175
|
+
*/
|
|
176
|
+
active: boolean;
|
|
177
|
+
/**
|
|
178
|
+
* The initially clicked pixel location.
|
|
179
|
+
*/
|
|
180
|
+
startPx?: import("../pixel.js").Pixel | undefined;
|
|
181
|
+
/**
|
|
182
|
+
* Targets available for tracing.
|
|
183
|
+
*/
|
|
184
|
+
targets?: TraceTarget[] | undefined;
|
|
185
|
+
/**
|
|
186
|
+
* The index of the currently traced target. A value of -1 indicates
|
|
187
|
+
* that no trace target is active.
|
|
188
|
+
*/
|
|
189
|
+
targetIndex?: number | undefined;
|
|
190
|
+
};
|
|
191
|
+
export type TraceTarget = {
|
|
192
|
+
/**
|
|
193
|
+
* Target coordinates.
|
|
194
|
+
*/
|
|
195
|
+
coordinates: Array<import("../coordinate.js").Coordinate>;
|
|
196
|
+
/**
|
|
197
|
+
* The target coordinates are a linear ring.
|
|
198
|
+
*/
|
|
199
|
+
ring: boolean;
|
|
200
|
+
/**
|
|
201
|
+
* The index of first traced coordinate. A fractional index represents an
|
|
202
|
+
* edge intersection. Index values for rings will wrap (may be negative or larger than coordinates length).
|
|
203
|
+
*/
|
|
204
|
+
startIndex: number;
|
|
205
|
+
/**
|
|
206
|
+
* The index of last traced coordinate. Details from startIndex also apply here.
|
|
207
|
+
*/
|
|
208
|
+
endIndex: number;
|
|
209
|
+
};
|
|
161
210
|
/**
|
|
162
211
|
* Function that takes an array of coordinates and an optional existing geometry
|
|
163
212
|
* and a projection as arguments, and returns a geometry. The optional existing
|
|
@@ -170,6 +219,26 @@ export type GeometryFunction = (arg0: SketchCoordType, arg1: import("../geom/Sim
|
|
|
170
219
|
* cousins.
|
|
171
220
|
*/
|
|
172
221
|
export type Mode = 'Point' | 'LineString' | 'Polygon' | 'Circle';
|
|
222
|
+
export type TraceTargetUpdateInfo = {
|
|
223
|
+
/**
|
|
224
|
+
* The new target index.
|
|
225
|
+
*/
|
|
226
|
+
index: number;
|
|
227
|
+
/**
|
|
228
|
+
* The new segment end index.
|
|
229
|
+
*/
|
|
230
|
+
endIndex: number;
|
|
231
|
+
};
|
|
232
|
+
export type PointSegmentRelationship = {
|
|
233
|
+
/**
|
|
234
|
+
* The closest point expressed as a fraction along the segment length.
|
|
235
|
+
*/
|
|
236
|
+
along: number;
|
|
237
|
+
/**
|
|
238
|
+
* The squared distance of the point to the segment.
|
|
239
|
+
*/
|
|
240
|
+
squaredDistance: number;
|
|
241
|
+
};
|
|
173
242
|
/**
|
|
174
243
|
* *
|
|
175
244
|
*/
|
|
@@ -386,6 +455,28 @@ declare class Draw extends PointerInteraction {
|
|
|
386
455
|
* @type {import("../events/condition.js").Condition}
|
|
387
456
|
*/
|
|
388
457
|
private freehandCondition_;
|
|
458
|
+
/**
|
|
459
|
+
* @type {import("../events/condition.js").Condition}
|
|
460
|
+
* @private
|
|
461
|
+
*/
|
|
462
|
+
private traceCondition_;
|
|
463
|
+
/**
|
|
464
|
+
* @type {TraceState}
|
|
465
|
+
* @private
|
|
466
|
+
*/
|
|
467
|
+
private traceState_;
|
|
468
|
+
/**
|
|
469
|
+
* @type {VectorSource|null}
|
|
470
|
+
* @private
|
|
471
|
+
*/
|
|
472
|
+
private traceSource_;
|
|
473
|
+
/**
|
|
474
|
+
* Toggle tracing mode or set a tracing condition.
|
|
475
|
+
*
|
|
476
|
+
* @param {boolean|import("../events/condition.js").Condition} trace A boolean to toggle tracing mode or an event
|
|
477
|
+
* condition that will be checked when a feature is clicked to determine if tracing should be active.
|
|
478
|
+
*/
|
|
479
|
+
setTrace(trace: boolean | import("../events/condition.js").Condition): void;
|
|
389
480
|
/**
|
|
390
481
|
* Remove the interaction from its current map and attach it to the new map.
|
|
391
482
|
* Subclasses may set up event handlers to get notified about changes to
|
|
@@ -399,6 +490,41 @@ declare class Draw extends PointerInteraction {
|
|
|
399
490
|
* @api
|
|
400
491
|
*/
|
|
401
492
|
getOverlay(): VectorLayer<any>;
|
|
493
|
+
/**
|
|
494
|
+
* @private
|
|
495
|
+
*/
|
|
496
|
+
private deactivateTrace_;
|
|
497
|
+
/**
|
|
498
|
+
* Activate or deactivate trace state based on a browser event.
|
|
499
|
+
* @param {import("../MapBrowserEvent.js").default} event Event.
|
|
500
|
+
* @private
|
|
501
|
+
*/
|
|
502
|
+
private toggleTraceState_;
|
|
503
|
+
/**
|
|
504
|
+
* @param {TraceTarget} target The trace target.
|
|
505
|
+
* @param {number} endIndex The new end index of the trace.
|
|
506
|
+
* @private
|
|
507
|
+
*/
|
|
508
|
+
private addOrRemoveTracedCoordinates_;
|
|
509
|
+
/**
|
|
510
|
+
* @param {number} fromIndex The start index.
|
|
511
|
+
* @param {number} toIndex The end index.
|
|
512
|
+
* @private
|
|
513
|
+
*/
|
|
514
|
+
private removeTracedCoordinates_;
|
|
515
|
+
/**
|
|
516
|
+
* @param {TraceTarget} target The trace target.
|
|
517
|
+
* @param {number} fromIndex The start index.
|
|
518
|
+
* @param {number} toIndex The end index.
|
|
519
|
+
* @private
|
|
520
|
+
*/
|
|
521
|
+
private addTracedCoordinates_;
|
|
522
|
+
/**
|
|
523
|
+
* Update the trace.
|
|
524
|
+
* @param {import("../MapBrowserEvent.js").default} event Event.
|
|
525
|
+
* @private
|
|
526
|
+
*/
|
|
527
|
+
private updateTrace_;
|
|
402
528
|
/**
|
|
403
529
|
* Handle move events.
|
|
404
530
|
* @param {import("../MapBrowserEvent.js").default} event A move event.
|
|
@@ -408,6 +534,7 @@ declare class Draw extends PointerInteraction {
|
|
|
408
534
|
/**
|
|
409
535
|
* Determine if an event is within the snapping tolerance of the start coord.
|
|
410
536
|
* @param {import("../pixel.js").Pixel} pixel Pixel.
|
|
537
|
+
* @param {boolean} [tracing] Drawing in trace mode (only stop if at the starting point).
|
|
411
538
|
* @return {boolean} The event is within the snapping tolerance of the start.
|
|
412
539
|
* @private
|
|
413
540
|
*/
|
|
@@ -440,6 +567,10 @@ declare class Draw extends PointerInteraction {
|
|
|
440
567
|
* @private
|
|
441
568
|
*/
|
|
442
569
|
private addToDrawing_;
|
|
570
|
+
/**
|
|
571
|
+
* @param {number} n The number of points to remove.
|
|
572
|
+
*/
|
|
573
|
+
removeLastPoints_(n: number): void;
|
|
443
574
|
/**
|
|
444
575
|
* Remove last point of the feature currently being drawn. Does not do anything when
|
|
445
576
|
* drawing POINT or MULTI_POINT geometries.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Draw.d.ts","sourceRoot":"","sources":["Draw.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Draw.d.ts","sourceRoot":"","sources":["Draw.js"],"names":[],"mappings":"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"}
|
package/interaction/Draw.js
CHANGED
|
@@ -5,6 +5,7 @@ import Circle from '../geom/Circle.js';
|
|
|
5
5
|
import Event from '../events/Event.js';
|
|
6
6
|
import EventType from '../events/EventType.js';
|
|
7
7
|
import Feature from '../Feature.js';
|
|
8
|
+
import GeometryCollection from '../geom/GeometryCollection.js';
|
|
8
9
|
import InteractionProperty from './Property.js';
|
|
9
10
|
import LineString from '../geom/LineString.js';
|
|
10
11
|
import MapBrowserEvent from '../MapBrowserEvent.js';
|
|
@@ -18,7 +19,12 @@ import Polygon, {fromCircle, makeRegular} from '../geom/Polygon.js';
|
|
|
18
19
|
import VectorLayer from '../layer/Vector.js';
|
|
19
20
|
import VectorSource from '../source/Vector.js';
|
|
20
21
|
import {FALSE, TRUE} from '../functions.js';
|
|
21
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
always,
|
|
24
|
+
never,
|
|
25
|
+
noModifierKeys,
|
|
26
|
+
shiftKeyOnly,
|
|
27
|
+
} from '../events/condition.js';
|
|
22
28
|
import {
|
|
23
29
|
boundingExtent,
|
|
24
30
|
getBottomLeft,
|
|
@@ -26,10 +32,14 @@ import {
|
|
|
26
32
|
getTopLeft,
|
|
27
33
|
getTopRight,
|
|
28
34
|
} from '../extent.js';
|
|
35
|
+
import {clamp, squaredDistance, toFixed} from '../math.js';
|
|
29
36
|
import {createEditingStyle} from '../style/Style.js';
|
|
37
|
+
import {
|
|
38
|
+
distance,
|
|
39
|
+
squaredDistance as squaredCoordinateDistance,
|
|
40
|
+
} from '../coordinate.js';
|
|
30
41
|
import {fromUserCoordinate, getUserProjection} from '../proj.js';
|
|
31
42
|
import {getStrideForLayout} from '../geom/SimpleGeometry.js';
|
|
32
|
-
import {squaredDistance as squaredCoordinateDistance} from '../coordinate.js';
|
|
33
43
|
|
|
34
44
|
/**
|
|
35
45
|
* @typedef {Object} Options
|
|
@@ -80,6 +90,11 @@ import {squaredDistance as squaredCoordinateDistance} from '../coordinate.js';
|
|
|
80
90
|
* returns a boolean to indicate whether that event should be handled. The
|
|
81
91
|
* default is {@link module:ol/events/condition.shiftKeyOnly}, meaning that the
|
|
82
92
|
* Shift key activates freehand drawing.
|
|
93
|
+
* @property {boolean|import("../events/condition.js").Condition} [trace=false] Trace a portion of another geometry.
|
|
94
|
+
* Ignored when in freehand mode.
|
|
95
|
+
* @property {VectorSource} [traceSource] Source for features to trace. If tracing is active and a `traceSource` is
|
|
96
|
+
* not provided, the interaction's `source` will be used. Tracing requires that the interaction is configured with
|
|
97
|
+
* either a `traceSource` or a `source`.
|
|
83
98
|
* @property {boolean} [wrapX=false] Wrap the world horizontally on the sketch
|
|
84
99
|
* overlay.
|
|
85
100
|
* @property {import("../geom/Geometry.js").GeometryLayout} [geometryLayout='XY'] Layout of the
|
|
@@ -106,6 +121,24 @@ import {squaredDistance as squaredCoordinateDistance} from '../coordinate.js';
|
|
|
106
121
|
* @typedef {PointCoordType|LineCoordType|PolyCoordType} SketchCoordType
|
|
107
122
|
*/
|
|
108
123
|
|
|
124
|
+
/**
|
|
125
|
+
* @typedef {Object} TraceState
|
|
126
|
+
* @property {boolean} active Tracing active.
|
|
127
|
+
* @property {import("../pixel.js").Pixel} [startPx] The initially clicked pixel location.
|
|
128
|
+
* @property {Array<TraceTarget>} [targets] Targets available for tracing.
|
|
129
|
+
* @property {number} [targetIndex] The index of the currently traced target. A value of -1 indicates
|
|
130
|
+
* that no trace target is active.
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @typedef {Object} TraceTarget
|
|
135
|
+
* @property {Array<import("../coordinate.js").Coordinate>} coordinates Target coordinates.
|
|
136
|
+
* @property {boolean} ring The target coordinates are a linear ring.
|
|
137
|
+
* @property {number} startIndex The index of first traced coordinate. A fractional index represents an
|
|
138
|
+
* edge intersection. Index values for rings will wrap (may be negative or larger than coordinates length).
|
|
139
|
+
* @property {number} endIndex The index of last traced coordinate. Details from startIndex also apply here.
|
|
140
|
+
*/
|
|
141
|
+
|
|
109
142
|
/**
|
|
110
143
|
* Function that takes an array of coordinates and an optional existing geometry
|
|
111
144
|
* and a projection as arguments, and returns a geometry. The optional existing
|
|
@@ -168,6 +201,359 @@ export class DrawEvent extends Event {
|
|
|
168
201
|
}
|
|
169
202
|
}
|
|
170
203
|
|
|
204
|
+
/**
|
|
205
|
+
* @param {import("../coordinate.js").Coordinate} coordinate The coordinate.
|
|
206
|
+
* @param {Array<Feature>} features The candidate features.
|
|
207
|
+
* @return {Array<TraceTarget>} The trace targets.
|
|
208
|
+
*/
|
|
209
|
+
function getTraceTargets(coordinate, features) {
|
|
210
|
+
/**
|
|
211
|
+
* @type {Array<TraceTarget>}
|
|
212
|
+
*/
|
|
213
|
+
const targets = [];
|
|
214
|
+
|
|
215
|
+
for (let i = 0; i < features.length; ++i) {
|
|
216
|
+
const feature = features[i];
|
|
217
|
+
const geometry = feature.getGeometry();
|
|
218
|
+
appendGeometryTraceTargets(coordinate, geometry, targets);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return targets;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @param {import("../coordinate.js").Coordinate} a One coordinate.
|
|
226
|
+
* @param {import("../coordinate.js").Coordinate} b Another coordinate.
|
|
227
|
+
* @return {number} The squared distance between the two coordinates.
|
|
228
|
+
*/
|
|
229
|
+
function getSquaredDistance(a, b) {
|
|
230
|
+
return squaredDistance(a[0], a[1], b[0], b[1]);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* @param {LineCoordType} coordinates The ring coordinates.
|
|
235
|
+
* @param {number} index The index. May be wrapped.
|
|
236
|
+
* @return {import("../coordinate.js").Coordinate} The coordinate.
|
|
237
|
+
*/
|
|
238
|
+
function getCoordinate(coordinates, index) {
|
|
239
|
+
const count = coordinates.length;
|
|
240
|
+
if (index < 0) {
|
|
241
|
+
return coordinates[index + count];
|
|
242
|
+
}
|
|
243
|
+
if (index >= count) {
|
|
244
|
+
return coordinates[index - count];
|
|
245
|
+
}
|
|
246
|
+
return coordinates[index];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Get the cumulative squared distance along a ring path. The end index index may be "wrapped" and it may
|
|
251
|
+
* be less than the start index to indicate the direction of travel. The start and end index may have
|
|
252
|
+
* a fractional part to indicate a point between two coordinates.
|
|
253
|
+
* @param {LineCoordType} coordinates Ring coordinates.
|
|
254
|
+
* @param {number} startIndex The start index.
|
|
255
|
+
* @param {number} endIndex The end index.
|
|
256
|
+
* @return {number} The cumulative squared distance along the ring path.
|
|
257
|
+
*/
|
|
258
|
+
function getCumulativeSquaredDistance(coordinates, startIndex, endIndex) {
|
|
259
|
+
let lowIndex, highIndex;
|
|
260
|
+
if (startIndex < endIndex) {
|
|
261
|
+
lowIndex = startIndex;
|
|
262
|
+
highIndex = endIndex;
|
|
263
|
+
} else {
|
|
264
|
+
lowIndex = endIndex;
|
|
265
|
+
highIndex = startIndex;
|
|
266
|
+
}
|
|
267
|
+
const lowWholeIndex = Math.ceil(lowIndex);
|
|
268
|
+
const highWholeIndex = Math.floor(highIndex);
|
|
269
|
+
|
|
270
|
+
if (lowWholeIndex > highWholeIndex) {
|
|
271
|
+
// both start and end are on the same segment
|
|
272
|
+
const start = interpolateCoordinate(coordinates, lowIndex);
|
|
273
|
+
const end = interpolateCoordinate(coordinates, highIndex);
|
|
274
|
+
return getSquaredDistance(start, end);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
let sd = 0;
|
|
278
|
+
|
|
279
|
+
if (lowIndex < lowWholeIndex) {
|
|
280
|
+
const start = interpolateCoordinate(coordinates, lowIndex);
|
|
281
|
+
const end = getCoordinate(coordinates, lowWholeIndex);
|
|
282
|
+
sd += getSquaredDistance(start, end);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (highWholeIndex < highIndex) {
|
|
286
|
+
const start = getCoordinate(coordinates, highWholeIndex);
|
|
287
|
+
const end = interpolateCoordinate(coordinates, highIndex);
|
|
288
|
+
sd += getSquaredDistance(start, end);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
for (let i = lowWholeIndex; i < highWholeIndex - 1; ++i) {
|
|
292
|
+
const start = getCoordinate(coordinates, i);
|
|
293
|
+
const end = getCoordinate(coordinates, i + 1);
|
|
294
|
+
sd += getSquaredDistance(start, end);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return sd;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* @param {import("../coordinate.js").Coordinate} coordinate The coordinate.
|
|
302
|
+
* @param {import("../geom/Geometry.js").default} geometry The candidate geometry.
|
|
303
|
+
* @param {Array<TraceTarget>} targets The trace targets.
|
|
304
|
+
*/
|
|
305
|
+
function appendGeometryTraceTargets(coordinate, geometry, targets) {
|
|
306
|
+
if (geometry instanceof LineString) {
|
|
307
|
+
appendTraceTarget(coordinate, geometry.getCoordinates(), false, targets);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (geometry instanceof MultiLineString) {
|
|
311
|
+
const coordinates = geometry.getCoordinates();
|
|
312
|
+
for (let i = 0, ii = coordinates.length; i < ii; ++i) {
|
|
313
|
+
appendTraceTarget(coordinate, coordinates[i], false, targets);
|
|
314
|
+
}
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
if (geometry instanceof Polygon) {
|
|
318
|
+
const coordinates = geometry.getCoordinates();
|
|
319
|
+
for (let i = 0, ii = coordinates.length; i < ii; ++i) {
|
|
320
|
+
appendTraceTarget(coordinate, coordinates[i], true, targets);
|
|
321
|
+
}
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (geometry instanceof MultiPolygon) {
|
|
325
|
+
const polys = geometry.getCoordinates();
|
|
326
|
+
for (let i = 0, ii = polys.length; i < ii; ++i) {
|
|
327
|
+
const coordinates = polys[i];
|
|
328
|
+
for (let j = 0, jj = coordinates.length; j < jj; ++j) {
|
|
329
|
+
appendTraceTarget(coordinate, coordinates[j], true, targets);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
if (geometry instanceof GeometryCollection) {
|
|
335
|
+
const geometries = geometry.getGeometries();
|
|
336
|
+
for (let i = 0; i < geometries.length; ++i) {
|
|
337
|
+
appendGeometryTraceTargets(coordinate, geometries[i], targets);
|
|
338
|
+
}
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
// other types cannot be traced
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* @typedef {Object} TraceTargetUpdateInfo
|
|
346
|
+
* @property {number} index The new target index.
|
|
347
|
+
* @property {number} endIndex The new segment end index.
|
|
348
|
+
*/
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* @type {TraceTargetUpdateInfo}
|
|
352
|
+
*/
|
|
353
|
+
const sharedUpdateInfo = {index: -1, endIndex: NaN};
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @param {import("../coordinate.js").Coordinate} coordinate The coordinate.
|
|
357
|
+
* @param {TraceState} traceState The trace state.
|
|
358
|
+
* @return {TraceTargetUpdateInfo} Information about the new trace target. The returned
|
|
359
|
+
* object is reused between calls and must not be modified by the caller.
|
|
360
|
+
*/
|
|
361
|
+
function getTraceTargetUpdate(coordinate, traceState) {
|
|
362
|
+
const x = coordinate[0];
|
|
363
|
+
const y = coordinate[1];
|
|
364
|
+
|
|
365
|
+
let closestTargetDistance = Infinity;
|
|
366
|
+
|
|
367
|
+
let newTargetIndex = -1;
|
|
368
|
+
let newEndIndex = NaN;
|
|
369
|
+
|
|
370
|
+
for (
|
|
371
|
+
let targetIndex = 0;
|
|
372
|
+
targetIndex < traceState.targets.length;
|
|
373
|
+
++targetIndex
|
|
374
|
+
) {
|
|
375
|
+
const target = traceState.targets[targetIndex];
|
|
376
|
+
const coordinates = target.coordinates;
|
|
377
|
+
|
|
378
|
+
let minSegmentDistance = Infinity;
|
|
379
|
+
let endIndex;
|
|
380
|
+
for (
|
|
381
|
+
let coordinateIndex = 0;
|
|
382
|
+
coordinateIndex < coordinates.length - 1;
|
|
383
|
+
++coordinateIndex
|
|
384
|
+
) {
|
|
385
|
+
const start = coordinates[coordinateIndex];
|
|
386
|
+
const end = coordinates[coordinateIndex + 1];
|
|
387
|
+
const rel = getPointSegmentRelationship(x, y, start, end);
|
|
388
|
+
if (rel.squaredDistance < minSegmentDistance) {
|
|
389
|
+
minSegmentDistance = rel.squaredDistance;
|
|
390
|
+
endIndex = coordinateIndex + rel.along;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (minSegmentDistance < closestTargetDistance) {
|
|
395
|
+
closestTargetDistance = minSegmentDistance;
|
|
396
|
+
if (target.ring && traceState.targetIndex === targetIndex) {
|
|
397
|
+
// same target, maintain the same trace direction
|
|
398
|
+
if (target.endIndex > target.startIndex) {
|
|
399
|
+
// forward trace
|
|
400
|
+
if (endIndex < target.startIndex) {
|
|
401
|
+
endIndex += coordinates.length;
|
|
402
|
+
}
|
|
403
|
+
} else if (target.endIndex < target.startIndex) {
|
|
404
|
+
// reverse trace
|
|
405
|
+
if (endIndex > target.startIndex) {
|
|
406
|
+
endIndex -= coordinates.length;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
newEndIndex = endIndex;
|
|
411
|
+
newTargetIndex = targetIndex;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (
|
|
416
|
+
traceState.targetIndex !== newTargetIndex &&
|
|
417
|
+
traceState.targets[newTargetIndex].ring
|
|
418
|
+
) {
|
|
419
|
+
const target = traceState.targets[newTargetIndex];
|
|
420
|
+
const coordinates = target.coordinates;
|
|
421
|
+
const count = coordinates.length;
|
|
422
|
+
const startIndex = target.startIndex;
|
|
423
|
+
const endIndex = newEndIndex;
|
|
424
|
+
if (startIndex < endIndex) {
|
|
425
|
+
const forwardDistance = getCumulativeSquaredDistance(
|
|
426
|
+
coordinates,
|
|
427
|
+
startIndex,
|
|
428
|
+
endIndex
|
|
429
|
+
);
|
|
430
|
+
const reverseDistance = getCumulativeSquaredDistance(
|
|
431
|
+
coordinates,
|
|
432
|
+
startIndex,
|
|
433
|
+
endIndex - count
|
|
434
|
+
);
|
|
435
|
+
if (reverseDistance < forwardDistance) {
|
|
436
|
+
newEndIndex -= count;
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
const reverseDistance = getCumulativeSquaredDistance(
|
|
440
|
+
coordinates,
|
|
441
|
+
startIndex,
|
|
442
|
+
endIndex
|
|
443
|
+
);
|
|
444
|
+
const forwardDistance = getCumulativeSquaredDistance(
|
|
445
|
+
coordinates,
|
|
446
|
+
startIndex,
|
|
447
|
+
endIndex + count
|
|
448
|
+
);
|
|
449
|
+
if (forwardDistance < reverseDistance) {
|
|
450
|
+
newEndIndex += count;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
sharedUpdateInfo.index = newTargetIndex;
|
|
456
|
+
sharedUpdateInfo.endIndex = newEndIndex;
|
|
457
|
+
return sharedUpdateInfo;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* @param {import("../coordinate.js").Coordinate} coordinate The clicked coordinate.
|
|
462
|
+
* @param {Array<import("../coordinate.js").Coordinate>} coordinates The geometry component coordinates.
|
|
463
|
+
* @param {boolean} ring The coordinates represent a linear ring.
|
|
464
|
+
* @param {Array<TraceTarget>} targets The trace targets.
|
|
465
|
+
*/
|
|
466
|
+
function appendTraceTarget(coordinate, coordinates, ring, targets) {
|
|
467
|
+
const x = coordinate[0];
|
|
468
|
+
const y = coordinate[1];
|
|
469
|
+
for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {
|
|
470
|
+
const start = coordinates[i];
|
|
471
|
+
const end = coordinates[i + 1];
|
|
472
|
+
const rel = getPointSegmentRelationship(x, y, start, end);
|
|
473
|
+
if (rel.squaredDistance === 0) {
|
|
474
|
+
const index = i + rel.along;
|
|
475
|
+
targets.push({
|
|
476
|
+
coordinates: coordinates,
|
|
477
|
+
ring: ring,
|
|
478
|
+
startIndex: index,
|
|
479
|
+
endIndex: index,
|
|
480
|
+
});
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* @typedef {Object} PointSegmentRelationship
|
|
488
|
+
* @property {number} along The closest point expressed as a fraction along the segment length.
|
|
489
|
+
* @property {number} squaredDistance The squared distance of the point to the segment.
|
|
490
|
+
*/
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* @type {PointSegmentRelationship}
|
|
494
|
+
*/
|
|
495
|
+
const sharedRel = {along: 0, squaredDistance: 0};
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* @param {number} x The point x.
|
|
499
|
+
* @param {number} y The point y.
|
|
500
|
+
* @param {import("../coordinate.js").Coordinate} start The segment start.
|
|
501
|
+
* @param {import("../coordinate.js").Coordinate} end The segment end.
|
|
502
|
+
* @return {PointSegmentRelationship} The point segment relationship. The returned object is
|
|
503
|
+
* shared between calls and must not be modified by the caller.
|
|
504
|
+
*/
|
|
505
|
+
function getPointSegmentRelationship(x, y, start, end) {
|
|
506
|
+
const x1 = start[0];
|
|
507
|
+
const y1 = start[1];
|
|
508
|
+
const x2 = end[0];
|
|
509
|
+
const y2 = end[1];
|
|
510
|
+
const dx = x2 - x1;
|
|
511
|
+
const dy = y2 - y1;
|
|
512
|
+
let along = 0;
|
|
513
|
+
let px = x1;
|
|
514
|
+
let py = y1;
|
|
515
|
+
if (dx !== 0 || dy !== 0) {
|
|
516
|
+
along = clamp(((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy), 0, 1);
|
|
517
|
+
px += dx * along;
|
|
518
|
+
py += dy * along;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
sharedRel.along = along;
|
|
522
|
+
sharedRel.squaredDistance = toFixed(squaredDistance(x, y, px, py), 10);
|
|
523
|
+
return sharedRel;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* @param {LineCoordType} coordinates The coordinates.
|
|
528
|
+
* @param {number} index The index. May be fractional and may wrap.
|
|
529
|
+
* @return {import("../coordinate.js").Coordinate} The interpolated coordinate.
|
|
530
|
+
*/
|
|
531
|
+
function interpolateCoordinate(coordinates, index) {
|
|
532
|
+
const count = coordinates.length;
|
|
533
|
+
|
|
534
|
+
let startIndex = Math.floor(index);
|
|
535
|
+
const along = index - startIndex;
|
|
536
|
+
if (startIndex >= count) {
|
|
537
|
+
startIndex -= count;
|
|
538
|
+
} else if (startIndex < 0) {
|
|
539
|
+
startIndex += count;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
let endIndex = startIndex + 1;
|
|
543
|
+
if (endIndex >= count) {
|
|
544
|
+
endIndex -= count;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const start = coordinates[startIndex];
|
|
548
|
+
const x0 = start[0];
|
|
549
|
+
const y0 = start[1];
|
|
550
|
+
const end = coordinates[endIndex];
|
|
551
|
+
const dx = end[0] - x0;
|
|
552
|
+
const dy = end[1] - y0;
|
|
553
|
+
|
|
554
|
+
return [x0 + dx * along, y0 + dy * along];
|
|
555
|
+
}
|
|
556
|
+
|
|
171
557
|
/***
|
|
172
558
|
* @template Return
|
|
173
559
|
* @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
|
|
@@ -514,9 +900,46 @@ class Draw extends PointerInteraction {
|
|
|
514
900
|
: shiftKeyOnly;
|
|
515
901
|
}
|
|
516
902
|
|
|
903
|
+
/**
|
|
904
|
+
* @type {import("../events/condition.js").Condition}
|
|
905
|
+
* @private
|
|
906
|
+
*/
|
|
907
|
+
this.traceCondition_;
|
|
908
|
+
this.setTrace(options.trace || false);
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* @type {TraceState}
|
|
912
|
+
* @private
|
|
913
|
+
*/
|
|
914
|
+
this.traceState_ = {active: false};
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* @type {VectorSource|null}
|
|
918
|
+
* @private
|
|
919
|
+
*/
|
|
920
|
+
this.traceSource_ = options.traceSource || options.source || null;
|
|
921
|
+
|
|
517
922
|
this.addChangeListener(InteractionProperty.ACTIVE, this.updateState_);
|
|
518
923
|
}
|
|
519
924
|
|
|
925
|
+
/**
|
|
926
|
+
* Toggle tracing mode or set a tracing condition.
|
|
927
|
+
*
|
|
928
|
+
* @param {boolean|import("../events/condition.js").Condition} trace A boolean to toggle tracing mode or an event
|
|
929
|
+
* condition that will be checked when a feature is clicked to determine if tracing should be active.
|
|
930
|
+
*/
|
|
931
|
+
setTrace(trace) {
|
|
932
|
+
let condition;
|
|
933
|
+
if (!trace) {
|
|
934
|
+
condition = never;
|
|
935
|
+
} else if (trace === true) {
|
|
936
|
+
condition = always;
|
|
937
|
+
} else {
|
|
938
|
+
condition = trace;
|
|
939
|
+
}
|
|
940
|
+
this.traceCondition_ = condition;
|
|
941
|
+
}
|
|
942
|
+
|
|
520
943
|
/**
|
|
521
944
|
* Remove the interaction from its current map and attach it to the new map.
|
|
522
945
|
* Subclasses may set up event handlers to get notified about changes to
|
|
@@ -617,28 +1040,241 @@ class Draw extends PointerInteraction {
|
|
|
617
1040
|
this.startDrawing_(event.coordinate);
|
|
618
1041
|
}
|
|
619
1042
|
return true;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
function () {
|
|
624
|
-
this.handlePointerMove_(
|
|
625
|
-
new MapBrowserEvent(
|
|
626
|
-
MapBrowserEventType.POINTERMOVE,
|
|
627
|
-
event.map,
|
|
628
|
-
event.originalEvent,
|
|
629
|
-
false,
|
|
630
|
-
event.frameState
|
|
631
|
-
)
|
|
632
|
-
);
|
|
633
|
-
}.bind(this),
|
|
634
|
-
this.dragVertexDelay_
|
|
635
|
-
);
|
|
636
|
-
this.downPx_ = event.pixel;
|
|
637
|
-
return true;
|
|
638
|
-
} else {
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
if (!this.condition_(event)) {
|
|
639
1046
|
this.lastDragTime_ = undefined;
|
|
640
1047
|
return false;
|
|
641
1048
|
}
|
|
1049
|
+
|
|
1050
|
+
this.lastDragTime_ = Date.now();
|
|
1051
|
+
this.downTimeout_ = setTimeout(
|
|
1052
|
+
function () {
|
|
1053
|
+
this.handlePointerMove_(
|
|
1054
|
+
new MapBrowserEvent(
|
|
1055
|
+
MapBrowserEventType.POINTERMOVE,
|
|
1056
|
+
event.map,
|
|
1057
|
+
event.originalEvent,
|
|
1058
|
+
false,
|
|
1059
|
+
event.frameState
|
|
1060
|
+
)
|
|
1061
|
+
);
|
|
1062
|
+
}.bind(this),
|
|
1063
|
+
this.dragVertexDelay_
|
|
1064
|
+
);
|
|
1065
|
+
this.downPx_ = event.pixel;
|
|
1066
|
+
return true;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* @private
|
|
1071
|
+
*/
|
|
1072
|
+
deactivateTrace_() {
|
|
1073
|
+
this.traceState_ = {active: false};
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* Activate or deactivate trace state based on a browser event.
|
|
1078
|
+
* @param {import("../MapBrowserEvent.js").default} event Event.
|
|
1079
|
+
* @private
|
|
1080
|
+
*/
|
|
1081
|
+
toggleTraceState_(event) {
|
|
1082
|
+
if (!this.traceSource_ || !this.traceCondition_(event)) {
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
if (this.traceState_.active) {
|
|
1087
|
+
this.deactivateTrace_();
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
const map = this.getMap();
|
|
1092
|
+
const lowerLeft = map.getCoordinateFromPixel([
|
|
1093
|
+
event.pixel[0] - this.snapTolerance_,
|
|
1094
|
+
event.pixel[1] + this.snapTolerance_,
|
|
1095
|
+
]);
|
|
1096
|
+
const upperRight = map.getCoordinateFromPixel([
|
|
1097
|
+
event.pixel[0] + this.snapTolerance_,
|
|
1098
|
+
event.pixel[1] - this.snapTolerance_,
|
|
1099
|
+
]);
|
|
1100
|
+
const extent = boundingExtent([lowerLeft, upperRight]);
|
|
1101
|
+
const features = this.traceSource_.getFeaturesInExtent(extent);
|
|
1102
|
+
if (features.length === 0) {
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
const targets = getTraceTargets(event.coordinate, features);
|
|
1107
|
+
if (targets.length) {
|
|
1108
|
+
this.traceState_ = {
|
|
1109
|
+
active: true,
|
|
1110
|
+
startPx: event.pixel.slice(),
|
|
1111
|
+
targets: targets,
|
|
1112
|
+
targetIndex: -1,
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
/**
|
|
1118
|
+
* @param {TraceTarget} target The trace target.
|
|
1119
|
+
* @param {number} endIndex The new end index of the trace.
|
|
1120
|
+
* @private
|
|
1121
|
+
*/
|
|
1122
|
+
addOrRemoveTracedCoordinates_(target, endIndex) {
|
|
1123
|
+
// three cases to handle:
|
|
1124
|
+
// 1. traced in the same direction and points need adding
|
|
1125
|
+
// 2. traced in the same direction and points need removing
|
|
1126
|
+
// 3. traced in a new direction
|
|
1127
|
+
const previouslyForward = target.startIndex <= target.endIndex;
|
|
1128
|
+
const currentlyForward = target.startIndex <= endIndex;
|
|
1129
|
+
if (previouslyForward === currentlyForward) {
|
|
1130
|
+
// same direction
|
|
1131
|
+
if (
|
|
1132
|
+
(previouslyForward && endIndex > target.endIndex) ||
|
|
1133
|
+
(!previouslyForward && endIndex < target.endIndex)
|
|
1134
|
+
) {
|
|
1135
|
+
// case 1 - add new points
|
|
1136
|
+
this.addTracedCoordinates_(target, target.endIndex, endIndex);
|
|
1137
|
+
} else if (
|
|
1138
|
+
(previouslyForward && endIndex < target.endIndex) ||
|
|
1139
|
+
(!previouslyForward && endIndex > target.endIndex)
|
|
1140
|
+
) {
|
|
1141
|
+
// case 2 - remove old points
|
|
1142
|
+
this.removeTracedCoordinates_(endIndex, target.endIndex);
|
|
1143
|
+
}
|
|
1144
|
+
} else {
|
|
1145
|
+
// case 3 - remove old points, add new points
|
|
1146
|
+
this.removeTracedCoordinates_(target.startIndex, target.endIndex);
|
|
1147
|
+
this.addTracedCoordinates_(target, target.startIndex, endIndex);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* @param {number} fromIndex The start index.
|
|
1153
|
+
* @param {number} toIndex The end index.
|
|
1154
|
+
* @private
|
|
1155
|
+
*/
|
|
1156
|
+
removeTracedCoordinates_(fromIndex, toIndex) {
|
|
1157
|
+
if (fromIndex === toIndex) {
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
let remove = 0;
|
|
1162
|
+
if (fromIndex < toIndex) {
|
|
1163
|
+
const start = Math.ceil(fromIndex);
|
|
1164
|
+
let end = Math.floor(toIndex);
|
|
1165
|
+
if (end === toIndex) {
|
|
1166
|
+
end -= 1;
|
|
1167
|
+
}
|
|
1168
|
+
remove = end - start + 1;
|
|
1169
|
+
} else {
|
|
1170
|
+
const start = Math.floor(fromIndex);
|
|
1171
|
+
let end = Math.ceil(toIndex);
|
|
1172
|
+
if (end === toIndex) {
|
|
1173
|
+
end += 1;
|
|
1174
|
+
}
|
|
1175
|
+
remove = start - end + 1;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
if (remove > 0) {
|
|
1179
|
+
this.removeLastPoints_(remove);
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/**
|
|
1184
|
+
* @param {TraceTarget} target The trace target.
|
|
1185
|
+
* @param {number} fromIndex The start index.
|
|
1186
|
+
* @param {number} toIndex The end index.
|
|
1187
|
+
* @private
|
|
1188
|
+
*/
|
|
1189
|
+
addTracedCoordinates_(target, fromIndex, toIndex) {
|
|
1190
|
+
if (fromIndex === toIndex) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
const coordinates = [];
|
|
1195
|
+
if (fromIndex < toIndex) {
|
|
1196
|
+
// forward trace
|
|
1197
|
+
const start = Math.ceil(fromIndex);
|
|
1198
|
+
let end = Math.floor(toIndex);
|
|
1199
|
+
if (end === toIndex) {
|
|
1200
|
+
// if end is snapped to a vertex, it will be added later
|
|
1201
|
+
end -= 1;
|
|
1202
|
+
}
|
|
1203
|
+
for (let i = start; i <= end; ++i) {
|
|
1204
|
+
coordinates.push(getCoordinate(target.coordinates, i));
|
|
1205
|
+
}
|
|
1206
|
+
} else {
|
|
1207
|
+
// reverse trace
|
|
1208
|
+
const start = Math.floor(fromIndex);
|
|
1209
|
+
let end = Math.ceil(toIndex);
|
|
1210
|
+
if (end === toIndex) {
|
|
1211
|
+
end += 1;
|
|
1212
|
+
}
|
|
1213
|
+
for (let i = start; i >= end; --i) {
|
|
1214
|
+
coordinates.push(getCoordinate(target.coordinates, i));
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
if (coordinates.length) {
|
|
1218
|
+
this.appendCoordinates(coordinates);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
/**
|
|
1223
|
+
* Update the trace.
|
|
1224
|
+
* @param {import("../MapBrowserEvent.js").default} event Event.
|
|
1225
|
+
* @private
|
|
1226
|
+
*/
|
|
1227
|
+
updateTrace_(event) {
|
|
1228
|
+
const traceState = this.traceState_;
|
|
1229
|
+
if (!traceState.active) {
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
if (traceState.targetIndex === -1) {
|
|
1234
|
+
// check if we are ready to pick a target
|
|
1235
|
+
if (distance(traceState.startPx, event.pixel) < this.snapTolerance_) {
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
const updatedTraceTarget = getTraceTargetUpdate(
|
|
1241
|
+
event.coordinate,
|
|
1242
|
+
traceState
|
|
1243
|
+
);
|
|
1244
|
+
|
|
1245
|
+
if (traceState.targetIndex !== updatedTraceTarget.index) {
|
|
1246
|
+
// target changed
|
|
1247
|
+
if (traceState.targetIndex !== -1) {
|
|
1248
|
+
// remove points added during previous trace
|
|
1249
|
+
const oldTarget = traceState.targets[traceState.targetIndex];
|
|
1250
|
+
this.removeTracedCoordinates_(oldTarget.startIndex, oldTarget.endIndex);
|
|
1251
|
+
}
|
|
1252
|
+
// add points for the new target
|
|
1253
|
+
const newTarget = traceState.targets[updatedTraceTarget.index];
|
|
1254
|
+
this.addTracedCoordinates_(
|
|
1255
|
+
newTarget,
|
|
1256
|
+
newTarget.startIndex,
|
|
1257
|
+
updatedTraceTarget.endIndex
|
|
1258
|
+
);
|
|
1259
|
+
} else {
|
|
1260
|
+
// target stayed the same
|
|
1261
|
+
const target = traceState.targets[traceState.targetIndex];
|
|
1262
|
+
this.addOrRemoveTracedCoordinates_(target, updatedTraceTarget.endIndex);
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// modify the state with updated info
|
|
1266
|
+
traceState.targetIndex = updatedTraceTarget.index;
|
|
1267
|
+
const target = traceState.targets[traceState.targetIndex];
|
|
1268
|
+
target.endIndex = updatedTraceTarget.endIndex;
|
|
1269
|
+
|
|
1270
|
+
// update event coordinate and pixel to match end point of final segment
|
|
1271
|
+
const coordinate = interpolateCoordinate(
|
|
1272
|
+
target.coordinates,
|
|
1273
|
+
target.endIndex
|
|
1274
|
+
);
|
|
1275
|
+
const pixel = this.getMap().getPixelFromCoordinate(coordinate);
|
|
1276
|
+
event.coordinate = coordinate;
|
|
1277
|
+
event.pixel = [Math.round(pixel[0]), Math.round(pixel[1])];
|
|
642
1278
|
}
|
|
643
1279
|
|
|
644
1280
|
/**
|
|
@@ -656,6 +1292,8 @@ class Draw extends PointerInteraction {
|
|
|
656
1292
|
}
|
|
657
1293
|
|
|
658
1294
|
this.handlePointerMove_(event);
|
|
1295
|
+
const tracing = this.traceState_.active;
|
|
1296
|
+
this.toggleTraceState_(event);
|
|
659
1297
|
|
|
660
1298
|
if (this.shouldHandle_) {
|
|
661
1299
|
const startingToDraw = !this.finishCoordinate_;
|
|
@@ -668,7 +1306,7 @@ class Draw extends PointerInteraction {
|
|
|
668
1306
|
!this.freehand_ &&
|
|
669
1307
|
(!startingToDraw || this.mode_ === 'Point')
|
|
670
1308
|
) {
|
|
671
|
-
if (this.atFinish_(event.pixel)) {
|
|
1309
|
+
if (this.atFinish_(event.pixel, tracing)) {
|
|
672
1310
|
if (this.finishCondition_(event)) {
|
|
673
1311
|
this.finishDrawing();
|
|
674
1312
|
}
|
|
@@ -713,20 +1351,23 @@ class Draw extends PointerInteraction {
|
|
|
713
1351
|
}
|
|
714
1352
|
}
|
|
715
1353
|
|
|
716
|
-
if (this.finishCoordinate_) {
|
|
717
|
-
this.modifyDrawing_(event.coordinate);
|
|
718
|
-
} else {
|
|
1354
|
+
if (!this.finishCoordinate_) {
|
|
719
1355
|
this.createOrUpdateSketchPoint_(event.coordinate.slice());
|
|
1356
|
+
return;
|
|
720
1357
|
}
|
|
1358
|
+
|
|
1359
|
+
this.updateTrace_(event);
|
|
1360
|
+
this.modifyDrawing_(event.coordinate);
|
|
721
1361
|
}
|
|
722
1362
|
|
|
723
1363
|
/**
|
|
724
1364
|
* Determine if an event is within the snapping tolerance of the start coord.
|
|
725
1365
|
* @param {import("../pixel.js").Pixel} pixel Pixel.
|
|
1366
|
+
* @param {boolean} [tracing] Drawing in trace mode (only stop if at the starting point).
|
|
726
1367
|
* @return {boolean} The event is within the snapping tolerance of the start.
|
|
727
1368
|
* @private
|
|
728
1369
|
*/
|
|
729
|
-
atFinish_(pixel) {
|
|
1370
|
+
atFinish_(pixel, tracing) {
|
|
730
1371
|
let at = false;
|
|
731
1372
|
if (this.sketchFeature_) {
|
|
732
1373
|
let potentiallyDone = false;
|
|
@@ -737,7 +1378,8 @@ class Draw extends PointerInteraction {
|
|
|
737
1378
|
} else if (mode === 'Circle') {
|
|
738
1379
|
at = this.sketchCoords_.length === 2;
|
|
739
1380
|
} else if (mode === 'LineString') {
|
|
740
|
-
potentiallyDone =
|
|
1381
|
+
potentiallyDone =
|
|
1382
|
+
!tracing && this.sketchCoords_.length > this.minPoints_;
|
|
741
1383
|
} else if (mode === 'Polygon') {
|
|
742
1384
|
const sketchCoords = /** @type {PolyCoordType} */ (this.sketchCoords_);
|
|
743
1385
|
potentiallyDone = sketchCoords[0].length > this.minPoints_;
|
|
@@ -745,6 +1387,14 @@ class Draw extends PointerInteraction {
|
|
|
745
1387
|
sketchCoords[0][0],
|
|
746
1388
|
sketchCoords[0][sketchCoords[0].length - 2],
|
|
747
1389
|
];
|
|
1390
|
+
if (tracing) {
|
|
1391
|
+
potentiallyFinishCoordinates = [sketchCoords[0][0]];
|
|
1392
|
+
} else {
|
|
1393
|
+
potentiallyFinishCoordinates = [
|
|
1394
|
+
sketchCoords[0][0],
|
|
1395
|
+
sketchCoords[0][sketchCoords[0].length - 2],
|
|
1396
|
+
];
|
|
1397
|
+
}
|
|
748
1398
|
}
|
|
749
1399
|
if (potentiallyDone) {
|
|
750
1400
|
const map = this.getMap();
|
|
@@ -936,51 +1586,63 @@ class Draw extends PointerInteraction {
|
|
|
936
1586
|
}
|
|
937
1587
|
|
|
938
1588
|
/**
|
|
939
|
-
*
|
|
940
|
-
* drawing POINT or MULTI_POINT geometries.
|
|
941
|
-
* @api
|
|
1589
|
+
* @param {number} n The number of points to remove.
|
|
942
1590
|
*/
|
|
943
|
-
|
|
1591
|
+
removeLastPoints_(n) {
|
|
944
1592
|
if (!this.sketchFeature_) {
|
|
945
1593
|
return;
|
|
946
1594
|
}
|
|
947
1595
|
const geometry = this.sketchFeature_.getGeometry();
|
|
948
1596
|
const projection = this.getMap().getView().getProjection();
|
|
949
|
-
let coordinates;
|
|
950
1597
|
const mode = this.mode_;
|
|
951
|
-
|
|
952
|
-
coordinates
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
this.
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
if (
|
|
969
|
-
|
|
970
|
-
coordinates
|
|
971
|
-
this.
|
|
1598
|
+
for (let i = 0; i < n; ++i) {
|
|
1599
|
+
let coordinates;
|
|
1600
|
+
if (mode === 'LineString' || mode === 'Circle') {
|
|
1601
|
+
coordinates = /** @type {LineCoordType} */ (this.sketchCoords_);
|
|
1602
|
+
coordinates.splice(-2, 1);
|
|
1603
|
+
if (coordinates.length >= 2) {
|
|
1604
|
+
this.finishCoordinate_ = coordinates[coordinates.length - 2].slice();
|
|
1605
|
+
const finishCoordinate = this.finishCoordinate_.slice();
|
|
1606
|
+
coordinates[coordinates.length - 1] = finishCoordinate;
|
|
1607
|
+
this.createOrUpdateSketchPoint_(finishCoordinate);
|
|
1608
|
+
}
|
|
1609
|
+
this.geometryFunction_(coordinates, geometry, projection);
|
|
1610
|
+
if (geometry.getType() === 'Polygon' && this.sketchLine_) {
|
|
1611
|
+
this.createOrUpdateCustomSketchLine_(
|
|
1612
|
+
/** @type {Polygon} */ (geometry)
|
|
1613
|
+
);
|
|
1614
|
+
}
|
|
1615
|
+
} else if (mode === 'Polygon') {
|
|
1616
|
+
coordinates = /** @type {PolyCoordType} */ (this.sketchCoords_)[0];
|
|
1617
|
+
coordinates.splice(-2, 1);
|
|
1618
|
+
const sketchLineGeom = this.sketchLine_.getGeometry();
|
|
1619
|
+
if (coordinates.length >= 2) {
|
|
1620
|
+
const finishCoordinate = coordinates[coordinates.length - 2].slice();
|
|
1621
|
+
coordinates[coordinates.length - 1] = finishCoordinate;
|
|
1622
|
+
this.createOrUpdateSketchPoint_(finishCoordinate);
|
|
1623
|
+
}
|
|
1624
|
+
sketchLineGeom.setCoordinates(coordinates);
|
|
1625
|
+
this.geometryFunction_(this.sketchCoords_, geometry, projection);
|
|
972
1626
|
}
|
|
973
|
-
sketchLineGeom.setCoordinates(coordinates);
|
|
974
|
-
this.geometryFunction_(this.sketchCoords_, geometry, projection);
|
|
975
|
-
}
|
|
976
1627
|
|
|
977
|
-
|
|
978
|
-
|
|
1628
|
+
if (coordinates.length === 1) {
|
|
1629
|
+
this.abortDrawing();
|
|
1630
|
+
break;
|
|
1631
|
+
}
|
|
979
1632
|
}
|
|
980
1633
|
|
|
981
1634
|
this.updateSketchFeatures_();
|
|
982
1635
|
}
|
|
983
1636
|
|
|
1637
|
+
/**
|
|
1638
|
+
* Remove last point of the feature currently being drawn. Does not do anything when
|
|
1639
|
+
* drawing POINT or MULTI_POINT geometries.
|
|
1640
|
+
* @api
|
|
1641
|
+
*/
|
|
1642
|
+
removeLastPoint() {
|
|
1643
|
+
this.removeLastPoints_(1);
|
|
1644
|
+
}
|
|
1645
|
+
|
|
984
1646
|
/**
|
|
985
1647
|
* Stop drawing and add the sketch feature to the target layer.
|
|
986
1648
|
* The {@link module:ol/interaction/Draw~DrawEventType.DRAWEND} event is
|
|
@@ -1045,6 +1707,7 @@ class Draw extends PointerInteraction {
|
|
|
1045
1707
|
this.sketchPoint_ = null;
|
|
1046
1708
|
this.sketchLine_ = null;
|
|
1047
1709
|
this.overlay_.getSource().clear(true);
|
|
1710
|
+
this.deactivateTrace_();
|
|
1048
1711
|
return sketchFeature;
|
|
1049
1712
|
}
|
|
1050
1713
|
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TileLayer.d.ts","sourceRoot":"","sources":["TileLayer.js"],"names":[],"mappings":";AA8BA;;;;;;GAMG;AACH;IACE;;OAEG;IACH,uBAFW,SAAS,EA0DnB;IArDC;;;OAGG;IACH,eAFU,OAAO,CAEQ;IAEzB;;;OAGG;IACH,wBAA2B;IAE3B;;;OAGG;IACH,8BAFU,MAAM,CAEO;IAEvB;;;OAGG;IACH,8BAFU,OAAO,0BAA0B,EAAE,OAAO,CAEtB;IAE9B;;;OAGG;IACH,4BAFU,MAAM,CAEK;IAErB;;;OAGG;IACH,yBAFW,MAAM,OAAO,eAAe,EAAE,OAAO,CAAC,CAE1B;IAEvB;;;OAGG;IACH,kBAAsB;IAEtB;;;OAGG;IACH,qBAFU,OAAO,iBAAiB,EAAE,MAAM,CAEZ;IAE9B;;;OAGG;IACH,sBAA8C;IAGhD;;;;OAIG;IACH,+BAHW,OAAO,eAAe,EAAE,OAAO,GAC9B,OAAO,CAWlB;IAED;;;;;;OAMG;IACH,WANW,MAAM,KACN,MAAM,KACN,MAAM,cACN,OAAO,cAAc,EAAE,UAAU,GAC/B,OAAO,eAAe,EAAE,OAAO,CAkB3C;IAED;;;OAGG;IACH,eAHW,OAAO,gBAAgB,EAAE,KAAK,GAC7B,iBAAiB,
|
|
1
|
+
{"version":3,"file":"TileLayer.d.ts","sourceRoot":"","sources":["TileLayer.js"],"names":[],"mappings":";AA8BA;;;;;;GAMG;AACH;IACE;;OAEG;IACH,uBAFW,SAAS,EA0DnB;IArDC;;;OAGG;IACH,eAFU,OAAO,CAEQ;IAEzB;;;OAGG;IACH,wBAA2B;IAE3B;;;OAGG;IACH,8BAFU,MAAM,CAEO;IAEvB;;;OAGG;IACH,8BAFU,OAAO,0BAA0B,EAAE,OAAO,CAEtB;IAE9B;;;OAGG;IACH,4BAFU,MAAM,CAEK;IAErB;;;OAGG;IACH,yBAFW,MAAM,OAAO,eAAe,EAAE,OAAO,CAAC,CAE1B;IAEvB;;;OAGG;IACH,kBAAsB;IAEtB;;;OAGG;IACH,qBAFU,OAAO,iBAAiB,EAAE,MAAM,CAEZ;IAE9B;;;OAGG;IACH,sBAA8C;IAGhD;;;;OAIG;IACH,+BAHW,OAAO,eAAe,EAAE,OAAO,GAC9B,OAAO,CAWlB;IAED;;;;;;OAMG;IACH,WANW,MAAM,KACN,MAAM,KACN,MAAM,cACN,OAAO,cAAc,EAAE,UAAU,GAC/B,OAAO,eAAe,EAAE,OAAO,CAkB3C;IAED;;;OAGG;IACH,eAHW,OAAO,gBAAgB,EAAE,KAAK,GAC7B,iBAAiB,CA4E5B;IAoWD;;;;;;;;;OASG;IACH,oBATW,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,cAAc,EAAE,UAAU,KACjC,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,UACN,MAAM,cACN,OAAO,QAqCjB;IAED;;OAEG;IACH,YAFY,iBAAiB,CAK5B;IAED;;;;;OAKG;IACH,6BAJW,OAAO,oBAAoB,EAAE,OAAO,GACnC,iBAAiB,GAAC,gBAAgB,GAAC,gBAAgB,CAK9D;IAED;;;;OAIG;IACH,0CAJW,OAAO,cAAc,EAAE,UAAU,cACjC,OAAO,sBAAsB,EAAE,OAAO,QA0BhD;IAED;;;;;OAKG;IACH;YALmB,MAAM;gBAAU,MAAM,GAAE,OAAO;;mBACvC,OAAO,sBAAsB,EAAE,OAAO,QACtC,OAAO,eAAe,EAAE,OAAO,QAUzC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,wCAXW,OAAO,cAAc,EAAE,UAAU,cACjC,OAAO,sBAAsB,EAAE,OAAO,YACtC,OAAO,4BAA4B,EAAE,OAAO,cAC5C,MAAM,cACN,OAAO,0BAA0B,EAAE,OAAO,UAC1C,OAAO,iBAAiB,EAAE,MAAM,YAChC,MAAM,WACN,MAAM,yBACG,OAAO,eAAe,EAAE,OAAO,KAAE,IAAI,qBAmExD;CACF"}
|
|
@@ -181,7 +181,10 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|
|
181
181
|
pixelRatio,
|
|
182
182
|
projection
|
|
183
183
|
);
|
|
184
|
-
if (
|
|
184
|
+
if (
|
|
185
|
+
!(tile instanceof ImageTile || tile instanceof ReprojTile) ||
|
|
186
|
+
(tile instanceof ReprojTile && tile.getState() === TileState.EMPTY)
|
|
187
|
+
) {
|
|
185
188
|
return null;
|
|
186
189
|
}
|
|
187
190
|
|
|
@@ -158,10 +158,11 @@ declare class WebGLTileLayerRenderer extends WebGLLayerRenderer<import("../../la
|
|
|
158
158
|
* @param {import("../../extent.js").Extent} extent The extent to be rendered.
|
|
159
159
|
* @param {number} initialZ The zoom level.
|
|
160
160
|
* @param {Object<number, Array<TileTexture>>} tileTexturesByZ The zoom level.
|
|
161
|
+
* @param {number} preload Number of additional levels to load.
|
|
161
162
|
*/
|
|
162
163
|
enqueueTiles(frameState: import("../../Map.js").FrameState, extent: import("../../extent.js").Extent, initialZ: number, tileTexturesByZ: {
|
|
163
164
|
[x: number]: Array<TileTexture>;
|
|
164
|
-
}): void;
|
|
165
|
+
}, preload: number): void;
|
|
165
166
|
/**
|
|
166
167
|
* Render the layer.
|
|
167
168
|
* @param {import("../../Map.js").FrameState} frameState Frame state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TileLayer.d.ts","sourceRoot":"","sources":["TileLayer.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"TileLayer.d.ts","sourceRoot":"","sources":["TileLayer.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;kBAkIc,MAAM;;;;oBACN,MAAM;;;;;;;;;;;;;;;;;wBAQP,OAAO,0BAA0B,EAAE,OAAO;AAXvD;;;;;;;;GAQG;AAEH;;GAEG;AAEH;;;;;GAKG;AACH;IACE;;;OAGG;IACH,uBAHW,SAAS,WACT,OAAO,EAmGjB;IA5FC;;;OAGG;IACH,gBAFU,OAAO,CAEU;IAE3B;;;;OAIG;IACH,uBAAuC;IAEvC;;;OAGG;IACH,kBAA6B;IAE7B;;;OAGG;IACH,uBAA+C;IAE/C;;;OAGG;IACH,uBAA8C;IAE9C;;;OAGG;IACH,kBAAuB;IAEvB;;;OAGG;IACH,iBAAa;IAEb;;OAEG;IACH,sBAAyC;IAEzC;;OAEG;IACH,wBAA6C;IAE7C;;;;;;;;;;;;;;;;OAgBG;IACH,iBAAuE;IAKvE;;;OAGG;IACH,0BAAgD;IAEhD;;;OAGG;IACH,yBAAqD;IAErD;;;OAGG;IACH,oBAAuB;IAGzB;;OAEG;IACH,eAFW,OAAO,QAgBjB;IAWD;;;;OAIG;IACH,wBASC;IAoBD;;;;;;OAMG;IACH,yBANW,OAAO,cAAc,EAAE,UAAU,UACjC,OAAO,iBAAiB,EAAE,MAAM,YAChC,MAAM;YACC,MAAM,GAAE,MAAM,WAAW,CAAC;gBACjC,MAAM,QAwGhB;IAED;;;;OAIG;IACH,wBAHW,OAAO,cAAc,EAAE,UAAU,GAChC,WAAW,CAkStB;IAED;;;OAGG;IACH,eAHW,OAAO,gBAAgB,EAAE,KAAK,GAC7B,iBAAiB,GAAC,UAAU,GAAC,YAAY,GAAC,QAAQ,CAyF7D;IAED;;;;;;;;;;OAUG;IACH,sBA+BC;CA+BF"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @module ol/renderer/webgl/TileLayer
|
|
3
3
|
*/
|
|
4
4
|
import LRUCache from '../../structs/LRUCache.js';
|
|
5
|
+
import ReprojTile from '../../reproj/Tile.js';
|
|
5
6
|
import TileRange from '../../TileRange.js';
|
|
6
7
|
import TileState from '../../TileState.js';
|
|
7
8
|
import TileTexture from '../../webgl/TileTexture.js';
|
|
@@ -316,8 +317,9 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|
|
316
317
|
* @param {import("../../extent.js").Extent} extent The extent to be rendered.
|
|
317
318
|
* @param {number} initialZ The zoom level.
|
|
318
319
|
* @param {Object<number, Array<TileTexture>>} tileTexturesByZ The zoom level.
|
|
320
|
+
* @param {number} preload Number of additional levels to load.
|
|
319
321
|
*/
|
|
320
|
-
enqueueTiles(frameState, extent, initialZ, tileTexturesByZ) {
|
|
322
|
+
enqueueTiles(frameState, extent, initialZ, tileTexturesByZ, preload) {
|
|
321
323
|
const viewState = frameState.viewState;
|
|
322
324
|
const tileLayer = this.getLayer();
|
|
323
325
|
const tileSource = tileLayer.getRenderSource();
|
|
@@ -330,12 +332,23 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|
|
330
332
|
}
|
|
331
333
|
|
|
332
334
|
const wantedTiles = frameState.wantedTiles[tileSourceKey];
|
|
333
|
-
|
|
334
335
|
const tileTextureCache = this.tileTextureCache_;
|
|
336
|
+
|
|
337
|
+
const map = tileLayer.getMapInternal();
|
|
335
338
|
const minZ = Math.max(
|
|
336
|
-
initialZ -
|
|
339
|
+
initialZ - preload,
|
|
337
340
|
tileGrid.getMinZoom(),
|
|
338
|
-
|
|
341
|
+
tileGrid.getZForResolution(
|
|
342
|
+
Math.min(
|
|
343
|
+
tileLayer.getMaxResolution(),
|
|
344
|
+
map
|
|
345
|
+
? map
|
|
346
|
+
.getView()
|
|
347
|
+
.getResolutionForZoom(Math.max(tileLayer.getMinZoom(), 0))
|
|
348
|
+
: tileGrid.getResolution(0)
|
|
349
|
+
),
|
|
350
|
+
tileSource.zDirection
|
|
351
|
+
)
|
|
339
352
|
);
|
|
340
353
|
for (let z = initialZ; z >= minZ; --z) {
|
|
341
354
|
const tileRange = tileGrid.getTileRangeForExtentAndZ(
|
|
@@ -437,16 +450,34 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|
|
437
450
|
*/
|
|
438
451
|
const tileTexturesByZ = {};
|
|
439
452
|
|
|
453
|
+
const preload = tileLayer.getPreload();
|
|
440
454
|
if (frameState.nextExtent) {
|
|
441
455
|
const targetZ = tileGrid.getZForResolution(
|
|
442
456
|
viewState.nextResolution,
|
|
443
457
|
tileSource.zDirection
|
|
444
458
|
);
|
|
445
459
|
const nextExtent = getRenderExtent(frameState, frameState.nextExtent);
|
|
446
|
-
this.enqueueTiles(
|
|
460
|
+
this.enqueueTiles(
|
|
461
|
+
frameState,
|
|
462
|
+
nextExtent,
|
|
463
|
+
targetZ,
|
|
464
|
+
tileTexturesByZ,
|
|
465
|
+
preload
|
|
466
|
+
);
|
|
447
467
|
}
|
|
448
468
|
|
|
449
|
-
this.enqueueTiles(frameState, extent, z, tileTexturesByZ);
|
|
469
|
+
this.enqueueTiles(frameState, extent, z, tileTexturesByZ, 0);
|
|
470
|
+
if (preload > 0) {
|
|
471
|
+
setTimeout(() => {
|
|
472
|
+
this.enqueueTiles(
|
|
473
|
+
frameState,
|
|
474
|
+
extent,
|
|
475
|
+
z - 1,
|
|
476
|
+
tileTexturesByZ,
|
|
477
|
+
preload - 1
|
|
478
|
+
);
|
|
479
|
+
}, 0);
|
|
480
|
+
}
|
|
450
481
|
|
|
451
482
|
/**
|
|
452
483
|
* A lookup of alpha values for tiles at the target rendering resolution
|
|
@@ -465,6 +496,9 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|
|
465
496
|
for (let i = 0, ii = tileTextures.length; i < ii; ++i) {
|
|
466
497
|
const tileTexture = tileTextures[i];
|
|
467
498
|
const tile = tileTexture.tile;
|
|
499
|
+
if (tile instanceof ReprojTile && tile.getState() === TileState.EMPTY) {
|
|
500
|
+
continue;
|
|
501
|
+
}
|
|
468
502
|
const tileCoord = tile.tileCoord;
|
|
469
503
|
|
|
470
504
|
if (tileTexture.loaded) {
|
|
@@ -753,6 +787,10 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|
|
753
787
|
continue;
|
|
754
788
|
}
|
|
755
789
|
const tileTexture = tileTextureCache.get(cacheKey);
|
|
790
|
+
const tile = tileTexture.tile;
|
|
791
|
+
if (tile instanceof ReprojTile && tile.getState() === TileState.EMPTY) {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
756
794
|
if (!tileTexture.loaded) {
|
|
757
795
|
continue;
|
|
758
796
|
}
|
package/util.js
CHANGED