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
package/src/utility.ts
ADDED
@@ -0,0 +1,802 @@
|
|
1
|
+
import {
|
2
|
+
BoundingSphere,
|
3
|
+
Cartesian2,
|
4
|
+
Cartesian3,
|
5
|
+
Color,
|
6
|
+
VerticalOrigin,
|
7
|
+
Viewer,
|
8
|
+
CallbackProperty,
|
9
|
+
defined,
|
10
|
+
Entity,
|
11
|
+
HorizontalOrigin,
|
12
|
+
Math as cMath,
|
13
|
+
PolylineDashMaterialProperty,
|
14
|
+
HeightReference,
|
15
|
+
Ellipsoid,
|
16
|
+
LabelStyle,
|
17
|
+
DistanceDisplayCondition,
|
18
|
+
HeadingPitchRoll,
|
19
|
+
Transforms,
|
20
|
+
Quaternion, Matrix3
|
21
|
+
} from "cesium";
|
22
|
+
// @ts-ignore
|
23
|
+
import * as Normalize from "normalize-value";
|
24
|
+
import * as Cesium from "cesium";
|
25
|
+
import type {
|
26
|
+
DrawingConfig,
|
27
|
+
Point,
|
28
|
+
LabelConfigByCartesian,
|
29
|
+
} from "./app.interface";
|
30
|
+
|
31
|
+
// Min map scale wrt google map
|
32
|
+
export const mapScale = 591657550.5;
|
33
|
+
// Map Maximum zoom level
|
34
|
+
export const mapMaxZoom = 23;
|
35
|
+
// Map min zoom level
|
36
|
+
export const mapMinZoom = 0;
|
37
|
+
|
38
|
+
/**
|
39
|
+
* To check object exist in cesium viewer
|
40
|
+
* @param obj Cesium object
|
41
|
+
* @returns boolean
|
42
|
+
*/
|
43
|
+
export const isCesiumObject = (obj: any) => defined(obj);
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Convert camera distance to zoom level
|
47
|
+
* @param height number distance between camera position and map earth surface
|
48
|
+
* @returns number zoom level between 0-23
|
49
|
+
*/
|
50
|
+
export const cameraHeightToZoomLevel = (height: number): number => {
|
51
|
+
for (let i = mapMinZoom; i <= mapMaxZoom; i += 1) {
|
52
|
+
// To check camera distance from earth lies between which zoom levels
|
53
|
+
if (height >= mapScale / 2 ** +(i + 1) && height < mapScale / 2 ** +i) {
|
54
|
+
const afterDecimal = Normalize.default(height, [
|
55
|
+
{ value: mapScale / 2 ** +(i + 1), norm: 0 },
|
56
|
+
{ value: mapScale / 2 ** +i, norm: 1 },
|
57
|
+
]);
|
58
|
+
return i + afterDecimal;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
throw new Error("Something went wrong");
|
63
|
+
};
|
64
|
+
|
65
|
+
/**
|
66
|
+
* Covert zoom level to camera distance
|
67
|
+
* @param zoom Zoom level
|
68
|
+
* @returns Distance between camera and earth surface
|
69
|
+
*/
|
70
|
+
export const zoomLevelToCameraHeight = (zoom: number): number =>
|
71
|
+
Normalize.default(
|
72
|
+
zoom.toString().split(".")[1] ? +zoom.toString().split(".")[1] : 0,
|
73
|
+
[
|
74
|
+
{
|
75
|
+
value: 0,
|
76
|
+
norm: mapScale / 2 ** +(zoom + 1).toString().split(".")[0],
|
77
|
+
},
|
78
|
+
{ value: 1, norm: mapScale / 2 ** +zoom.toString().split(".")[0] },
|
79
|
+
]
|
80
|
+
);
|
81
|
+
|
82
|
+
/**
|
83
|
+
* This method allows user to convert position from Latitude,
|
84
|
+
* Longitude & altitude to Cesium Cartesian3 format
|
85
|
+
* @param position - Json object contains Latitude, Longitude & Altitude
|
86
|
+
* @returns - Cesium Cartesian3 Position
|
87
|
+
*/
|
88
|
+
export const PointToCartesian = (position: Point): Cartesian3 => {
|
89
|
+
const cartesian = Cartesian3.fromDegrees(
|
90
|
+
+position.long,
|
91
|
+
+position.lat,
|
92
|
+
+(position.height || 0)
|
93
|
+
);
|
94
|
+
return cartesian;
|
95
|
+
};
|
96
|
+
|
97
|
+
/**
|
98
|
+
* To convert Cartesian3 to Point
|
99
|
+
* @param position Cartesian3 position
|
100
|
+
* @returns Point
|
101
|
+
*/
|
102
|
+
export const cartesianToPoint = (position: Cartesian3): Point => {
|
103
|
+
const cartographic = Ellipsoid.WGS84.cartesianToCartographic(position);
|
104
|
+
return {
|
105
|
+
long: cMath.toDegrees(cartographic.longitude),
|
106
|
+
lat: cMath.toDegrees(cartographic.latitude),
|
107
|
+
height: cartographic.height,
|
108
|
+
};
|
109
|
+
};
|
110
|
+
|
111
|
+
/**
|
112
|
+
* This Function is for converting array of Cartesian to lat lng
|
113
|
+
* @param { Cartesian3[] } positions - Array of Cesium Cartesian3 Position
|
114
|
+
* @returns Array of longitude, latitude & height
|
115
|
+
*/
|
116
|
+
export const cartesianArrayToPointArray = (positions: Cartesian3[]) => {
|
117
|
+
const langLats: any = [];
|
118
|
+
positions.forEach((position) => {
|
119
|
+
const cartographic = Ellipsoid.WGS84.cartesianToCartographic(position);
|
120
|
+
langLats.push([
|
121
|
+
cMath.toDegrees(cartographic.longitude),
|
122
|
+
cMath.toDegrees(cartographic.latitude),
|
123
|
+
cartographic.height,
|
124
|
+
]);
|
125
|
+
});
|
126
|
+
return langLats;
|
127
|
+
};
|
128
|
+
|
129
|
+
/**
|
130
|
+
* To
|
131
|
+
* @param { Point[] } positions
|
132
|
+
* @returns { Cartesian3[] }
|
133
|
+
*/
|
134
|
+
export const pointArrayToCartesianArray = (positions: Array<Array<number>>) => {
|
135
|
+
const cartesians: Cartesian3[] = [];
|
136
|
+
positions.forEach((position) => {
|
137
|
+
cartesians.push(
|
138
|
+
PointToCartesian({
|
139
|
+
lat: +position[1],
|
140
|
+
long: +position[0],
|
141
|
+
height: +(position[2] || 0),
|
142
|
+
})
|
143
|
+
);
|
144
|
+
});
|
145
|
+
return cartesians;
|
146
|
+
};
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Covert cesium coordinates to geojson feature collection
|
150
|
+
* @param positions Array<Cartesian3>
|
151
|
+
* @param type DrawingConfig['type']
|
152
|
+
* @returns any
|
153
|
+
*/
|
154
|
+
export const cartesianToGeojson = (
|
155
|
+
positions: Array<Cartesian3>,
|
156
|
+
type: DrawingConfig["type"],
|
157
|
+
properties?: any
|
158
|
+
) => {
|
159
|
+
const features: any = [];
|
160
|
+
if (type === "Polygon") {
|
161
|
+
const feature = {
|
162
|
+
type: "Feature",
|
163
|
+
geometry: {
|
164
|
+
type: "Polygon",
|
165
|
+
coordinates: [cartesianArrayToPointArray(positions)],
|
166
|
+
},
|
167
|
+
};
|
168
|
+
features.push(feature);
|
169
|
+
} else if (type === "Point") {
|
170
|
+
positions.forEach((position) => {
|
171
|
+
const feature = {
|
172
|
+
type: "Feature",
|
173
|
+
geometry: {
|
174
|
+
type: "Point",
|
175
|
+
coordinates: [
|
176
|
+
cartesianToPoint(position).long,
|
177
|
+
cartesianToPoint(position).lat,
|
178
|
+
cartesianToPoint(position).height,
|
179
|
+
],
|
180
|
+
},
|
181
|
+
};
|
182
|
+
features.push(feature);
|
183
|
+
});
|
184
|
+
} else {
|
185
|
+
const feature = {
|
186
|
+
type: "Feature",
|
187
|
+
geometry: {
|
188
|
+
type: "LineString",
|
189
|
+
coordinates: cartesianArrayToPointArray(positions),
|
190
|
+
},
|
191
|
+
};
|
192
|
+
features.push(feature);
|
193
|
+
}
|
194
|
+
|
195
|
+
const geojson = {
|
196
|
+
type: "FeatureCollection",
|
197
|
+
features,
|
198
|
+
properties,
|
199
|
+
};
|
200
|
+
|
201
|
+
return geojson;
|
202
|
+
};
|
203
|
+
|
204
|
+
// eslint-disable-next-line consistent-return
|
205
|
+
export const getEntityById = (viewer: Viewer, windowPosition: Cartesian2) => {
|
206
|
+
let object;
|
207
|
+
if (viewer.scene.pickPositionSupported) {
|
208
|
+
const pickedObject = viewer.scene.pick(windowPosition);
|
209
|
+
|
210
|
+
if (pickedObject?.id instanceof Entity) {
|
211
|
+
object = pickedObject.id;
|
212
|
+
}
|
213
|
+
return object;
|
214
|
+
}
|
215
|
+
};
|
216
|
+
|
217
|
+
/**
|
218
|
+
* Get global position from mouse screen position
|
219
|
+
* @param viewer Viewer
|
220
|
+
* @param windowPosition Mouse window position object
|
221
|
+
* @returns Object with feature details and position
|
222
|
+
*/
|
223
|
+
export const screenToWorldPosition = (
|
224
|
+
viewer: Viewer,
|
225
|
+
windowPosition: Cartesian2
|
226
|
+
):
|
227
|
+
| {
|
228
|
+
data?: { [key: string]: string };
|
229
|
+
position: Cartesian3;
|
230
|
+
id?: string;
|
231
|
+
layerId?: string;
|
232
|
+
}
|
233
|
+
| any => {
|
234
|
+
const entity = getEntityById(viewer, windowPosition);
|
235
|
+
const position = viewer.scene.pickPosition(windowPosition);
|
236
|
+
if (position) {
|
237
|
+
return {
|
238
|
+
position,
|
239
|
+
data: entity?.data,
|
240
|
+
id: entity ? entity : undefined,
|
241
|
+
layerId: entity?.layerId,
|
242
|
+
};
|
243
|
+
}
|
244
|
+
|
245
|
+
const ray = viewer.scene.camera.getPickRay(windowPosition)!;
|
246
|
+
return { position: viewer.scene.globe.pick(ray, viewer.scene)! };
|
247
|
+
};
|
248
|
+
|
249
|
+
/**
|
250
|
+
* This function allows user to get distance between two points
|
251
|
+
* @param left - Position first
|
252
|
+
* @param right - Position second
|
253
|
+
* @returns Distance between first and second position in meter
|
254
|
+
*/
|
255
|
+
export const distance2D = (left: Cartesian2, right: Cartesian2): number => {
|
256
|
+
const distance = Cartesian2.distance(left, right);
|
257
|
+
return distance;
|
258
|
+
};
|
259
|
+
|
260
|
+
/**
|
261
|
+
* This function allows user to compute sum of distances between the positions
|
262
|
+
* @param position - Array of positions
|
263
|
+
* @returns Sum of distances between the positions in meter
|
264
|
+
*/
|
265
|
+
export const distance3D = (positions: Array<Cartesian3>): number => {
|
266
|
+
let length = 0;
|
267
|
+
for (let i = 0; i < positions.length - 1; i += 1) {
|
268
|
+
length += Cartesian3.distance(positions[i], positions[i + 1]);
|
269
|
+
}
|
270
|
+
return length;
|
271
|
+
};
|
272
|
+
|
273
|
+
/**
|
274
|
+
* This function allows user to get mid point between two position
|
275
|
+
* @param left - first position
|
276
|
+
* @param right - second position
|
277
|
+
* @returns Mid Point in Cartesian3 format
|
278
|
+
*/
|
279
|
+
export const getMidPoint = (
|
280
|
+
left: Cartesian3,
|
281
|
+
right: Cartesian3
|
282
|
+
): Cartesian3 => {
|
283
|
+
const midPoint = Cartesian3.add(left, right, new Cartesian3());
|
284
|
+
Cartesian3.multiplyByScalar(midPoint, 0.5, midPoint);
|
285
|
+
return midPoint;
|
286
|
+
};
|
287
|
+
|
288
|
+
export const getPolygonCenter = (positions: Array<Cartesian3>): Cartesian3 => {
|
289
|
+
const { center } = BoundingSphere.fromPoints(positions);
|
290
|
+
return center;
|
291
|
+
};
|
292
|
+
|
293
|
+
/**
|
294
|
+
* This function allows user to get area of 3D Polygon
|
295
|
+
* @param polygonEntity : Cesium Polygon entity/geometry
|
296
|
+
* @returns Area in square meter
|
297
|
+
*/
|
298
|
+
export const calculateArea = (pointData: Array<Point>): number => {
|
299
|
+
let area = 0;
|
300
|
+
const positions: any = [];
|
301
|
+
pointData.forEach((point) => {
|
302
|
+
positions.push(PointToCartesian(point));
|
303
|
+
});
|
304
|
+
|
305
|
+
for (let i = 0; i < positions.length - 2; i += 1) {
|
306
|
+
const vector1 = positions[0];
|
307
|
+
const vector2 = positions[i + 1];
|
308
|
+
const vector3 = positions[i + 2];
|
309
|
+
const vectorC = Cartesian3.subtract(vector2, vector1, new Cartesian3());
|
310
|
+
const vectorD = Cartesian3.subtract(vector3, vector1, new Cartesian3());
|
311
|
+
const areaVector = Cartesian3.cross(vectorC, vectorD, new Cartesian3());
|
312
|
+
area += Cartesian3.magnitude(areaVector) / 2.0;
|
313
|
+
}
|
314
|
+
return area;
|
315
|
+
};
|
316
|
+
|
317
|
+
export const calculate3DArea = (geoPoints: Point[]): number => {
|
318
|
+
const points: Cartesian3[] = geoPoints.map((p) =>
|
319
|
+
Cartesian3.fromDegrees(Number(p.long), Number(p.lat), Number(p.height) || 0)
|
320
|
+
);
|
321
|
+
console.log('dddddd',points)
|
322
|
+
if (points.length < 3) return 0; // Not enough points to form an area
|
323
|
+
|
324
|
+
let area = 0;
|
325
|
+
const origin = points[0];
|
326
|
+
|
327
|
+
for (let i = 1; i < points.length - 1; i++) {
|
328
|
+
const vec1 = Cartesian3.subtract(points[i], origin, new Cartesian3());
|
329
|
+
const vec2 = Cartesian3.subtract(points[i + 1], origin, new Cartesian3());
|
330
|
+
const cross = Cartesian3.cross(vec1, vec2, new Cartesian3());
|
331
|
+
const triangleArea = Cartesian3.magnitude(cross) / 2.0;
|
332
|
+
area += triangleArea;
|
333
|
+
}
|
334
|
+
|
335
|
+
return area;
|
336
|
+
};
|
337
|
+
|
338
|
+
export const calculate3DPerimeter = (points: Point[]): number => {
|
339
|
+
const cartesianPoints = points.map(p =>
|
340
|
+
Cartesian3.fromDegrees(Number(p.long), Number(p.lat), Number(p.height) || 0)
|
341
|
+
);
|
342
|
+
|
343
|
+
let length = 0;
|
344
|
+
for (let i = 0; i < cartesianPoints.length; i++) {
|
345
|
+
const current = cartesianPoints[i];
|
346
|
+
const next = cartesianPoints[(i + 1) % cartesianPoints.length]; // loop back to start
|
347
|
+
length += Cartesian3.distance(current, next);
|
348
|
+
}
|
349
|
+
|
350
|
+
return length; // in meters
|
351
|
+
};
|
352
|
+
|
353
|
+
/**
|
354
|
+
* This method allows user to add a point on map on a position
|
355
|
+
* @param viewer - Cesium Viewer object
|
356
|
+
* @param position - Cesium Cartesian3 position
|
357
|
+
* @param id - Id thats user want to assign point entity
|
358
|
+
* @param id - Id thats user want to assign point entity
|
359
|
+
* @returns - Point type Entity
|
360
|
+
*/
|
361
|
+
export const addPoint = (
|
362
|
+
viewer: Viewer,
|
363
|
+
position: Cartesian3,
|
364
|
+
id?: string,
|
365
|
+
size?: number,
|
366
|
+
color?: CallbackProperty,
|
367
|
+
noOutline?: boolean
|
368
|
+
): Entity => {
|
369
|
+
if (id && viewer.entities.getById(id))
|
370
|
+
viewer.entities.remove(viewer.entities.getById(id)!);
|
371
|
+
|
372
|
+
const svg = `<svg height="20" width="20" xmlns="http://www.w3.org/2000/svg">
|
373
|
+
<circle cx="10" cy="10" r="8.5" stroke="red" stroke-width="1.5" fill="whiteSmoke" />
|
374
|
+
</svg>`;
|
375
|
+
|
376
|
+
const point = viewer.entities.add({
|
377
|
+
id,
|
378
|
+
position,
|
379
|
+
// point: {
|
380
|
+
// pixelSize: size || 10,
|
381
|
+
// color: color || Color.WHITE,
|
382
|
+
// heightReference: HeightReference.RELATIVE_TO_GROUND,
|
383
|
+
// outlineColor: Color.BLACK,
|
384
|
+
// outlineWidth: noOutline ? 0 : 3,
|
385
|
+
// // disableDepthTestDistance: 10
|
386
|
+
// },
|
387
|
+
billboard: {
|
388
|
+
image: `data:image/svg+xml;base64,${window.btoa(svg)}`,
|
389
|
+
verticalOrigin: VerticalOrigin.CENTER,
|
390
|
+
eyeOffset: new Cartesian3(0, 0, -1),
|
391
|
+
},
|
392
|
+
});
|
393
|
+
return point;
|
394
|
+
};
|
395
|
+
|
396
|
+
/**
|
397
|
+
* This method allows user to add a polyline on map using set of user provided position
|
398
|
+
* @param viewer - Cesium Viewer object
|
399
|
+
* @param positions - Array of position in Cesium cartesian3
|
400
|
+
* @param config - Configuration object to control color & width of line
|
401
|
+
* @returns - Cesium Polyline entity
|
402
|
+
*/
|
403
|
+
export const addPolyLineFilled = (
|
404
|
+
viewer: Viewer,
|
405
|
+
positions: Array<Cartesian3>,
|
406
|
+
config?: DrawingConfig,
|
407
|
+
layerId?: string,
|
408
|
+
properties?: any
|
409
|
+
): any => {
|
410
|
+
if (config?.id && viewer.entities.getById(config.id)) {
|
411
|
+
viewer.entities.remove(viewer.entities.getById(config.id)!);
|
412
|
+
}
|
413
|
+
|
414
|
+
return {
|
415
|
+
id: config?.id,
|
416
|
+
polyline: {
|
417
|
+
// classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
418
|
+
depthFailMaterial: config?.lineColor
|
419
|
+
? Color.fromCssColorString(config.lineColor)
|
420
|
+
: Color.fromCssColorString("#FF0000"),
|
421
|
+
positions,
|
422
|
+
width: config?.lineWidth ? config?.lineWidth : 3,
|
423
|
+
|
424
|
+
material: config?.lineColor
|
425
|
+
? Color.fromCssColorString(config.lineColor).withAlpha(
|
426
|
+
config.opacity ? config.opacity : 1
|
427
|
+
)
|
428
|
+
: Color.fromCssColorString("#FFC72C").withAlpha(
|
429
|
+
config?.opacity ? config.opacity : 1
|
430
|
+
),
|
431
|
+
clampToGround: properties?.clamp,
|
432
|
+
},
|
433
|
+
layerId,
|
434
|
+
heightReference: HeightReference.CLAMP_TO_GROUND,
|
435
|
+
data: properties,
|
436
|
+
};
|
437
|
+
};
|
438
|
+
|
439
|
+
/**
|
440
|
+
* Get pyramid cone for camera position
|
441
|
+
* @param position - position in Cesium cartesian3
|
442
|
+
* @param layerId - layer Id
|
443
|
+
* @param url - image url
|
444
|
+
* @returns - Cesium Polyline entity
|
445
|
+
*/
|
446
|
+
export const getPyramid = (
|
447
|
+
position: Cartesian3,
|
448
|
+
layerId?: string,
|
449
|
+
url?: string,
|
450
|
+
angle?: number,
|
451
|
+
z_angle?: number,
|
452
|
+
flightpitchdegree?: number,
|
453
|
+
flightrolldegree?: number,
|
454
|
+
flightyawdegree?: number,
|
455
|
+
directionVector?: [number, number, number]
|
456
|
+
): any => {
|
457
|
+
|
458
|
+
let orientation: Quaternion;
|
459
|
+
|
460
|
+
// Check if direction vector is provided, otherwise calculate from yaw and pitch
|
461
|
+
if (directionVector) {
|
462
|
+
const direction = new Cartesian3(directionVector[0], directionVector[1], directionVector[2]);
|
463
|
+
// Calculate orientation using the direction vector
|
464
|
+
orientation = getOrientationFromDirectionVector(position, direction);
|
465
|
+
} else {
|
466
|
+
// If no direction vector, use yaw, pitch, and roll
|
467
|
+
const heading = cMath.toRadians(angle || 0);
|
468
|
+
const pitch = cMath.toRadians(z_angle || 0);
|
469
|
+
const roll = cMath.toRadians(flightrolldegree || 0);
|
470
|
+
const hpr = new HeadingPitchRoll(heading, pitch, roll);
|
471
|
+
orientation = Transforms.headingPitchRollQuaternion(position, hpr);
|
472
|
+
}
|
473
|
+
|
474
|
+
return {
|
475
|
+
position: position,
|
476
|
+
orientation: orientation,
|
477
|
+
cylinder: {
|
478
|
+
topRadius: 0,
|
479
|
+
bottomRadius: 1.5,
|
480
|
+
length: 1.5,
|
481
|
+
slices: 4,
|
482
|
+
material: Color.WHITE.withAlpha(0.01),
|
483
|
+
outline: true,
|
484
|
+
outlineColor: Color.WHITE,
|
485
|
+
outlineWidth: 5,
|
486
|
+
},
|
487
|
+
layerId,
|
488
|
+
data: { url },
|
489
|
+
};
|
490
|
+
};
|
491
|
+
|
492
|
+
function getOrientationFromDirectionVector(position: Cartesian3, direction: Cartesian3): Quaternion {
|
493
|
+
// Compute the rotation matrix from the direction vector
|
494
|
+
const up = Cartesian3.UNIT_Z; // Up direction
|
495
|
+
const right = Cartesian3.cross(up, direction, new Cartesian3()); // Right direction (cross product)
|
496
|
+
const finalUp = Cartesian3.cross(direction, right, new Cartesian3()); // Final Up vector (cross product)
|
497
|
+
|
498
|
+
const rotationMatrix = new Matrix3(
|
499
|
+
right.x, right.y, right.z,
|
500
|
+
finalUp.x, finalUp.y, finalUp.z,
|
501
|
+
-direction.x, -direction.y, -direction.z
|
502
|
+
);
|
503
|
+
|
504
|
+
// Convert the rotation matrix to a quaternion for orientation
|
505
|
+
return Quaternion.fromRotationMatrix(rotationMatrix);
|
506
|
+
}
|
507
|
+
|
508
|
+
/**
|
509
|
+
* Get pyramid cone for camera position
|
510
|
+
* @param position - position in Cesium cartesian3
|
511
|
+
* @param layerId - layer Id
|
512
|
+
* @param url - image url
|
513
|
+
* @returns - Cesium Polyline entity
|
514
|
+
*/
|
515
|
+
export const getTriangle = (
|
516
|
+
position: Cartesian3,
|
517
|
+
layerId?: string,
|
518
|
+
url?: string,
|
519
|
+
angle?: number,
|
520
|
+
z_angle?: number,
|
521
|
+
flightpitchdegree?: number,
|
522
|
+
flightrolldegree?: number,
|
523
|
+
flightyawdegree?: number
|
524
|
+
): any => {
|
525
|
+
const heading = cMath.toRadians(flightyawdegree || 0);
|
526
|
+
const pitch = cMath.toRadians(flightpitchdegree || 0);
|
527
|
+
const roll = cMath.toRadians(flightrolldegree || 0);
|
528
|
+
|
529
|
+
const hpr: any = new HeadingPitchRoll(heading, pitch, roll);
|
530
|
+
const orientation: any = Transforms.headingPitchRollQuaternion(position, hpr);
|
531
|
+
|
532
|
+
|
533
|
+
return {
|
534
|
+
position: Cesium.Matrix4.multiplyByPoint(
|
535
|
+
Cesium.Transforms.eastNorthUpToFixedFrame(position),
|
536
|
+
new Cesium.Cartesian3(0, 1.5, 0),
|
537
|
+
new Cesium.Cartesian3()
|
538
|
+
),
|
539
|
+
orientation: orientation,
|
540
|
+
cylinder: {
|
541
|
+
topRadius: 0.5,
|
542
|
+
bottomRadius: 0.5,
|
543
|
+
length: 0.001,
|
544
|
+
slices: 3,
|
545
|
+
material: Color.WHITE.withAlpha(0.01),
|
546
|
+
outline: true,
|
547
|
+
outlineColor: Color.WHITE,
|
548
|
+
outlineWidth: 5,
|
549
|
+
},
|
550
|
+
layerId,
|
551
|
+
data: { url },
|
552
|
+
};
|
553
|
+
};
|
554
|
+
|
555
|
+
/**
|
556
|
+
* This function allows user to add polygon on map
|
557
|
+
* @param viewer - Cesium Viewer object
|
558
|
+
* @param positions - Cesium Polygon Hierarchy
|
559
|
+
* @param config - Configuration Object to control fill color
|
560
|
+
* @returns Cesium Polygon entity
|
561
|
+
*/
|
562
|
+
export const getPolygonEntity = (
|
563
|
+
positions: any,
|
564
|
+
layerId: string,
|
565
|
+
opacity: number,
|
566
|
+
properties?: any,
|
567
|
+
outline?: boolean,
|
568
|
+
clampToGround?: boolean,
|
569
|
+
near?: number,
|
570
|
+
far?: number
|
571
|
+
): any => ({
|
572
|
+
polygon: {
|
573
|
+
hierarchy: positions,
|
574
|
+
// perPositionHeight: true,
|
575
|
+
// heightReference: HeightReference.CLAMP_TO_GROUND,
|
576
|
+
outline: true,
|
577
|
+
fill: true,
|
578
|
+
outlineWidth: 5,
|
579
|
+
outlineColor: properties.color
|
580
|
+
? Color.fromCssColorString(properties.color).withAlpha(1)
|
581
|
+
: Color.fromCssColorString("#FFC72C").withAlpha(1),
|
582
|
+
material: properties.color
|
583
|
+
? Color.fromCssColorString(properties.color).withAlpha(opacity || 0.0)
|
584
|
+
: Color.fromCssColorString("#FFC72C").withAlpha(opacity || 0.0),
|
585
|
+
|
586
|
+
clampToGround: !!clampToGround,
|
587
|
+
// distanceDisplayCondition: new DistanceDisplayCondition(near, far),
|
588
|
+
},
|
589
|
+
layerId,
|
590
|
+
data: properties,
|
591
|
+
});
|
592
|
+
|
593
|
+
/**
|
594
|
+
* this function will add a label on map and return label entity
|
595
|
+
* @param viewer - Cesium viewer object
|
596
|
+
* @param config - LabelConfigByCartesian
|
597
|
+
* @returns - Cesium label entity
|
598
|
+
*/
|
599
|
+
export const getLabelEntity = (
|
600
|
+
text: string,
|
601
|
+
position: Cartesian3,
|
602
|
+
near?: number,
|
603
|
+
far?: number
|
604
|
+
): any => ({
|
605
|
+
position,
|
606
|
+
label: {
|
607
|
+
text,
|
608
|
+
font: `14px Roboto Condensed`,
|
609
|
+
fillColor: Color.BLACK,
|
610
|
+
showBackground: true,
|
611
|
+
backgroundColor: Color.WHITESMOKE,
|
612
|
+
horizontalOrigin: HorizontalOrigin.CENTER,
|
613
|
+
verticalOrigin: VerticalOrigin.CENTER,
|
614
|
+
style: LabelStyle.FILL,
|
615
|
+
// heightReference: HeightReference.CLAMP_TO_GROUND,
|
616
|
+
eyeOffset: new Cartesian3(0, 0, 10),
|
617
|
+
distanceDisplayCondition: new DistanceDisplayCondition(near, far),
|
618
|
+
},
|
619
|
+
});
|
620
|
+
|
621
|
+
/**
|
622
|
+
* This method allows user to add a dashed polyline on map using set of user provided position
|
623
|
+
* @param viewer - Cesium Viewer object
|
624
|
+
* @param positions - Array of position in Cesium cartesian3
|
625
|
+
* @param config - Configuration object to control color & width of line
|
626
|
+
* @returns - Cesium Polyline entity
|
627
|
+
*/
|
628
|
+
export const addPolyLine = (
|
629
|
+
viewer: Viewer,
|
630
|
+
positions: Array<Cartesian3>,
|
631
|
+
config?: DrawingConfig,
|
632
|
+
isDashed: boolean = true
|
633
|
+
): Entity => {
|
634
|
+
if (config?.id && viewer.entities.getById(config.id)) {
|
635
|
+
viewer.entities.remove(viewer.entities.getById(config.id)!);
|
636
|
+
}
|
637
|
+
|
638
|
+
console.log(config?.clamp);
|
639
|
+
|
640
|
+
const polyline = viewer.entities.add({
|
641
|
+
id: config?.id,
|
642
|
+
polyline: {
|
643
|
+
// classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
644
|
+
depthFailMaterial: isDashed
|
645
|
+
? new PolylineDashMaterialProperty({
|
646
|
+
color: config?.lineColor
|
647
|
+
? Color.fromCssColorString(config.lineColor)
|
648
|
+
: Color.fromCssColorString("#FF0000"),
|
649
|
+
dashLength: 10,
|
650
|
+
})
|
651
|
+
: config?.lineColor
|
652
|
+
? Color.fromCssColorString(config.lineColor)
|
653
|
+
: Color.fromCssColorString("#FF0000"),
|
654
|
+
positions,
|
655
|
+
width: config?.lineWidth ? config?.lineWidth : 3,
|
656
|
+
|
657
|
+
material: isDashed
|
658
|
+
? new PolylineDashMaterialProperty({
|
659
|
+
color: config?.lineColor
|
660
|
+
? Color.fromCssColorString(config.lineColor)
|
661
|
+
: Color.fromCssColorString("#FF0000"),
|
662
|
+
dashLength: 10,
|
663
|
+
})
|
664
|
+
: config?.lineColor
|
665
|
+
? Color.fromCssColorString(config.lineColor)
|
666
|
+
: Color.fromCssColorString("#FF0000"),
|
667
|
+
clampToGround: !!config?.clamp,
|
668
|
+
},
|
669
|
+
});
|
670
|
+
|
671
|
+
(polyline as any).config = config;
|
672
|
+
return polyline;
|
673
|
+
};
|
674
|
+
|
675
|
+
/**
|
676
|
+
* This function allows user to add polygon on map
|
677
|
+
* @param viewer - Cesium Viewer object
|
678
|
+
* @param positions - Cesium Polygon Hierarchy
|
679
|
+
* @param config - Configuration Object to control fill color
|
680
|
+
* @returns Cesium Polygon entity
|
681
|
+
*/
|
682
|
+
export const addPolygon = (
|
683
|
+
viewer: Viewer,
|
684
|
+
positions: any,
|
685
|
+
config?: DrawingConfig
|
686
|
+
): Entity => {
|
687
|
+
if (config?.id && viewer.entities.getById(config?.id)) {
|
688
|
+
viewer.entities.remove(viewer.entities.getById(config?.id)!);
|
689
|
+
}
|
690
|
+
|
691
|
+
const polygon = viewer.entities.add({
|
692
|
+
id: config?.id,
|
693
|
+
polygon: {
|
694
|
+
hierarchy: positions,
|
695
|
+
perPositionHeight: !config?.clamp,
|
696
|
+
heightReference: config?.clamp
|
697
|
+
? HeightReference.RELATIVE_TO_GROUND
|
698
|
+
: HeightReference.NONE,
|
699
|
+
outline: false,
|
700
|
+
fill: true,
|
701
|
+
outlineWidth: 15,
|
702
|
+
outlineColor: config?.strokeColor
|
703
|
+
? Color.fromCssColorString(config.strokeColor)
|
704
|
+
: Color.BLACK,
|
705
|
+
material: config?.fillColor
|
706
|
+
? Color.fromCssColorString(config.fillColor).withAlpha(
|
707
|
+
config.opacity ? config.opacity : 0.5
|
708
|
+
)
|
709
|
+
: Color.fromCssColorString("#FFC72C").withAlpha(
|
710
|
+
config?.opacity ? config.opacity : 0.5
|
711
|
+
),
|
712
|
+
},
|
713
|
+
});
|
714
|
+
|
715
|
+
(polygon as any).config = config;
|
716
|
+
|
717
|
+
return polygon;
|
718
|
+
};
|
719
|
+
|
720
|
+
/**
|
721
|
+
* this function will add a label on map and return label entity
|
722
|
+
* @param viewer - Cesium viewer object
|
723
|
+
* @param config - LabelConfigByCartesian
|
724
|
+
* @returns - Cesium label entity
|
725
|
+
*/
|
726
|
+
export const addLabel = (
|
727
|
+
viewer: Viewer,
|
728
|
+
config: LabelConfigByCartesian
|
729
|
+
): Entity => {
|
730
|
+
if (config.id && viewer.entities.getById(config.id)) {
|
731
|
+
viewer.entities.remove(viewer.entities.getById(config.id)!);
|
732
|
+
}
|
733
|
+
const label = viewer.entities.add({
|
734
|
+
id: config.id,
|
735
|
+
position: config.position,
|
736
|
+
billboard: {
|
737
|
+
sizeInMeters: true,
|
738
|
+
},
|
739
|
+
label: {
|
740
|
+
show: true,
|
741
|
+
text: config.text,
|
742
|
+
font: `${config.size ? config.size : 12}px Roboto Condensed`,
|
743
|
+
fillColor: config.fillColor
|
744
|
+
? Color.fromCssColorString(config.fillColor)
|
745
|
+
: Color.WHITE,
|
746
|
+
showBackground: config.isBackground !== false,
|
747
|
+
backgroundColor: config.backgroundColor
|
748
|
+
? Color.fromCssColorString(config.backgroundColor).withAlpha(
|
749
|
+
config.opacity ? config.opacity : 0.5
|
750
|
+
)
|
751
|
+
: Color.BLACK,
|
752
|
+
backgroundPadding: new Cartesian2(7, 7),
|
753
|
+
horizontalOrigin: HorizontalOrigin.CENTER,
|
754
|
+
verticalOrigin: VerticalOrigin.BOTTOM,
|
755
|
+
outlineWidth: 10,
|
756
|
+
outlineColor: Color.BLACK,
|
757
|
+
style: LabelStyle.FILL,
|
758
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
759
|
+
},
|
760
|
+
});
|
761
|
+
return label;
|
762
|
+
};
|
763
|
+
|
764
|
+
/**
|
765
|
+
* This function allows user to get direction from one point to another point
|
766
|
+
* @param start - Start cartesian position
|
767
|
+
* @param end - End Cartesian position
|
768
|
+
* @returns - return cartesian of direction
|
769
|
+
*/
|
770
|
+
export function getDirBetweenTwoCartesians(
|
771
|
+
start: Cartesian3,
|
772
|
+
end: Cartesian3
|
773
|
+
): Cartesian3 | undefined {
|
774
|
+
const res = Cartesian3.subtract(end, start, new Cartesian3());
|
775
|
+
Cartesian3.normalize(res, res);
|
776
|
+
return res;
|
777
|
+
}
|
778
|
+
|
779
|
+
/**
|
780
|
+
* This Function allows user to get position after every half meter
|
781
|
+
* @param start - First cartesian
|
782
|
+
* @param end - Second Cartesian
|
783
|
+
* @returns - Array of cartesian after every 0.5 meter
|
784
|
+
*/
|
785
|
+
export const getPositionsByFixDistance = (
|
786
|
+
start: Cartesian3,
|
787
|
+
end: Cartesian3
|
788
|
+
): Array<Cartesian3> => {
|
789
|
+
const dir = getDirBetweenTwoCartesians(start, end)!;
|
790
|
+
const dist = Cartesian3.distance(start, end);
|
791
|
+
const interval = dist / 200;
|
792
|
+
const result: any = [];
|
793
|
+
|
794
|
+
for (let i = 0; dist - i >= interval; i += interval) {
|
795
|
+
const res = new Cartesian3();
|
796
|
+
Cartesian3.multiplyByScalar(dir, i, res);
|
797
|
+
Cartesian3.add(start, res, res);
|
798
|
+
result.push(res);
|
799
|
+
}
|
800
|
+
result.push(end);
|
801
|
+
return result;
|
802
|
+
};
|