drone_view 3.0.18 → 3.0.20
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/.vscode/settings.json +3 -0
- package/dist/514.droneView.js +1 -1
- package/dist/800.droneView.js +1 -1
- package/dist/droneView.js +1 -1
- package/package.json +1 -1
- package/src/app.interface.ts +684 -0
- package/src/droneView.ts +1070 -0
- package/src/event.ts +359 -0
- package/src/layers/annotation.ts +175 -0
- package/src/layers/droneImages.ts +199 -0
- package/src/layers/editLine.ts +521 -0
- package/src/layers/editPoint.ts +345 -0
- package/src/layers/editPolygon.ts +511 -0
- package/src/layers/line.ts +210 -0
- package/src/layers/marker.ts +333 -0
- package/src/layers/marker3d.ts +326 -0
- package/src/layers/model.ts +253 -0
- package/src/layers/note.ts +333 -0
- package/src/layers/ortho.ts +76 -0
- package/src/layers/polygon.ts +218 -0
- package/src/measurement.ts +374 -0
- package/src/utility.ts +802 -0
@@ -0,0 +1,511 @@
|
|
1
|
+
import {
|
2
|
+
CallbackProperty,
|
3
|
+
Color,
|
4
|
+
Cartesian3,
|
5
|
+
CustomDataSource,
|
6
|
+
Entity,
|
7
|
+
Math as cMath,
|
8
|
+
HeadingPitchRange,
|
9
|
+
PolygonHierarchy,
|
10
|
+
PolylineDashMaterialProperty,
|
11
|
+
sampleTerrainMostDetailed,
|
12
|
+
ScreenSpaceEventHandler,
|
13
|
+
ScreenSpaceEventType,
|
14
|
+
HeightReference,
|
15
|
+
VerticalOrigin,
|
16
|
+
Cartographic,
|
17
|
+
} from "cesium";
|
18
|
+
|
19
|
+
import { Point, PolygonData, PolygonOptions } from "../app.interface";
|
20
|
+
|
21
|
+
import type CesiumView from "../droneView";
|
22
|
+
|
23
|
+
import {
|
24
|
+
cartesianArrayToPointArray,
|
25
|
+
cartesianToPoint,
|
26
|
+
getMidPoint,
|
27
|
+
pointArrayToCartesianArray,
|
28
|
+
screenToWorldPosition,
|
29
|
+
} from "../utility";
|
30
|
+
|
31
|
+
/**
|
32
|
+
* @param {CesiumView} mapObject - The viewer object
|
33
|
+
* @param {string} uniqueName - The unique name of the layer
|
34
|
+
* @param {PolygonData[]} data - The data to be used in the layer
|
35
|
+
* @param {PolygonOptions} options - The options for the layer)
|
36
|
+
*/
|
37
|
+
export default class EditPolygon {
|
38
|
+
editLayerId: string;
|
39
|
+
|
40
|
+
pointLayer: CustomDataSource;
|
41
|
+
|
42
|
+
lineLayer: CustomDataSource;
|
43
|
+
|
44
|
+
verticsPostions: any = [];
|
45
|
+
|
46
|
+
sideCenterPositions: Cartesian3[] = [];
|
47
|
+
|
48
|
+
verticesSelected: boolean[];
|
49
|
+
|
50
|
+
selectedIndex: number = -1;
|
51
|
+
|
52
|
+
selectedAnnotationID: string | number | null;
|
53
|
+
|
54
|
+
selectedPointID: string | number | null;
|
55
|
+
|
56
|
+
pointWasDragged: boolean;
|
57
|
+
|
58
|
+
mapWasMoved: boolean;
|
59
|
+
|
60
|
+
mouseOverEntity: any | null;
|
61
|
+
|
62
|
+
opacity: number = 0.0;
|
63
|
+
|
64
|
+
handler: ScreenSpaceEventHandler;
|
65
|
+
|
66
|
+
/**
|
67
|
+
* @param { CesiumView } mapObject map object
|
68
|
+
* @param { string }uniqueName string unique name for the layer
|
69
|
+
* @param { PolygonData } data
|
70
|
+
* @param { PolygonOptions } options
|
71
|
+
*/
|
72
|
+
constructor(
|
73
|
+
public mapObject: CesiumView,
|
74
|
+
public uniqueName: string,
|
75
|
+
public data: PolygonData,
|
76
|
+
public options: PolygonOptions
|
77
|
+
) {
|
78
|
+
this.editLayerId = `polygon-edit-layer-${this.uniqueName}`;
|
79
|
+
this.opacity = 0.0;
|
80
|
+
this.buildLayer();
|
81
|
+
this.add(this.data);
|
82
|
+
if (this.options.setBounds === undefined || this.options.setBounds) {
|
83
|
+
this.setBounds();
|
84
|
+
}
|
85
|
+
this.addListeners();
|
86
|
+
}
|
87
|
+
|
88
|
+
/** To initialize layer */
|
89
|
+
public buildLayer(): void {
|
90
|
+
if (
|
91
|
+
this.mapObject.viewer.dataSources.getByName(
|
92
|
+
"polygon-edit-Point-" + this.uniqueName
|
93
|
+
)
|
94
|
+
) {
|
95
|
+
this.mapObject.viewer.dataSources.remove(
|
96
|
+
this.mapObject.viewer.dataSources.getByName(
|
97
|
+
"polygon-edit-Point-" + this.uniqueName
|
98
|
+
)[0],
|
99
|
+
true
|
100
|
+
);
|
101
|
+
}
|
102
|
+
|
103
|
+
this.pointLayer = new CustomDataSource(
|
104
|
+
`polygon-edit-Point-${this.editLayerId}`
|
105
|
+
);
|
106
|
+
|
107
|
+
this.mapObject.viewer.dataSources.add(this.pointLayer);
|
108
|
+
|
109
|
+
if (
|
110
|
+
this.mapObject.viewer.dataSources.getByName(
|
111
|
+
"polygon-edit-Line-" + this.uniqueName
|
112
|
+
)
|
113
|
+
) {
|
114
|
+
this.mapObject.viewer.dataSources.remove(
|
115
|
+
this.mapObject.viewer.dataSources.getByName(
|
116
|
+
"polygon-edit-Line-" + this.uniqueName
|
117
|
+
)[0],
|
118
|
+
true
|
119
|
+
);
|
120
|
+
}
|
121
|
+
|
122
|
+
this.lineLayer = new CustomDataSource(
|
123
|
+
`polygon-edit-Line-${this.editLayerId}`
|
124
|
+
);
|
125
|
+
|
126
|
+
this.mapObject.viewer.dataSources.add(this.lineLayer);
|
127
|
+
}
|
128
|
+
|
129
|
+
/** To add layer on map */
|
130
|
+
public add(data: PolygonData) {
|
131
|
+
// const self = this;
|
132
|
+
// let positions = Cartesian3.fromDegreesArrayHeights(data.points.flat());
|
133
|
+
// if (positions[0] !== positions[positions.length - 1]) {
|
134
|
+
// positions = [...positions, positions[0]];
|
135
|
+
// }
|
136
|
+
|
137
|
+
// self.verticsPostions = positions;
|
138
|
+
// self.verticesSelected = new Array(positions.length).fill(false);
|
139
|
+
|
140
|
+
// const dynamicPositions: any = new CallbackProperty(
|
141
|
+
// () => new PolygonHierarchy(self.verticsPostions),
|
142
|
+
// false
|
143
|
+
// );
|
144
|
+
|
145
|
+
// this.updateVerticesPoints();
|
146
|
+
|
147
|
+
// const line = {
|
148
|
+
// polyline: {
|
149
|
+
// positions: new CallbackProperty(() => [...self.verticsPostions], false),
|
150
|
+
// width: 4,
|
151
|
+
// material: Color.fromCssColorString("#FF0000"),
|
152
|
+
// clampToGround: true,
|
153
|
+
// },
|
154
|
+
// };
|
155
|
+
|
156
|
+
// this.lineLayer.entities.add(line);
|
157
|
+
// }
|
158
|
+
|
159
|
+
// /**
|
160
|
+
// * Add data on map
|
161
|
+
// * @param { FreeformData } data
|
162
|
+
// */
|
163
|
+
// public addToMap(data: PolygonData) {
|
164
|
+
const self = this;
|
165
|
+
// let zOffset = 0;
|
166
|
+
|
167
|
+
// if (this.mapObject.layers.freeform) {
|
168
|
+
// zOffset = this.mapObject.layers.freeform.length;
|
169
|
+
// }
|
170
|
+
|
171
|
+
return new Promise<void>((resolve) => {
|
172
|
+
const cartesianPositions = pointArrayToCartesianArray(data.points);
|
173
|
+
const cartographicPositions =
|
174
|
+
this.mapObject.viewer.scene.globe.ellipsoid.cartesianArrayToCartographicArray(
|
175
|
+
cartesianPositions
|
176
|
+
);
|
177
|
+
this.mapObject.viewer.scene
|
178
|
+
.sampleHeightMostDetailed(cartographicPositions)
|
179
|
+
.then((pos) => {
|
180
|
+
let positions =
|
181
|
+
this.mapObject.viewer.scene.globe.ellipsoid.cartographicArrayToCartesianArray(
|
182
|
+
pos
|
183
|
+
);
|
184
|
+
|
185
|
+
if (positions[0] !== positions[positions.length - 1]) {
|
186
|
+
positions = [...positions, positions[0]];
|
187
|
+
}
|
188
|
+
|
189
|
+
self.verticsPostions = positions;
|
190
|
+
self.verticesSelected = new Array(positions.length).fill(false);
|
191
|
+
|
192
|
+
// const dynamicPositions: any = new CallbackProperty(
|
193
|
+
// () => new PolygonHierarchy(self.verticsPostions),
|
194
|
+
// false
|
195
|
+
// );
|
196
|
+
|
197
|
+
this.updateVerticesPoints();
|
198
|
+
// this.updateNonVeticesPoints();
|
199
|
+
|
200
|
+
const line = {
|
201
|
+
polyline: {
|
202
|
+
positions: new CallbackProperty(
|
203
|
+
() => [...self.verticsPostions],
|
204
|
+
false
|
205
|
+
),
|
206
|
+
width: 4,
|
207
|
+
material: Color.fromCssColorString("#FF0000"),
|
208
|
+
clampToGround: true,
|
209
|
+
},
|
210
|
+
};
|
211
|
+
|
212
|
+
this.lineLayer.entities.add(line);
|
213
|
+
|
214
|
+
resolve();
|
215
|
+
});
|
216
|
+
});
|
217
|
+
}
|
218
|
+
|
219
|
+
/** to set map bouds fit with layer data */
|
220
|
+
public setBounds(): void {
|
221
|
+
const time = this.options.setBoundsInstant ? 0 : undefined;
|
222
|
+
this.mapObject.viewer.flyTo(this.lineLayer.entities, {
|
223
|
+
duration: time,
|
224
|
+
offset: new HeadingPitchRange(
|
225
|
+
cMath.toRadians(this.mapObject.viewer.camera.heading),
|
226
|
+
-Math.PI / 2,
|
227
|
+
0
|
228
|
+
),
|
229
|
+
});
|
230
|
+
}
|
231
|
+
|
232
|
+
updateVerticesPoints(isDepth?: boolean) {
|
233
|
+
this.pointLayer.entities.values.forEach((entity: any, i: number) => {
|
234
|
+
if (entity.type === "main") {
|
235
|
+
// this.pointLayer.entities.remove(entity);
|
236
|
+
entity.position = this.verticsPostions[i];
|
237
|
+
entity.billboard.disableDepthTestDistance = isDepth
|
238
|
+
? Number.POSITIVE_INFINITY
|
239
|
+
: undefined;
|
240
|
+
this.mapObject.viewer.scene.requestRender();
|
241
|
+
}
|
242
|
+
});
|
243
|
+
|
244
|
+
if (this.pointLayer.entities.values.length > 2) {
|
245
|
+
return;
|
246
|
+
}
|
247
|
+
|
248
|
+
const svg = `<svg height="20" width="20" xmlns="http://www.w3.org/2000/svg">
|
249
|
+
<circle cx="10" cy="10" r="8.5" stroke="red" stroke-width="1.5" fill="whiteSmoke" />
|
250
|
+
</svg>`;
|
251
|
+
|
252
|
+
console.log(this.verticsPostions.length);
|
253
|
+
|
254
|
+
this.verticsPostions.forEach((position: Cartesian3) => {
|
255
|
+
const pointMain = {
|
256
|
+
position,
|
257
|
+
billboard: {
|
258
|
+
image: `data:image/svg+xml;base64,${window.btoa(svg)}`,
|
259
|
+
verticalOrigin: VerticalOrigin.CENTER,
|
260
|
+
eyeOffset: new Cartesian3(0, 0, -10),
|
261
|
+
disableDepthTestDistance: isDepth
|
262
|
+
? Number.POSITIVE_INFINITY
|
263
|
+
: undefined,
|
264
|
+
},
|
265
|
+
type: "main",
|
266
|
+
};
|
267
|
+
this.mapObject.viewer.scene.requestRender();
|
268
|
+
|
269
|
+
this.pointLayer.entities.add(pointMain);
|
270
|
+
});
|
271
|
+
|
272
|
+
this.mapObject.viewer.scene.requestRender();
|
273
|
+
}
|
274
|
+
|
275
|
+
/** Add all listeners for layer */
|
276
|
+
public addListeners() {
|
277
|
+
this.handler = new ScreenSpaceEventHandler(this.mapObject.viewer.canvas);
|
278
|
+
this.handler.setInputAction(
|
279
|
+
this.mouseMoveHandler.bind(this),
|
280
|
+
ScreenSpaceEventType.MOUSE_MOVE
|
281
|
+
);
|
282
|
+
|
283
|
+
this.handler.setInputAction(
|
284
|
+
this.mouseMoveHandler.bind(this),
|
285
|
+
ScreenSpaceEventType.PINCH_MOVE
|
286
|
+
);
|
287
|
+
}
|
288
|
+
|
289
|
+
mouseMoveHandler(event: any) {
|
290
|
+
if (!event.endPosition) {
|
291
|
+
return;
|
292
|
+
}
|
293
|
+
|
294
|
+
if (this.mouseOverEntity && this.selectedIndex >= 0) {
|
295
|
+
this.pointWasDragged = true;
|
296
|
+
|
297
|
+
const point = screenToWorldPosition(this.mapObject.viewer,event.endPosition).position;
|
298
|
+
|
299
|
+
|
300
|
+
if (!point) {
|
301
|
+
return;
|
302
|
+
}
|
303
|
+
|
304
|
+
let carto = Cartographic.fromCartesian(point);
|
305
|
+
|
306
|
+
const height = this.mapObject.viewer.scene.sampleHeight(carto);
|
307
|
+
|
308
|
+
this.verticsPostions[this.selectedIndex] = Cartesian3.fromRadians(
|
309
|
+
carto.longitude,
|
310
|
+
carto.latitude,
|
311
|
+
height
|
312
|
+
);
|
313
|
+
|
314
|
+
// console.log(Cartographic.fromCartesian(point).height);
|
315
|
+
|
316
|
+
if (this.selectedIndex === 0) {
|
317
|
+
this.verticsPostions[this.verticsPostions.length - 1] =
|
318
|
+
this.verticsPostions[0];
|
319
|
+
}
|
320
|
+
|
321
|
+
if (this.selectedIndex === this.verticsPostions.length - 1) {
|
322
|
+
this.verticsPostions[0] =
|
323
|
+
this.verticsPostions[this.verticsPostions.length - 1];
|
324
|
+
}
|
325
|
+
|
326
|
+
this.mapObject.viewer.scene.requestRender();
|
327
|
+
|
328
|
+
this.updateVerticesPoints(true);
|
329
|
+
this.mapObject.viewer.scene.requestRender();
|
330
|
+
return;
|
331
|
+
}
|
332
|
+
|
333
|
+
if (this.mapObject.viewer.scene.pickPositionSupported) {
|
334
|
+
let result: any;
|
335
|
+
|
336
|
+
const pickedObject = this.mapObject.viewer.scene.drillPick(
|
337
|
+
event.endPosition
|
338
|
+
);
|
339
|
+
|
340
|
+
const entity: any = pickedObject.filter(
|
341
|
+
(object) => object.id && object.id.billboard !== undefined
|
342
|
+
)[0];
|
343
|
+
|
344
|
+
if (entity && entity.id && entity.id instanceof Entity) {
|
345
|
+
result = {
|
346
|
+
id:
|
347
|
+
((entity as any).id.data && (entity as any).data.id) ||
|
348
|
+
entity.id.id,
|
349
|
+
point: event.position,
|
350
|
+
target: this.mapObject.viewer,
|
351
|
+
type: "mousemove",
|
352
|
+
features: [entity.id],
|
353
|
+
};
|
354
|
+
|
355
|
+
this.mouseEnter(entity, result);
|
356
|
+
// }
|
357
|
+
} else {
|
358
|
+
if (this.mouseOverEntity && !this.pointWasDragged) {
|
359
|
+
this.mouseLeave();
|
360
|
+
}
|
361
|
+
}
|
362
|
+
}
|
363
|
+
}
|
364
|
+
|
365
|
+
/**
|
366
|
+
* On mouse enter
|
367
|
+
*/
|
368
|
+
mouseEnter(entity: any, result?: any) {
|
369
|
+
if (!result.features[0]) {
|
370
|
+
return;
|
371
|
+
}
|
372
|
+
|
373
|
+
this.mapObject.viewer.canvas.style.cursor = "pointer";
|
374
|
+
this.mouseOverEntity = entity.id;
|
375
|
+
|
376
|
+
this.handler.setInputAction(
|
377
|
+
this.mouseDown.bind(this),
|
378
|
+
ScreenSpaceEventType.LEFT_DOWN
|
379
|
+
);
|
380
|
+
this.handler.setInputAction(
|
381
|
+
this.mouseUp.bind(this),
|
382
|
+
ScreenSpaceEventType.LEFT_UP
|
383
|
+
);
|
384
|
+
this.handler.setInputAction(
|
385
|
+
this.mouseDown.bind(this),
|
386
|
+
ScreenSpaceEventType.PINCH_START
|
387
|
+
);
|
388
|
+
this.handler.setInputAction(
|
389
|
+
this.mouseUp.bind(this),
|
390
|
+
ScreenSpaceEventType.PINCH_END
|
391
|
+
);
|
392
|
+
}
|
393
|
+
|
394
|
+
/**
|
395
|
+
* On mouse leave
|
396
|
+
*/
|
397
|
+
private mouseLeave = () => {
|
398
|
+
this.mapObject.viewer.scene.requestRender();
|
399
|
+
this.updateVerticesPoints();
|
400
|
+
this.selectedIndex = -1;
|
401
|
+
this.pointWasDragged = false;
|
402
|
+
this.mouseOverEntity = false;
|
403
|
+
this.mapObject.viewer.canvas.style.cursor = "default";
|
404
|
+
this.mapObject.viewer.scene.requestRender();
|
405
|
+
};
|
406
|
+
|
407
|
+
/**
|
408
|
+
* On mouse down
|
409
|
+
*/
|
410
|
+
private mouseDown = () => {
|
411
|
+
if (this.mouseOverEntity) {
|
412
|
+
const self = this;
|
413
|
+
|
414
|
+
if (this.mouseOverEntity.type === "main") {
|
415
|
+
const entityPosition: Cartesian3 =
|
416
|
+
// eslint-disable-next-line no-underscore-dangle
|
417
|
+
this.mouseOverEntity.position._value;
|
418
|
+
|
419
|
+
this.selectedIndex = self.verticsPostions.findIndex(
|
420
|
+
(position: Cartesian3) => {
|
421
|
+
if (
|
422
|
+
position.x === entityPosition.x &&
|
423
|
+
position.y === entityPosition.y &&
|
424
|
+
position.z === entityPosition.z
|
425
|
+
) {
|
426
|
+
return true;
|
427
|
+
}
|
428
|
+
return false;
|
429
|
+
}
|
430
|
+
);
|
431
|
+
}
|
432
|
+
|
433
|
+
this.mapObject.disablePan();
|
434
|
+
}
|
435
|
+
|
436
|
+
this.updateVerticesPoints();
|
437
|
+
};
|
438
|
+
|
439
|
+
/**
|
440
|
+
* On mouse up
|
441
|
+
*/
|
442
|
+
private mouseUp() {
|
443
|
+
if (this.selectedIndex === 0) {
|
444
|
+
this.verticsPostions[this.verticsPostions.length - 1] =
|
445
|
+
this.verticsPostions[0];
|
446
|
+
}
|
447
|
+
|
448
|
+
if (this.selectedIndex === this.verticsPostions.length - 1) {
|
449
|
+
this.verticsPostions[0] =
|
450
|
+
this.verticsPostions[this.verticsPostions.length - 1];
|
451
|
+
}
|
452
|
+
|
453
|
+
if (this.options.onPinchEnd && this.selectedIndex >= 0) {
|
454
|
+
this.options.onPinchEnd(this.getData());
|
455
|
+
}
|
456
|
+
|
457
|
+
this.mapObject.viewer.scene.requestRender();
|
458
|
+
|
459
|
+
this.updateVerticesPoints();
|
460
|
+
|
461
|
+
this.pointWasDragged = false;
|
462
|
+
this.mouseOverEntity = null;
|
463
|
+
this.selectedIndex = -1;
|
464
|
+
this.mapObject.enablePan();
|
465
|
+
this.mapObject.viewer.scene.requestRender();
|
466
|
+
}
|
467
|
+
|
468
|
+
/** Removes all listeners added by this layer */
|
469
|
+
public removeListeners() {
|
470
|
+
this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOWN);
|
471
|
+
this.handler.removeInputAction(ScreenSpaceEventType.LEFT_UP);
|
472
|
+
this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
|
473
|
+
this.handler.removeInputAction(ScreenSpaceEventType.PINCH_END);
|
474
|
+
this.handler.removeInputAction(ScreenSpaceEventType.PINCH_START);
|
475
|
+
this.handler.removeInputAction(ScreenSpaceEventType.PINCH_MOVE);
|
476
|
+
}
|
477
|
+
|
478
|
+
/**
|
479
|
+
* Returns the layer's data se
|
480
|
+
*/
|
481
|
+
public getData(): PolygonData {
|
482
|
+
const data: any = {
|
483
|
+
points: cartesianArrayToPointArray(this.verticsPostions),
|
484
|
+
properties: this.data.properties,
|
485
|
+
};
|
486
|
+
|
487
|
+
return data;
|
488
|
+
}
|
489
|
+
|
490
|
+
/** @inheritdoc */
|
491
|
+
remove() {
|
492
|
+
this.mapObject.viewer.dataSources.remove(this.pointLayer, true);
|
493
|
+
this.mapObject.viewer.dataSources.remove(this.lineLayer, true);
|
494
|
+
this.removeListeners();
|
495
|
+
this.mapObject.viewer.scene.requestRender();
|
496
|
+
}
|
497
|
+
|
498
|
+
/** @inheritdoc */
|
499
|
+
show() {
|
500
|
+
this.pointLayer.show = true;
|
501
|
+
this.lineLayer.show = true;
|
502
|
+
this.mapObject.viewer.scene.requestRender();
|
503
|
+
}
|
504
|
+
|
505
|
+
/** @inheritdoc */
|
506
|
+
hide() {
|
507
|
+
this.pointLayer.show = false;
|
508
|
+
this.lineLayer.show = false;
|
509
|
+
this.mapObject.viewer.scene.requestRender();
|
510
|
+
}
|
511
|
+
}
|
@@ -0,0 +1,210 @@
|
|
1
|
+
import {
|
2
|
+
Cartesian3,
|
3
|
+
CustomDataSource,
|
4
|
+
HeadingPitchRange,
|
5
|
+
Math as cMath,
|
6
|
+
} from "cesium";
|
7
|
+
|
8
|
+
import type { LineData, LineOptions } from "../app.interface";
|
9
|
+
|
10
|
+
import type CesiumView from "../droneView";
|
11
|
+
|
12
|
+
import { addPolyLineFilled, addLabel, distance3D, getMidPoint} from "../utility";
|
13
|
+
|
14
|
+
|
15
|
+
/**
|
16
|
+
* Use this class to create a marker layer
|
17
|
+
* @param {MapBox} mapObject - The mapbox map object
|
18
|
+
* @param {string} uniqueName - The unique name of the layer
|
19
|
+
* @param {LineData[]} data - The data to be used in the layer
|
20
|
+
* @param {LineOptions} options - The options for the layer (see {@link LineOptions})
|
21
|
+
*/
|
22
|
+
export default class LineLayer {
|
23
|
+
lineLayerId: string;
|
24
|
+
|
25
|
+
opacity: number;
|
26
|
+
|
27
|
+
layer: CustomDataSource;
|
28
|
+
|
29
|
+
/**
|
30
|
+
* @param { CesiumView } mapObject map object
|
31
|
+
* @param { string }uniqueName string unique name for the layer
|
32
|
+
* @param { LineData[] } data
|
33
|
+
* @param { LineOptions } options
|
34
|
+
*/
|
35
|
+
constructor(
|
36
|
+
public mapObject: CesiumView,
|
37
|
+
public uniqueName: string,
|
38
|
+
public data: LineData[],
|
39
|
+
public options: LineOptions
|
40
|
+
) {
|
41
|
+
this.lineLayerId = `Line-layer-${this.uniqueName}`;
|
42
|
+
this.opacity = 1;
|
43
|
+
this.buildLayer();
|
44
|
+
this.add(this.data).then(() => {
|
45
|
+
if (this.options.setBounds === undefined || this.options.setBounds) {
|
46
|
+
this.setBounds();
|
47
|
+
}
|
48
|
+
this.addListeners();
|
49
|
+
});
|
50
|
+
}
|
51
|
+
|
52
|
+
/** To initialize layer */
|
53
|
+
public buildLayer(): void {
|
54
|
+
if (this.mapObject.viewer.dataSources.getByName("line" + this.uniqueName)) {
|
55
|
+
this.mapObject.viewer.dataSources.remove(
|
56
|
+
this.mapObject.viewer.dataSources.getByName(
|
57
|
+
"line" + this.uniqueName
|
58
|
+
)[0],
|
59
|
+
true
|
60
|
+
);
|
61
|
+
}
|
62
|
+
this.layer = new CustomDataSource("line" + this.uniqueName);
|
63
|
+
|
64
|
+
this.mapObject.viewer.dataSources.add(this.layer);
|
65
|
+
}
|
66
|
+
|
67
|
+
/** To add layer on map */
|
68
|
+
public add(data: LineData[]) {
|
69
|
+
const self = this;
|
70
|
+
return new Promise<void>((resolve) => {
|
71
|
+
const loadCommands: any = [];
|
72
|
+
data.forEach((lineData: LineData) => {
|
73
|
+
loadCommands.push(self.addToMap(lineData));
|
74
|
+
});
|
75
|
+
|
76
|
+
Promise.all(loadCommands).then(() => {
|
77
|
+
this.mapObject.viewer.scene.requestRender();
|
78
|
+
resolve();
|
79
|
+
});
|
80
|
+
});
|
81
|
+
}
|
82
|
+
|
83
|
+
/**
|
84
|
+
* Add data on map
|
85
|
+
* @param { LineData } data
|
86
|
+
*/
|
87
|
+
public addToMap(data: LineData) {
|
88
|
+
let zOffset = 0; // To add this layer little above to prevous layer
|
89
|
+
if (this.mapObject.layers.line) {
|
90
|
+
zOffset = this.mapObject.layers.line.length * 0.1;
|
91
|
+
}
|
92
|
+
|
93
|
+
return new Promise<void>((resolve) => {
|
94
|
+
|
95
|
+
const line = addPolyLineFilled(
|
96
|
+
this.mapObject.viewer,
|
97
|
+
Cartesian3.fromDegreesArrayHeights(data.points.flat()),
|
98
|
+
{
|
99
|
+
type: "LineString",
|
100
|
+
lineColor: data.properties.color,
|
101
|
+
lineWidth: +data.properties.lineWidth || 3,
|
102
|
+
opacity: +this.opacity,
|
103
|
+
measurement: false
|
104
|
+
},
|
105
|
+
this.lineLayerId,
|
106
|
+
data.properties
|
107
|
+
);
|
108
|
+
this.layer.entities.add(line);
|
109
|
+
|
110
|
+
console.log("data points", data.points)
|
111
|
+
for (var i = 0; i < data.points.length - 1; i++) {
|
112
|
+
const convertedCoords = Cartesian3.fromDegreesArrayHeights(data.points.flat())
|
113
|
+
var firstCoordinate = convertedCoords[i]
|
114
|
+
var secondCoordinate = convertedCoords[i+1]
|
115
|
+
|
116
|
+
const distance = distance3D([
|
117
|
+
firstCoordinate,
|
118
|
+
secondCoordinate,
|
119
|
+
]);
|
120
|
+
|
121
|
+
addLabel(this.mapObject.viewer, {
|
122
|
+
position: getMidPoint(firstCoordinate,secondCoordinate),
|
123
|
+
text: `${distance.toFixed(2).toString()} m`,
|
124
|
+
id: data.properties.label
|
125
|
+
});
|
126
|
+
}
|
127
|
+
|
128
|
+
resolve();
|
129
|
+
});
|
130
|
+
}
|
131
|
+
|
132
|
+
/**
|
133
|
+
* With the correct LayerOptions configuration
|
134
|
+
* the map will fit its bounds around the given feature set
|
135
|
+
* @param features Array<MarkerData>
|
136
|
+
*/
|
137
|
+
public setBounds(): void {
|
138
|
+
const time = this.options.setBoundsInstant ? 0 : undefined;
|
139
|
+
this.mapObject.viewer.flyTo(this.layer.entities, {
|
140
|
+
duration: time,
|
141
|
+
offset: new HeadingPitchRange(
|
142
|
+
cMath.toRadians(this.mapObject.viewer.camera.heading),
|
143
|
+
-Math.PI / 2,
|
144
|
+
0
|
145
|
+
),
|
146
|
+
});
|
147
|
+
}
|
148
|
+
|
149
|
+
public addListeners() {
|
150
|
+
this.mapObject.addLayerListener('click', this.lineLayerId, (event: any) => {
|
151
|
+
if(this.options.onClick){
|
152
|
+
this.options.onClick(event);
|
153
|
+
}
|
154
|
+
});
|
155
|
+
|
156
|
+
this.mapObject.addLayerListener(
|
157
|
+
'mousemove',
|
158
|
+
this.lineLayerId,
|
159
|
+
(event: any) => {
|
160
|
+
this.mapObject.viewer.canvas.style.cursor = 'pointer';
|
161
|
+
}
|
162
|
+
);
|
163
|
+
|
164
|
+
this.mapObject.addLayerListener(
|
165
|
+
'mouseenter',
|
166
|
+
this.lineLayerId,
|
167
|
+
(event: any) => {
|
168
|
+
this.mapObject.viewer.canvas.style.cursor = 'pointer';
|
169
|
+
}
|
170
|
+
);
|
171
|
+
|
172
|
+
this.mapObject.addLayerListener('mouseout', this.lineLayerId, () => {
|
173
|
+
this.mapObject.viewer.canvas.style.cursor = '';
|
174
|
+
});
|
175
|
+
}
|
176
|
+
|
177
|
+
/** Removes all listeners added by this layer */
|
178
|
+
public removeListeners() {
|
179
|
+
this.mapObject.removeLayerListeners(this.lineLayerId);
|
180
|
+
}
|
181
|
+
|
182
|
+
/** Remove layer from map and destroy layer */
|
183
|
+
public remove(): void {
|
184
|
+
this.mapObject.viewer.dataSources.remove(this.layer, true);
|
185
|
+
this.removeListeners();
|
186
|
+
this.mapObject.viewer.scene.requestRender();
|
187
|
+
}
|
188
|
+
|
189
|
+
/**
|
190
|
+
* Sets opacity of the layer
|
191
|
+
* @param opacity number between 0-1
|
192
|
+
*/
|
193
|
+
public setOpacity(opacity: number): void {
|
194
|
+
this.opacity = opacity;
|
195
|
+
this.buildLayer();
|
196
|
+
this.add(this.data);
|
197
|
+
}
|
198
|
+
|
199
|
+
/** enables visibility of the layer */
|
200
|
+
public show(): void {
|
201
|
+
this.layer.show = true;
|
202
|
+
this.mapObject.viewer.entities.show = true;
|
203
|
+
}
|
204
|
+
|
205
|
+
/** Disables visibility of the layer */
|
206
|
+
public hide(): void {
|
207
|
+
this.layer.show = false;
|
208
|
+
this.mapObject.viewer.entities.show = false
|
209
|
+
}
|
210
|
+
}
|