easy-three-utils 0.0.331 → 0.0.332

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,753 @@
1
+ import * as Cesium from 'cesium'
2
+ import * as turf from "@turf/turf";
3
+
4
+ class MeasureDistance {
5
+ constructor(viewer) {
6
+ this.viewer = viewer;
7
+ this.initEvents();
8
+ this.positions = [];
9
+ this.tempPositions = [];
10
+ this.vertexEntities = [];
11
+ this.labelEntity = undefined;
12
+ this.measureDistance = 0;
13
+ }
14
+
15
+ initEvents() {
16
+ this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
17
+ this.MeasureStartEvent = new Cesium.Event();
18
+ this.MeasureEndEvent = new Cesium.Event();
19
+ }
20
+
21
+ activate() {
22
+ this.deactivate();
23
+ this.registerEvents();
24
+ this.viewer.enableCursorStyle = false;
25
+ this.viewer._element.style.cursor = 'default';
26
+ this.isMeasure = true;
27
+ this.measureDistance = 0;
28
+ }
29
+
30
+ deactivate() {
31
+ if (!this.isMeasure) return;
32
+ this.unRegisterEvents();
33
+ this.viewer._element.style.cursor = 'pointer';
34
+ this.viewer.enableCursorStyle = true;
35
+ this.isMeasure = false;
36
+ this.tempPositions = [];
37
+ this.positions = [];
38
+ }
39
+
40
+ clear() {
41
+ this.viewer.entities.remove(this.lineEntity);
42
+ this.lineEntity = undefined;
43
+
44
+ this.vertexEntities.forEach(item => {
45
+ this.viewer.entities.remove(item);
46
+ });
47
+ this.vertexEntities = [];
48
+ }
49
+
50
+ createLineEntity() {
51
+ this.lineEntity = this.viewer.entities.add({
52
+ polyline: {
53
+ positions: new Cesium.CallbackProperty(e => {
54
+ return this.tempPositions;
55
+ }, false),
56
+ width: 2,
57
+ material: Cesium.Color.YELLOW,
58
+ depthFailMaterial: Cesium.Color.YELLOW
59
+ }
60
+ })
61
+ }
62
+
63
+ createVertex() {
64
+ let vertexEntity = this.viewer.entities.add({
65
+ position: this.positions[this.positions.length - 1],
66
+ id: "MeasureDistanceVertex" + this.positions[this.positions.length - 1],
67
+ type: "MeasureDistanceVertex",
68
+ label: {
69
+ text: spaceDistance(this.positions) + "米",
70
+ scale: 0.5,
71
+ font: 'normal 24px MicroSoft YaHei',
72
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
73
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
74
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
75
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
76
+ pixelOffset: new Cesium.Cartesian2(0, -30),
77
+ outlineWidth: 9,
78
+ outlineColor: Cesium.Color.WHITE
79
+ },
80
+ point: {
81
+ color: Cesium.Color.FUCHSIA,
82
+ pixelSize: 8,
83
+ disableDepthTestDistance: 500,
84
+ },
85
+ });
86
+ this.vertexEntities.push(vertexEntity);
87
+ }
88
+
89
+ createStartEntity() {
90
+ let vertexEntity = this.viewer.entities.add({
91
+ position: this.positions[0],
92
+ type: "MeasureDistanceVertex",
93
+ billboard: {
94
+ scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, 0.4),
95
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000),
96
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM
97
+ },
98
+ point: {
99
+ color: Cesium.Color.FUCHSIA,
100
+ pixelSize: 6,
101
+ },
102
+ });
103
+ this.vertexEntities.push(vertexEntity);
104
+ }
105
+
106
+ createEndEntity() {
107
+ let lastLabel = this.viewer.entities.getById("MeasureDistanceVertex" + this.positions[this.positions.length - 1]);
108
+ this.viewer.entities.remove(lastLabel);
109
+ this.viewer.entities.remove(this.moveVertexEntity);
110
+
111
+ let vertexEntity = this.viewer.entities.add({
112
+ position: this.positions[this.positions.length - 1],
113
+ type: "MeasureDistanceVertex",
114
+ label: {
115
+ text: "总距离:" + spaceDistance(this.positions) + "米",
116
+ scale: 0.5,
117
+ font: 'normal 26px MicroSoft YaHei',
118
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
119
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
120
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
121
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
122
+ pixelOffset: new Cesium.Cartesian2(0, -50),
123
+ outlineWidth: 9,
124
+ outlineColor: Cesium.Color.WHITE,
125
+ eyeOffset: new Cesium.Cartesian3(0, 0, -10)
126
+ },
127
+ billboard: {
128
+ image: "../../static/images/end.png",
129
+ scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, 0.4),
130
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 10000),
131
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM
132
+ },
133
+ point: {
134
+ color: Cesium.Color.FUCHSIA,
135
+ pixelSize: 6,
136
+ },
137
+ });
138
+ this.vertexEntities.push(vertexEntity);
139
+ }
140
+
141
+ registerEvents() {
142
+ this.leftClickEvent();
143
+ this.rightClickEvent();
144
+ this.mouseMoveEvent();
145
+ }
146
+
147
+ leftClickEvent() {
148
+ this.handler.setInputAction(e => {
149
+ this.viewer._element.style.cursor = 'default';
150
+ let position = this.viewer.scene.pickPosition(e.position);
151
+ if (!position) {
152
+ const ellipsoid = this.viewer.scene.globe.ellipsoid;
153
+ position = this.viewer.scene.camera.pickEllipsoid(e.position, ellipsoid);
154
+ }
155
+ if (!position) return;
156
+ this.positions.push(position);
157
+ if (this.positions.length == 1) {
158
+ this.createLineEntity();
159
+ this.createStartEntity();
160
+ return;
161
+ }
162
+ this.createVertex();
163
+
164
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
165
+ }
166
+
167
+ mouseMoveEvent() {
168
+ this.handler.setInputAction(e => {
169
+ if (!this.isMeasure) return;
170
+ this.viewer._element.style.cursor = 'default';
171
+ let position = this.viewer.scene.pickPosition(e.endPosition);
172
+ if (!position) {
173
+ position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid);
174
+ }
175
+ if (!position) return;
176
+ this.handleMoveEvent(position);
177
+ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
178
+ }
179
+
180
+ handleMoveEvent(position) {
181
+ if (this.positions.length < 1) return;
182
+ this.tempPositions = this.positions.concat(position);
183
+ }
184
+
185
+ rightClickEvent() {
186
+ this.handler.setInputAction(e => {
187
+ if (!this.isMeasure || this.positions.length < 1) {
188
+ this.deactivate();
189
+ this.clear();
190
+ } else {
191
+ this.createEndEntity();
192
+ this.lineEntity.polyline = {
193
+ positions: this.positions,
194
+ width: 2,
195
+ material: Cesium.Color.YELLOW,
196
+ depthFailMaterial: Cesium.Color.YELLOW
197
+ };
198
+ this.measureEnd();
199
+ }
200
+
201
+ }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
202
+ }
203
+
204
+ measureEnd() {
205
+ this.deactivate();
206
+ this.MeasureEndEvent.raiseEvent(this.measureDistance);
207
+ }
208
+
209
+ unRegisterEvents() {
210
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
211
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
212
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
213
+ }
214
+ }
215
+
216
+ class MeasureHeight {
217
+ constructor(viewer) {
218
+ this.viewer = viewer;
219
+ this.initEvents();
220
+ this.positions = [];
221
+ this.vertexEntities = [];
222
+ this.labelEntity = undefined;
223
+ this.measureHeight = 0;
224
+ }
225
+
226
+ initEvents() {
227
+ this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
228
+ this.MeasureStartEvent = new Cesium.Event();
229
+ this.MeasureEndEvent = new Cesium.Event();
230
+ }
231
+
232
+ activate() {
233
+ this.deactivate();
234
+ this.registerEvents();
235
+ this.viewer.enableCursorStyle = false;
236
+ this.viewer._element.style.cursor = 'default';
237
+ this.isMeasure = true;
238
+ this.circleRadius = 0.1;
239
+ this.measureHeight = 0;
240
+ this.positions = [];
241
+ }
242
+
243
+ deactivate() {
244
+ if (!this.isMeasure) return;
245
+ this.unRegisterEvents();
246
+ this.viewer._element.style.cursor = 'pointer';
247
+ this.viewer.enableCursorStyle = true;
248
+ this.isMeasure = false;
249
+ }
250
+
251
+ clear() {
252
+ this.viewer.entities.remove(this.lineEntity);
253
+ this.lineEntity = undefined;
254
+
255
+ this.viewer.entities.remove(this.labelEntity);
256
+ this.labelEntity = undefined;
257
+
258
+ this.removeCircleEntity();
259
+
260
+ this.vertexEntities.forEach(item => {
261
+ this.viewer.entities.remove(item);
262
+ });
263
+ this.vertexEntities = [];
264
+ }
265
+
266
+ createLineEntity() {
267
+ this.lineEntity = this.viewer.entities.add({
268
+ polyline: {
269
+ positions: new Cesium.CallbackProperty(e => {
270
+ return this.positions;
271
+ }, false),
272
+ width: 3,
273
+ material: Cesium.Color.fromCssColorString("rgb(249, 157, 11)")
274
+ }
275
+ })
276
+ }
277
+
278
+ createVertex(index) {
279
+ const vertexEntity = this.viewer.entities.add({
280
+ position: new Cesium.CallbackProperty(e => {
281
+ return this.positions[index];
282
+ }, false),
283
+ type: "MeasureHeightVertex",
284
+ point: {
285
+ color: Cesium.Color.fromCssColorString("rgb(249, 157, 11)"),
286
+ outlineColor: Cesium.Color.WHITE,
287
+ outlineWidth: 2,
288
+ pixelSize: 10
289
+ }
290
+ });
291
+ this.vertexEntities.push(vertexEntity);
292
+ }
293
+
294
+ createLabel() {
295
+ this.labelEntity = this.viewer.entities.add({
296
+ position: new Cesium.CallbackProperty(e => {
297
+ return this.positions[1];
298
+ }, false),
299
+ label: {
300
+ text: "",
301
+ scale: 0.5,
302
+ font: 'normal 40px MicroSoft YaHei',
303
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
304
+ scaleByDistance: new Cesium.NearFarScalar(500, 1, 1500, 0.4),
305
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
306
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
307
+ pixelOffset: new Cesium.Cartesian2(0, -30),
308
+ outlineWidth: 9,
309
+ outlineColor: Cesium.Color.WHITE
310
+ }
311
+ })
312
+ }
313
+
314
+ createCircleEntitiy() {
315
+ this.circleEntity = this.viewer.entities.add({
316
+ position: new Cesium.CallbackProperty(e => {
317
+ return this.positions[this.positions.length - 1];
318
+ }, false),
319
+ ellipse: {
320
+ height: new Cesium.CallbackProperty(e => {
321
+ return this.getPositionHeight(this.positions[this.positions.length - 1]);
322
+ }, false),
323
+ semiMinorAxis: new Cesium.CallbackProperty(e => {
324
+ return this.circleRadius;
325
+ }, false),
326
+ semiMajorAxis: new Cesium.CallbackProperty(e => {
327
+ return this.circleRadius;
328
+ }, false),
329
+ material: Cesium.Color.YELLOW.withAlpha(0.5)
330
+ },
331
+ });
332
+ }
333
+
334
+ getPositionHeight(position) {
335
+ const cartographic = Cesium.Cartographic.fromCartesian(position);
336
+ return cartographic.height;
337
+ }
338
+
339
+ removeCircleEntity() {
340
+ this.viewer.entities.remove(this.circleEntity);
341
+ this.circleEntity = undefined;
342
+ }
343
+
344
+ registerEvents() {
345
+ this.leftClickEvent();
346
+ this.rightClickEvent();
347
+ this.mouseMoveEvent();
348
+ }
349
+
350
+ leftClickEvent() {
351
+ this.handler.setInputAction(e => {
352
+ this.viewer._element.style.cursor = 'default';
353
+ let position = this.viewer.scene.pickPosition(e.position);
354
+ if (!position) {
355
+ const ellipsoid = this.viewer.scene.globe.ellipsoid;
356
+ position = this.viewer.scene.camera.pickEllipsoid(e.position, ellipsoid);
357
+ }
358
+ if (!position) return;
359
+
360
+ if (this.positions.length == 0) {
361
+ this.positions.push(position);
362
+ this.createVertex(0);
363
+ this.createLineEntity();
364
+ this.createCircleEntitiy();
365
+ this.createLabel();
366
+ } else {
367
+ this.measureEnd();
368
+ this.removeCircleEntity()
369
+ }
370
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
371
+ }
372
+
373
+ mouseMoveEvent() {
374
+ this.handler.setInputAction(e => {
375
+ if (!this.isMeasure) return;
376
+ this.viewer._element.style.cursor = 'default';
377
+ let position = this.viewer.scene.pickPosition(e.endPosition);
378
+ if (!position) {
379
+ position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid);
380
+ }
381
+ if (!position) return;
382
+ this.handleMoveEvent(position);
383
+ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
384
+ }
385
+
386
+ cartesian3Point3(pos) {
387
+ const ellipsoid = this.viewer.scene.globe.ellipsoid;
388
+ const cartographic = ellipsoid.cartesianToCartographic(pos);
389
+ const lng = Cesium.Math.toDegrees(cartographic.longitude);
390
+ const lat = Cesium.Math.toDegrees(cartographic.latitude);
391
+ const alt = cartographic.height;
392
+
393
+ return [lng, lat, alt]
394
+ }
395
+
396
+ getDistanceH(p1, p2) {
397
+ if (!p1 || !p2) return 2;
398
+ let distance = Cesium.Cartesian3.distance(p1, p2);
399
+ let p2Car = this.cartesian3Point3(p2);
400
+ let radius = Math.sqrt(Math.abs(Math.pow(distance, 2) - Math.pow(p2Car[2], 2)));
401
+ return radius;
402
+ }
403
+
404
+ handleMoveEvent(position) {
405
+ if (this.positions.length < 1) return;
406
+ let firstPoint = this.cartesian3Point3(this.positions[0])
407
+ let movePoint = this.cartesian3Point3(position)
408
+ const h = movePoint[2] - firstPoint[2];
409
+ firstPoint[2] = movePoint[2];
410
+ const twoPosition = Cesium.Cartesian3.fromDegrees(firstPoint[0], firstPoint[1], movePoint[2]);
411
+ if (this.positions.length < 2) {
412
+ this.positions.push(twoPosition, position);
413
+ this.createVertex(1);
414
+ this.createVertex(2);
415
+ } else {
416
+ this.positions[1] = twoPosition;
417
+ this.positions[2] = position;
418
+ this.measureHeight = h.toFixed(3);
419
+ this.labelEntity.label.text = "高度:" + this.measureHeight + " 米"
420
+ }
421
+
422
+ this.circleRadius = 20
423
+ }
424
+
425
+ rightClickEvent() {
426
+ this.handler.setInputAction(e => {
427
+ if (this.isMeasure) {
428
+ this.deactivate();
429
+ this.clear();
430
+ }
431
+ }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
432
+ }
433
+
434
+ measureEnd() {
435
+ this.deactivate();
436
+ this.MeasureEndEvent.raiseEvent(this.measureHeight);
437
+ }
438
+
439
+ unRegisterEvents() {
440
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
441
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
442
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
443
+ }
444
+ }
445
+
446
+ class MeasureArea {
447
+ constructor(viewer) {
448
+ this.viewer = viewer;
449
+ this.initEvents();
450
+ this.positions = [];
451
+ this.tempPositions = [];
452
+ this.vertexEntities = [];
453
+ this.labelEntity = undefined;
454
+ this.measureArea = 0;
455
+ }
456
+
457
+ initEvents() {
458
+ this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
459
+ this.MeasureStartEvent = new Cesium.Event();
460
+ this.MeasureEndEvent = new Cesium.Event();
461
+ }
462
+
463
+ activate() {
464
+ this.deactivate();
465
+ this.registerEvents();
466
+ this.viewer.enableCursorStyle = false;
467
+ this.viewer._element.style.cursor = 'default';
468
+ this.isMeasure = true;
469
+ this.measureArea = 0;
470
+ }
471
+
472
+ deactivate() {
473
+ if (!this.isMeasure) return;
474
+ this.unRegisterEvents();
475
+ this.viewer._element.style.cursor = 'pointer';
476
+ this.viewer.enableCursorStyle = true;
477
+ this.isMeasure = false;
478
+ this.tempPositions = [];
479
+ this.positions = [];
480
+ this.height = undefined;
481
+ }
482
+
483
+ clear() {
484
+ this.viewer.entities.remove(this.polygonEntity);
485
+ this.polygonEntity = undefined;
486
+
487
+ this.vertexEntities.forEach(item => {
488
+ this.viewer.entities.remove(item);
489
+ });
490
+ this.vertexEntities = [];
491
+
492
+ this.viewer.entities.remove(this.mesureResultEntity);
493
+ this.mesureResultEntity = undefined;
494
+
495
+ this.height = undefined;
496
+ }
497
+
498
+ createPolygonEntity() {
499
+ this.polygonEntity = this.viewer.entities.add({
500
+ polygon: {
501
+ hierarchy: new Cesium.CallbackProperty(e => {
502
+ return new Cesium.PolygonHierarchy(this.tempPositions);
503
+ }, false),
504
+ material: Cesium.Color.fromCssColorString("rgb(249, 157, 11,.6)")
505
+ },
506
+ polyline: {
507
+ clampToGround: true,
508
+ positions: new Cesium.CallbackProperty(e => {
509
+ return this.tempPositions.concat(this.tempPositions[0]);
510
+ }, false),
511
+ width: 1,
512
+ material: new Cesium.PolylineOutlineMaterialProperty({
513
+ outlineWidth: 2,
514
+ outlineColor: Cesium.Color.WHITE,
515
+ })
516
+ }
517
+ })
518
+ }
519
+
520
+ createVertex() {
521
+ const vertexEntity = this.viewer.entities.add({
522
+ position: this.positions[this.positions.length - 1],
523
+ type: "MeasureAreaVertex",
524
+ point: {
525
+ color: Cesium.Color.fromCssColorString("rgb(249, 157, 11)"),
526
+ outlineColor: Cesium.Color.WHITE,
527
+ outlineWidth: 2,
528
+ pixelSize: 10,
529
+ heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
530
+ }
531
+ });
532
+ this.vertexEntities.push(vertexEntity);
533
+ }
534
+
535
+ createResultLabel() {
536
+ this.mesureResultEntity = this.viewer.entities.add({
537
+ position: new Cesium.CallbackProperty(e => {
538
+ return this.getCenterPosition()
539
+ }, false),
540
+ type: "MeasureAreaResult",
541
+ label: {
542
+ text: new Cesium.CallbackProperty(e => {
543
+ return "面积" + this.computeArea(this.tempPositions);
544
+ }, false),
545
+ scale: 0.5,
546
+ font: 'normal 28px MicroSoft YaHei',
547
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
548
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 0.4),
549
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
550
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
551
+ pixelOffset: new Cesium.Cartesian2(0, -30),
552
+ outlineWidth: 9,
553
+ outlineColor: Cesium.Color.WHITE
554
+ }
555
+ });
556
+ }
557
+
558
+ getCenterPosition() {
559
+ let points = [];
560
+ if (this.tempPositions.length < 3) return this.tempPositions[0];
561
+ this.tempPositions.forEach(position => {
562
+ const point3d = this.cartesian3ToPoint3D(position);
563
+ points.push([point3d.x, point3d.y]);
564
+ })
565
+ let geo = turf.lineString(points);
566
+ let bbox = turf.bbox(geo);
567
+ let bboxPolygon = turf.bboxPolygon(bbox);
568
+ let pointOnFeature = turf.center(bboxPolygon);
569
+ let lonLat = pointOnFeature.geometry.coordinates;
570
+
571
+ return Cesium.Cartesian3.fromDegrees(lonLat[0], lonLat[1], this.height + 0.3);
572
+ }
573
+
574
+ registerEvents() {
575
+ this.leftClickEvent();
576
+ this.rightClickEvent();
577
+ this.mouseMoveEvent();
578
+ }
579
+
580
+ leftClickEvent() {
581
+ this.handler.setInputAction(e => {
582
+ this.viewer._element.style.cursor = 'default';
583
+ let position = this.viewer.scene.pickPosition(e.position);
584
+ if (!position) {
585
+ const ellipsoid = this.viewer.scene.globe.ellipsoid;
586
+ position = this.viewer.scene.camera.pickEllipsoid(e.position, ellipsoid);
587
+ }
588
+ if (!position) return;
589
+ this.positions.push(position);
590
+ this.height = this.unifiedHeight(this.positions, this.height);
591
+ if (this.positions.length == 1) {
592
+ this.createPolygonEntity();
593
+ }
594
+ this.createVertex();
595
+
596
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
597
+ }
598
+
599
+ mouseMoveEvent() {
600
+ this.handler.setInputAction(e => {
601
+ if (!this.isMeasure) return;
602
+ this.viewer._element.style.cursor = 'default';
603
+ let position = this.viewer.scene.pickPosition(e.endPosition);
604
+ if (!position) {
605
+ position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid);
606
+ }
607
+ if (!position) return;
608
+ this.handleMoveEvent(position);
609
+ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
610
+ }
611
+
612
+ handleMoveEvent(position) {
613
+ if (this.positions.length < 1) return;
614
+
615
+ this.height = this.unifiedHeight(this.positions, this.height);
616
+ this.tempPositions = this.positions.concat(position);
617
+ if (this.tempPositions.length >= 3 && !this.mesureResultEntity) {
618
+ this.createResultLabel();
619
+ }
620
+ }
621
+
622
+ unifiedHeight(positions, height) {
623
+ if (!height) height = this.getPositionHeight(positions[0]);
624
+ let point3d;
625
+ for (let i = 0; i < positions.length; i++) {
626
+ const element = positions[i];
627
+ point3d = this.cartesian3ToPoint3D(element);
628
+ positions[i] = Cesium.Cartesian3.fromDegrees(point3d.x, point3d.y, height)
629
+ }
630
+
631
+ return height;
632
+ }
633
+
634
+ getPositionHeight(position) {
635
+ const cartographic = Cesium.Cartographic.fromCartesian(position);
636
+ return cartographic.height;
637
+ }
638
+
639
+ cartesian3ToPoint3D(position) {
640
+ const cartographic = Cesium.Cartographic.fromCartesian(position);
641
+ const lon = Cesium.Math.toDegrees(cartographic.longitude);
642
+ const lat = Cesium.Math.toDegrees(cartographic.latitude);
643
+ return { x: lon, y: lat, z: cartographic.height };
644
+ }
645
+
646
+ Bearing(from, to) {
647
+ from = Cesium.Cartographic.fromCartesian(from);
648
+ to = Cesium.Cartographic.fromCartesian(to);
649
+
650
+ const lat1 = from.latitude;
651
+ const lon1 = from.longitude;
652
+ const lat2 = to.latitude;
653
+ const lon2 = to.longitude;
654
+ let angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
655
+ if (angle < 0) {
656
+ angle += Math.PI * 2.0;
657
+ }
658
+ const degreesPerRadian = 180.0 / Math.PI;
659
+
660
+ angle = angle * degreesPerRadian;
661
+ return angle;
662
+ }
663
+
664
+ Angle(p1, p2, p3) {
665
+ const bearing21 = this.Bearing(p2, p1);
666
+ const bearing23 = this.Bearing(p2, p3);
667
+ let angle = bearing21 - bearing23;
668
+ if (angle < 0) {
669
+ angle += 360;
670
+ }
671
+ return angle;
672
+ }
673
+
674
+ distance(point1, point2) {
675
+ const point1cartographic = Cesium.Cartographic.fromCartesian(point1);
676
+ const point2cartographic = Cesium.Cartographic.fromCartesian(point2);
677
+ const geodesic = new Cesium.EllipsoidGeodesic();
678
+ geodesic.setEndPoints(point1cartographic, point2cartographic);
679
+ let s = geodesic.surfaceDistance;
680
+ s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
681
+ return s;
682
+ }
683
+
684
+ computeArea(points) {
685
+ let res = 0;
686
+
687
+ for (let i = 0; i < points.length - 2; i++) {
688
+ const j = (i + 1) % points.length;
689
+ const k = (i + 2) % points.length;
690
+ const totalAngle = this.Angle(points[i], points[j], points[k]);
691
+
692
+ const dis_temp1 = this.distance(points[j], points[0]);
693
+ const dis_temp2 = this.distance(points[k], points[0]);
694
+
695
+ res += dis_temp1 * dis_temp2 * Math.sin(totalAngle) / 2;
696
+ }
697
+
698
+ if (res < 1000000) {
699
+ res = Math.abs(res).toFixed(4) + " 平方米";
700
+ } else {
701
+ res = Math.abs((res / 1000000.0).toFixed(4)) + " 平方公里";
702
+ }
703
+
704
+ return res;
705
+ }
706
+
707
+ rightClickEvent() {
708
+ this.handler.setInputAction(e => {
709
+ if (!this.isMeasure || this.positions.length < 3) {
710
+ this.deactivate();
711
+ this.clear();
712
+ } else {
713
+ this.tempPositions = [...this.positions];
714
+
715
+ this.polygonEntity.polyline = {
716
+ clampToGround: true,
717
+ positions: new Cesium.CallbackProperty(e => {
718
+ return this.tempPositions.concat(this.tempPositions[0]);
719
+ }, false),
720
+ width: 1,
721
+ material: new Cesium.PolylineOutlineMaterialProperty({
722
+ color: Cesium.Color.ORANGE,
723
+ outlineWidth: 2,
724
+ outlineColor: Cesium.Color.WHITE
725
+ })
726
+ }
727
+
728
+ this.polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(this.tempPositions);
729
+ this.mesureResultEntity.position = this.getCenterPosition();
730
+ this.mesureResultEntity.label.text = "总面积为" + this.computeArea(this.positions)
731
+ this.measureEnd();
732
+ }
733
+
734
+ }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
735
+ }
736
+
737
+ measureEnd() {
738
+ this.deactivate();
739
+ this.MeasureEndEvent.raiseEvent(this.measureArea);
740
+ }
741
+
742
+ unRegisterEvents() {
743
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
744
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
745
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
746
+ }
747
+ }
748
+
749
+ export {
750
+ MeasureDistance,
751
+ MeasureHeight,
752
+ MeasureArea
753
+ }