easy-three-utils 0.0.345 → 0.0.347
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/cesium/index.ts
CHANGED
|
@@ -82,11 +82,15 @@ const useCesium = () => {
|
|
|
82
82
|
const customCollection = hooks.useCustomCollection(viewer)
|
|
83
83
|
const drawPolygon = hooks.useDrawPolygon(viewer, {
|
|
84
84
|
nodeCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.POLYGON_NODE),
|
|
85
|
-
polygonCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.POLYGON)
|
|
85
|
+
polygonCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.POLYGON)
|
|
86
86
|
})
|
|
87
87
|
const clipping = hooks.useClipping(viewer)
|
|
88
88
|
const weather = hooks.useWeather(viewer)
|
|
89
|
-
const measure = hooks.useMeasure(viewer
|
|
89
|
+
const measure = hooks.useMeasure(viewer, {
|
|
90
|
+
distanceCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.MEASURE_DISTANCE),
|
|
91
|
+
heightCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.MEASURE_HEIGHT),
|
|
92
|
+
areaCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.MEASURE_AREA)
|
|
93
|
+
})
|
|
90
94
|
|
|
91
95
|
if (config.controllerStyle === cesiumConfigDict.EControllerStyle.THREE) {
|
|
92
96
|
updateController(viewer)
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import * as Cesium from 'cesium'
|
|
2
2
|
|
|
3
3
|
enum ECollectionWhiteListNames {
|
|
4
|
+
POLYGON_NODE = 'polygon_node',
|
|
4
5
|
POLYGON = 'polygon',
|
|
5
|
-
|
|
6
|
+
|
|
7
|
+
MEASURE_DISTANCE = 'measure_distance',
|
|
8
|
+
MEASURE_HEIGHT = 'measure_height',
|
|
9
|
+
MEASURE_AREA = 'measure_area'
|
|
6
10
|
}
|
|
7
11
|
|
|
8
12
|
const useCustomCollection = (viewer: Cesium.Viewer) => {
|
|
9
13
|
|
|
10
14
|
let collectionNames: string[] = ([])
|
|
11
|
-
let whiteList: string[] = ['polygon', 'polygon_node']
|
|
15
|
+
let whiteList: string[] = ['polygon', 'polygon_node', 'measure_distance', 'measure_height', 'measure_area']
|
|
12
16
|
|
|
13
17
|
const addCollection = (name: string) => {
|
|
14
18
|
const index = collectionNames.findIndex(item => item === name)
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import * as Cesium from 'cesium'
|
|
2
|
+
import * as turf from "@turf/turf"
|
|
2
3
|
|
|
3
|
-
const useMeasure = (viewer: Cesium.Viewer
|
|
4
|
+
const useMeasure = (viewer: Cesium.Viewer, options: {
|
|
5
|
+
distanceCollection: Cesium.CustomDataSource,
|
|
6
|
+
heightCollection: Cesium.CustomDataSource,
|
|
7
|
+
areaCollection: Cesium.CustomDataSource
|
|
8
|
+
}) => {
|
|
4
9
|
|
|
5
10
|
const angleMeasurement = () => {
|
|
6
11
|
let anglePoints = []
|
|
@@ -15,14 +20,14 @@ const useMeasure = (viewer: Cesium.Viewer) => {
|
|
|
15
20
|
angleMeasurementHandler = null
|
|
16
21
|
}
|
|
17
22
|
|
|
18
|
-
angleMeasurementHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
23
|
+
angleMeasurementHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
19
24
|
|
|
20
25
|
angleMeasurementHandler.setInputAction((movement) => {
|
|
21
|
-
const ray = viewer.camera.getPickRay(movement.position)
|
|
22
|
-
const cartesian = viewer.scene.globe.pick(ray, viewer.scene)
|
|
26
|
+
const ray = viewer.camera.getPickRay(movement.position)
|
|
27
|
+
const cartesian = viewer.scene.globe.pick(ray, viewer.scene)
|
|
23
28
|
|
|
24
29
|
if (cartesian) {
|
|
25
|
-
anglePoints.push(cartesian)
|
|
30
|
+
anglePoints.push(cartesian)
|
|
26
31
|
|
|
27
32
|
const pointEntity = viewer.entities.add({
|
|
28
33
|
position: cartesian,
|
|
@@ -33,7 +38,7 @@ const useMeasure = (viewer: Cesium.Viewer) => {
|
|
|
33
38
|
pixelSize: 10,
|
|
34
39
|
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
35
40
|
}
|
|
36
|
-
})
|
|
41
|
+
})
|
|
37
42
|
angleEntities.push(pointEntity)
|
|
38
43
|
|
|
39
44
|
if (anglePoints.length >= 2) {
|
|
@@ -44,7 +49,7 @@ const useMeasure = (viewer: Cesium.Viewer) => {
|
|
|
44
49
|
material: Cesium.Color.fromCssColorString("rgb(249, 157, 11)"),
|
|
45
50
|
clampToGround: true,
|
|
46
51
|
}
|
|
47
|
-
})
|
|
52
|
+
})
|
|
48
53
|
angleLines.push(lineEntity)
|
|
49
54
|
}
|
|
50
55
|
|
|
@@ -56,7 +61,7 @@ const useMeasure = (viewer: Cesium.Viewer) => {
|
|
|
56
61
|
}
|
|
57
62
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
58
63
|
|
|
59
|
-
angleMeasurementHandler.setInputAction(
|
|
64
|
+
angleMeasurementHandler.setInputAction((movement) => {
|
|
60
65
|
if (anglePoints.length > 0 && anglePoints.length < 3) {
|
|
61
66
|
const ray = viewer.camera.getPickRay(movement.endPosition)
|
|
62
67
|
const cartesian = viewer.scene.globe.pick(ray, viewer.scene)
|
|
@@ -70,7 +75,7 @@ const useMeasure = (viewer: Cesium.Viewer) => {
|
|
|
70
75
|
material: Cesium.Color.fromCssColorString("rgb(249, 157, 11)"),
|
|
71
76
|
clampToGround: true
|
|
72
77
|
}
|
|
73
|
-
})
|
|
78
|
+
})
|
|
74
79
|
angleLines.push(lineEntity)
|
|
75
80
|
} else {
|
|
76
81
|
const line = angleLines[angleLines.length - 1]
|
|
@@ -78,7 +83,7 @@ const useMeasure = (viewer: Cesium.Viewer) => {
|
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
|
-
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
86
|
+
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
const calculateAndDisplayAngle = () => {
|
|
@@ -110,7 +115,7 @@ const useMeasure = (viewer: Cesium.Viewer) => {
|
|
|
110
115
|
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
|
111
116
|
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
112
117
|
}
|
|
113
|
-
})
|
|
118
|
+
})
|
|
114
119
|
angleLabels.push(angleLabel)
|
|
115
120
|
}
|
|
116
121
|
|
|
@@ -141,10 +146,607 @@ const useMeasure = (viewer: Cesium.Viewer) => {
|
|
|
141
146
|
}
|
|
142
147
|
}
|
|
143
148
|
|
|
149
|
+
const distanceMeasurement = () => {
|
|
150
|
+
let positions = []
|
|
151
|
+
let tempPositions = []
|
|
152
|
+
let currentLineEntity: Cesium.Entity
|
|
153
|
+
let handler = null
|
|
154
|
+
|
|
155
|
+
const point = {
|
|
156
|
+
color: Cesium.Color.fromCssColorString("rgb(249,157,11)"),
|
|
157
|
+
outlineColor: Cesium.Color.WHITE,
|
|
158
|
+
outlineWidth: 2,
|
|
159
|
+
pixelSize: 10,
|
|
160
|
+
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const draw = () => {
|
|
164
|
+
if (handler) {
|
|
165
|
+
console.log('请使用右键结束上次测量!')
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
169
|
+
leftClickEvent()
|
|
170
|
+
rightClickEvent()
|
|
171
|
+
mouseMoveEvent()
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const stopDraw = () => {
|
|
175
|
+
if (currentLineEntity) {
|
|
176
|
+
options.distanceCollection.entities.remove(currentLineEntity)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (handler) {
|
|
180
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
181
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
182
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
183
|
+
handler.destroy()
|
|
184
|
+
handler = null
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
positions = []
|
|
188
|
+
tempPositions = []
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const removeAll = () => {
|
|
192
|
+
stopDraw()
|
|
193
|
+
options.distanceCollection.entities.removeAll()
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const createLine = () => {
|
|
197
|
+
currentLineEntity = options.distanceCollection.entities.add({
|
|
198
|
+
polyline: {
|
|
199
|
+
positions: new Cesium.CallbackProperty(() => tempPositions, false),
|
|
200
|
+
material: Cesium.Color.fromCssColorString("rgb(249,157,11)"),
|
|
201
|
+
width: 2,
|
|
202
|
+
clampToGround: true
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const createPoint = () => {
|
|
208
|
+
const pos = positions[positions.length - 1]
|
|
209
|
+
const text = getSpaceDistance(positions) + " 米"
|
|
210
|
+
options.distanceCollection.entities.add({
|
|
211
|
+
position: pos,
|
|
212
|
+
label: {
|
|
213
|
+
text: positions.length === 1 ? '起始点' : text,
|
|
214
|
+
scale: 0.5,
|
|
215
|
+
font: "normal 28px MicroSoft YaHei",
|
|
216
|
+
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
217
|
+
pixelOffset: new Cesium.Cartesian2(0, -30),
|
|
218
|
+
outlineWidth: 9,
|
|
219
|
+
outlineColor: Cesium.Color.WHITE,
|
|
220
|
+
heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
|
|
221
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
222
|
+
},
|
|
223
|
+
point
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const getSpaceDistance = (positions) => {
|
|
228
|
+
if (positions.length < 2) return 0
|
|
229
|
+
let distance = 0
|
|
230
|
+
|
|
231
|
+
for (let i = 0; i < positions.length - 1; i++) {
|
|
232
|
+
const c1 = Cesium.Cartographic.fromCartesian(positions[i])
|
|
233
|
+
const c2 = Cesium.Cartographic.fromCartesian(positions[i + 1])
|
|
234
|
+
const geodesic = new Cesium.EllipsoidGeodesic(c1, c2)
|
|
235
|
+
let s = geodesic.surfaceDistance
|
|
236
|
+
s = Math.sqrt(Math.pow(s, 2) + Math.pow(c2.height - c1.height, 2))
|
|
237
|
+
distance += s
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return distance.toFixed(2)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const leftClickEvent = () => {
|
|
244
|
+
let lastClickTime = 0
|
|
245
|
+
const MIN_INTERVAL = 250
|
|
246
|
+
|
|
247
|
+
handler.setInputAction(event => {
|
|
248
|
+
const now = Date.now()
|
|
249
|
+
if (now - lastClickTime < MIN_INTERVAL) return
|
|
250
|
+
lastClickTime = now
|
|
251
|
+
|
|
252
|
+
let position = viewer.scene.pickPosition(event.position)
|
|
253
|
+
if (!position)
|
|
254
|
+
position = viewer.scene.camera.pickEllipsoid(event.position, viewer.scene.globe.ellipsoid)
|
|
255
|
+
if (!position) return
|
|
256
|
+
|
|
257
|
+
positions.push(position)
|
|
258
|
+
|
|
259
|
+
if (positions.length === 1) {
|
|
260
|
+
createPoint()
|
|
261
|
+
createLine()
|
|
262
|
+
} else {
|
|
263
|
+
createPoint()
|
|
264
|
+
}
|
|
265
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const mouseMoveEvent = () => {
|
|
269
|
+
handler.setInputAction(event => {
|
|
270
|
+
let position = viewer.scene.pickPosition(event.endPosition)
|
|
271
|
+
if (!position)
|
|
272
|
+
position = viewer.scene.camera.pickEllipsoid(event.endPosition, viewer.scene.globe.ellipsoid)
|
|
273
|
+
if (!position) return
|
|
274
|
+
handleMoveEvent(position)
|
|
275
|
+
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const handleMoveEvent = (position) => {
|
|
279
|
+
if (positions.length < 1) return
|
|
280
|
+
tempPositions = positions.concat(position)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const rightClickEvent = () => {
|
|
284
|
+
handler.setInputAction(() => {
|
|
285
|
+
if (positions.length <= 1) {
|
|
286
|
+
removeAll()
|
|
287
|
+
stopDraw()
|
|
288
|
+
} else {
|
|
289
|
+
options.distanceCollection.entities.add({
|
|
290
|
+
polyline: {
|
|
291
|
+
positions: positions,
|
|
292
|
+
material: Cesium.Color.fromCssColorString("rgb(249,157,11)"),
|
|
293
|
+
width: 2,
|
|
294
|
+
clampToGround: true
|
|
295
|
+
}
|
|
296
|
+
})
|
|
297
|
+
stopDraw()
|
|
298
|
+
}
|
|
299
|
+
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
draw,
|
|
304
|
+
removeAll
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const heightMeasurement = () => {
|
|
309
|
+
let positions = []
|
|
310
|
+
let currentLineEntity: Cesium.Entity
|
|
311
|
+
let currentPointEntities: Cesium.Entity[] = []
|
|
312
|
+
let currentLabelEntity: Cesium.Entity
|
|
313
|
+
let handler = null
|
|
314
|
+
|
|
315
|
+
const cartesian3Point3 = (pos) => {
|
|
316
|
+
const ellipsoid = viewer.scene.globe.ellipsoid
|
|
317
|
+
const cartographic = ellipsoid.cartesianToCartographic(pos)
|
|
318
|
+
return [
|
|
319
|
+
Cesium.Math.toDegrees(cartographic.longitude),
|
|
320
|
+
Cesium.Math.toDegrees(cartographic.latitude),
|
|
321
|
+
cartographic.height
|
|
322
|
+
]
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const draw = () => {
|
|
326
|
+
if (handler) {
|
|
327
|
+
console.log('请先结束上次测量!')
|
|
328
|
+
return
|
|
329
|
+
}
|
|
330
|
+
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
331
|
+
leftClickEvent()
|
|
332
|
+
mouseMoveEvent()
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const createLine = () => {
|
|
336
|
+
currentLineEntity = options.heightCollection.entities.add({
|
|
337
|
+
polyline: {
|
|
338
|
+
positions: new Cesium.CallbackProperty(() => positions, false),
|
|
339
|
+
width: 2,
|
|
340
|
+
material: Cesium.Color.fromCssColorString("rgb(249,157,11)")
|
|
341
|
+
}
|
|
342
|
+
})
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const createPoint = (index) => {
|
|
346
|
+
const entity = options.heightCollection.entities.add({
|
|
347
|
+
position: new Cesium.CallbackProperty(() => positions[index], false) as Cesium.CallbackPositionProperty,
|
|
348
|
+
point: {
|
|
349
|
+
color: Cesium.Color.fromCssColorString("rgb(249,157,11)"),
|
|
350
|
+
outlineColor: Cesium.Color.WHITE,
|
|
351
|
+
outlineWidth: 2,
|
|
352
|
+
pixelSize: 10
|
|
353
|
+
}
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
currentPointEntities.push(entity)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const createLabel = () => {
|
|
360
|
+
currentLabelEntity = options.heightCollection.entities.add({
|
|
361
|
+
position: new Cesium.CallbackProperty(() => positions[1], false) as Cesium.CallbackPositionProperty,
|
|
362
|
+
label: {
|
|
363
|
+
text: "",
|
|
364
|
+
scale: 0.5,
|
|
365
|
+
font: "normal 28px MicroSoft YaHei",
|
|
366
|
+
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
367
|
+
pixelOffset: new Cesium.Cartesian2(0, -30),
|
|
368
|
+
outlineWidth: 9,
|
|
369
|
+
outlineColor: Cesium.Color.WHITE
|
|
370
|
+
}
|
|
371
|
+
})
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const leftClickEvent = () => {
|
|
375
|
+
let lastClickTime = 0
|
|
376
|
+
const MIN_INTERVAL = 250
|
|
377
|
+
|
|
378
|
+
handler.setInputAction(e => {
|
|
379
|
+
const now = Date.now()
|
|
380
|
+
if (now - lastClickTime < MIN_INTERVAL) return
|
|
381
|
+
lastClickTime = now
|
|
382
|
+
|
|
383
|
+
let position = viewer.scene.pickPosition(e.position)
|
|
384
|
+
if (!position) position = viewer.scene.camera.pickEllipsoid(e.position, viewer.scene.globe.ellipsoid)
|
|
385
|
+
if (!position) return
|
|
386
|
+
|
|
387
|
+
if (positions.length === 0) {
|
|
388
|
+
positions.push(position)
|
|
389
|
+
createPoint(0)
|
|
390
|
+
createLine()
|
|
391
|
+
createLabel()
|
|
392
|
+
} else if (positions.length > 2) {
|
|
393
|
+
options.heightCollection.entities.add({
|
|
394
|
+
polyline: {
|
|
395
|
+
positions: positions,
|
|
396
|
+
width: 2,
|
|
397
|
+
material: Cesium.Color.fromCssColorString("rgb(249,157,11)")
|
|
398
|
+
}
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
positions.forEach(pos => {
|
|
402
|
+
options.heightCollection.entities.add({
|
|
403
|
+
position: pos,
|
|
404
|
+
point: {
|
|
405
|
+
color: Cesium.Color.fromCssColorString("rgb(249,157,11)"),
|
|
406
|
+
outlineColor: Cesium.Color.WHITE,
|
|
407
|
+
outlineWidth: 2,
|
|
408
|
+
pixelSize: 10
|
|
409
|
+
}
|
|
410
|
+
})
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
options.heightCollection.entities.add({
|
|
414
|
+
position: positions[1],
|
|
415
|
+
label: {
|
|
416
|
+
text: currentLabelEntity.label.text,
|
|
417
|
+
scale: 0.5,
|
|
418
|
+
font: "normal 28px MicroSoft YaHei",
|
|
419
|
+
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
420
|
+
pixelOffset: new Cesium.Cartesian2(0, -30),
|
|
421
|
+
outlineWidth: 9,
|
|
422
|
+
outlineColor: Cesium.Color.WHITE
|
|
423
|
+
}
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
stopDraw()
|
|
427
|
+
}
|
|
428
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const mouseMoveEvent = () => {
|
|
432
|
+
handler.setInputAction(e => {
|
|
433
|
+
let position = viewer.scene.pickPosition(e.endPosition)
|
|
434
|
+
if (!position) position = viewer.scene.camera.pickEllipsoid(e.startPosition, viewer.scene.globe.ellipsoid)
|
|
435
|
+
if (!position) return
|
|
436
|
+
|
|
437
|
+
handleMove(position)
|
|
438
|
+
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const handleMove = (position) => {
|
|
442
|
+
if (positions.length < 1) return
|
|
443
|
+
const first = cartesian3Point3(positions[0])
|
|
444
|
+
const move = cartesian3Point3(position)
|
|
445
|
+
|
|
446
|
+
const h = move[2] - first[2]
|
|
447
|
+
first[2] = move[2]
|
|
448
|
+
const twoPos = Cesium.Cartesian3.fromDegrees(first[0], first[1], move[2])
|
|
449
|
+
|
|
450
|
+
if (positions.length < 2) {
|
|
451
|
+
positions.push(twoPos, position)
|
|
452
|
+
createPoint(1)
|
|
453
|
+
createPoint(2)
|
|
454
|
+
} else {
|
|
455
|
+
positions[1] = twoPos
|
|
456
|
+
positions[2] = position
|
|
457
|
+
if (currentLabelEntity) {
|
|
458
|
+
(currentLabelEntity.label.text as any) = `高度:${h.toFixed(3)} 米`
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const stopDraw = () => {
|
|
464
|
+
if (handler) {
|
|
465
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
466
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
467
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
468
|
+
handler.destroy()
|
|
469
|
+
handler = null
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (currentLineEntity) {
|
|
473
|
+
options.heightCollection.entities.remove(currentLineEntity)
|
|
474
|
+
currentLineEntity = null
|
|
475
|
+
}
|
|
476
|
+
if (currentLabelEntity) {
|
|
477
|
+
options.heightCollection.entities.remove(currentLabelEntity)
|
|
478
|
+
currentLabelEntity = null
|
|
479
|
+
}
|
|
480
|
+
if (currentPointEntities.length) {
|
|
481
|
+
currentPointEntities.forEach(entity => options.heightCollection.entities.remove(entity))
|
|
482
|
+
currentPointEntities = []
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
positions = []
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
const removeAll = () => {
|
|
489
|
+
stopDraw()
|
|
490
|
+
options.heightCollection.entities.removeAll()
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return {
|
|
494
|
+
draw,
|
|
495
|
+
removeAll
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const areaMeasurement = () => {
|
|
500
|
+
let handler = null
|
|
501
|
+
let currentPolygonEntity = null
|
|
502
|
+
let currentLabelEntity = null
|
|
503
|
+
let positions = []
|
|
504
|
+
let tempPositions = []
|
|
505
|
+
let height = undefined
|
|
506
|
+
|
|
507
|
+
const draw = () => {
|
|
508
|
+
if (handler) {
|
|
509
|
+
console.log('请使用右键结束上次测量!')
|
|
510
|
+
return
|
|
511
|
+
}
|
|
512
|
+
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
513
|
+
leftClickEvent()
|
|
514
|
+
mouseMoveEvent()
|
|
515
|
+
rightClickEvent()
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const stopDraw = () => {
|
|
519
|
+
if (handler) {
|
|
520
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
521
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
522
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
523
|
+
handler.destroy()
|
|
524
|
+
handler = null
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
tempPositions = []
|
|
528
|
+
positions = []
|
|
529
|
+
currentPolygonEntity = null
|
|
530
|
+
currentLabelEntity = null
|
|
531
|
+
height = undefined
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
const removeAll = () => {
|
|
535
|
+
stopDraw()
|
|
536
|
+
options.areaCollection.entities.removeAll()
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const createPolygon = () => {
|
|
540
|
+
currentPolygonEntity = options.areaCollection.entities.add({
|
|
541
|
+
polygon: {
|
|
542
|
+
hierarchy: new Cesium.CallbackProperty(() => {
|
|
543
|
+
return new Cesium.PolygonHierarchy(tempPositions)
|
|
544
|
+
}, false),
|
|
545
|
+
material: Cesium.Color.fromCssColorString("rgb(249, 157, 11,.6)")
|
|
546
|
+
},
|
|
547
|
+
polyline: {
|
|
548
|
+
clampToGround: true,
|
|
549
|
+
positions: new Cesium.CallbackProperty(() => {
|
|
550
|
+
return tempPositions.concat(tempPositions[0])
|
|
551
|
+
}, false),
|
|
552
|
+
width: 1,
|
|
553
|
+
material: new Cesium.PolylineOutlineMaterialProperty({
|
|
554
|
+
outlineWidth: 2,
|
|
555
|
+
outlineColor: Cesium.Color.WHITE
|
|
556
|
+
})
|
|
557
|
+
}
|
|
558
|
+
})
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const createPoint = () => {
|
|
562
|
+
options.areaCollection.entities.add({
|
|
563
|
+
position: positions[positions.length - 1],
|
|
564
|
+
point: {
|
|
565
|
+
color: Cesium.Color.fromCssColorString("rgb(249, 157, 11)"),
|
|
566
|
+
outlineColor: Cesium.Color.WHITE,
|
|
567
|
+
outlineWidth: 2,
|
|
568
|
+
pixelSize: 10,
|
|
569
|
+
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
570
|
+
}
|
|
571
|
+
})
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const createLabel = () => {
|
|
575
|
+
currentLabelEntity = options.areaCollection.entities.add({
|
|
576
|
+
position: new Cesium.CallbackProperty(() => getCenterPosition(), false) as Cesium.CallbackPositionProperty,
|
|
577
|
+
label: {
|
|
578
|
+
text: new Cesium.CallbackProperty(() => {
|
|
579
|
+
return "面积 " + computeArea(tempPositions)
|
|
580
|
+
}, false),
|
|
581
|
+
scale: 0.5,
|
|
582
|
+
font: "normal 28px MicroSoft YaHei",
|
|
583
|
+
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
584
|
+
pixelOffset: new Cesium.Cartesian2(0, -30),
|
|
585
|
+
outlineWidth: 9,
|
|
586
|
+
outlineColor: Cesium.Color.WHITE,
|
|
587
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
588
|
+
}
|
|
589
|
+
})
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const getCenterPosition = () => {
|
|
593
|
+
if (tempPositions.length < 3) return tempPositions[0]
|
|
594
|
+
const points = tempPositions.map(p => {
|
|
595
|
+
const c = cartesian3ToPoint3D(p)
|
|
596
|
+
return [c.x, c.y]
|
|
597
|
+
})
|
|
598
|
+
const geo = turf.lineString(points)
|
|
599
|
+
const bbox = turf.bbox(geo)
|
|
600
|
+
const bboxPolygon = turf.bboxPolygon(bbox)
|
|
601
|
+
const center = turf.center(bboxPolygon)
|
|
602
|
+
const [lon, lat] = center.geometry.coordinates
|
|
603
|
+
return Cesium.Cartesian3.fromDegrees(lon, lat, height + 0.3)
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const leftClickEvent = () => {
|
|
607
|
+
let lastClickTime = 0
|
|
608
|
+
const MIN_INTERVAL = 250
|
|
609
|
+
|
|
610
|
+
handler.setInputAction(e => {
|
|
611
|
+
const now = Date.now()
|
|
612
|
+
if (now - lastClickTime < MIN_INTERVAL) return
|
|
613
|
+
lastClickTime = now
|
|
614
|
+
|
|
615
|
+
let position = viewer.scene.pickPosition(e.position)
|
|
616
|
+
if (!position) {
|
|
617
|
+
const ellipsoid = viewer.scene.globe.ellipsoid
|
|
618
|
+
position = viewer.scene.camera.pickEllipsoid(e.position, ellipsoid)
|
|
619
|
+
}
|
|
620
|
+
if (!position) return
|
|
621
|
+
|
|
622
|
+
positions.push(position)
|
|
623
|
+
height = unifiedHeight(positions, height)
|
|
624
|
+
if (positions.length === 1) {
|
|
625
|
+
createPolygon()
|
|
626
|
+
}
|
|
627
|
+
createPoint()
|
|
628
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
const mouseMoveEvent = () => {
|
|
632
|
+
handler.setInputAction(e => {
|
|
633
|
+
let position = viewer.scene.pickPosition(e.endPosition)
|
|
634
|
+
if (!position)
|
|
635
|
+
position = viewer.scene.camera.pickEllipsoid(
|
|
636
|
+
e.startPosition,
|
|
637
|
+
viewer.scene.globe.ellipsoid
|
|
638
|
+
)
|
|
639
|
+
if (!position) return
|
|
640
|
+
handleMoveEvent(position)
|
|
641
|
+
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const rightClickEvent = () => {
|
|
645
|
+
handler.setInputAction(e => {
|
|
646
|
+
if (positions.length < 3) {
|
|
647
|
+
stopDraw()
|
|
648
|
+
removeAll()
|
|
649
|
+
} else {
|
|
650
|
+
tempPositions = [...positions]
|
|
651
|
+
currentPolygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(tempPositions)
|
|
652
|
+
currentLabelEntity.position = getCenterPosition()
|
|
653
|
+
currentLabelEntity.label.text = "总面积为 " + computeArea(positions)
|
|
654
|
+
stopDraw()
|
|
655
|
+
}
|
|
656
|
+
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
const handleMoveEvent = (position) => {
|
|
660
|
+
if (positions.length < 1) return
|
|
661
|
+
height = unifiedHeight(positions, height)
|
|
662
|
+
tempPositions = positions.concat(position)
|
|
663
|
+
if (tempPositions.length >= 3 && !currentLabelEntity) createLabel()
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
const unifiedHeight = (positions, height) => {
|
|
667
|
+
if (!height) height = getPositionHeight(positions[0])
|
|
668
|
+
for (let i = 0; i < positions.length; i++) {
|
|
669
|
+
const p = cartesian3ToPoint3D(positions[i])
|
|
670
|
+
positions[i] = Cesium.Cartesian3.fromDegrees(p.x, p.y, height)
|
|
671
|
+
}
|
|
672
|
+
return height
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
const computeArea = (points) => {
|
|
676
|
+
let res = 0
|
|
677
|
+
for (let i = 0; i < points.length - 2; i++) {
|
|
678
|
+
const j = (i + 1) % points.length
|
|
679
|
+
const k = (i + 2) % points.length
|
|
680
|
+
const angle = Angle(points[i], points[j], points[k])
|
|
681
|
+
const dis1 = distance(points[j], points[0])
|
|
682
|
+
const dis2 = distance(points[k], points[0])
|
|
683
|
+
res += (dis1 * dis2 * Math.sin(angle)) / 2
|
|
684
|
+
}
|
|
685
|
+
return res < 1000000
|
|
686
|
+
? Math.abs(res).toFixed(4) + " 平方米"
|
|
687
|
+
: Math.abs(res / 1000000).toFixed(4) + " 平方公里"
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
const Bearing = (from, to) => {
|
|
691
|
+
from = Cesium.Cartographic.fromCartesian(from)
|
|
692
|
+
to = Cesium.Cartographic.fromCartesian(to)
|
|
693
|
+
const lat1 = from.latitude, lon1 = from.longitude
|
|
694
|
+
const lat2 = to.latitude, lon2 = to.longitude
|
|
695
|
+
let angle = -Math.atan2(
|
|
696
|
+
Math.sin(lon1 - lon2) * Math.cos(lat2),
|
|
697
|
+
Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2)
|
|
698
|
+
)
|
|
699
|
+
if (angle < 0) angle += Math.PI * 2.0
|
|
700
|
+
return (angle * 180.0) / Math.PI
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
const Angle = (p1, p2, p3) => {
|
|
704
|
+
const b21 = Bearing(p2, p1)
|
|
705
|
+
const b23 = Bearing(p2, p3)
|
|
706
|
+
let angle = b21 - b23
|
|
707
|
+
if (angle < 0) angle += 360
|
|
708
|
+
return angle
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
const distance = (p1, p2) => {
|
|
712
|
+
const c1 = Cesium.Cartographic.fromCartesian(p1)
|
|
713
|
+
const c2 = Cesium.Cartographic.fromCartesian(p2)
|
|
714
|
+
const geodesic = new Cesium.EllipsoidGeodesic()
|
|
715
|
+
geodesic.setEndPoints(c1, c2)
|
|
716
|
+
let s = geodesic.surfaceDistance
|
|
717
|
+
return Math.sqrt(s * s + Math.pow(c2.height - c1.height, 2))
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
const getPositionHeight = (p) => {
|
|
721
|
+
const c = Cesium.Cartographic.fromCartesian(p)
|
|
722
|
+
return c.height
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
const cartesian3ToPoint3D = (p) => {
|
|
726
|
+
const c = Cesium.Cartographic.fromCartesian(p)
|
|
727
|
+
return {
|
|
728
|
+
x: Cesium.Math.toDegrees(c.longitude),
|
|
729
|
+
y: Cesium.Math.toDegrees(c.latitude),
|
|
730
|
+
z: c.height
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
return {
|
|
735
|
+
draw,
|
|
736
|
+
removeAll
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
144
740
|
const angle = angleMeasurement()
|
|
741
|
+
const distance = distanceMeasurement()
|
|
742
|
+
const height = heightMeasurement()
|
|
743
|
+
const area = areaMeasurement()
|
|
145
744
|
|
|
146
745
|
return {
|
|
147
|
-
angle
|
|
746
|
+
angle,
|
|
747
|
+
distance,
|
|
748
|
+
height,
|
|
749
|
+
area
|
|
148
750
|
}
|
|
149
751
|
}
|
|
150
752
|
|
package/cesium/utils/usePath.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as Cesium from 'cesium'
|
|
2
2
|
|
|
3
|
-
export enum
|
|
3
|
+
export enum EMovementType {
|
|
4
4
|
SPEED = 'speed',
|
|
5
5
|
TIME = 'time'
|
|
6
6
|
}
|
|
@@ -14,14 +14,14 @@ export interface IPathType {
|
|
|
14
14
|
modelParams: {
|
|
15
15
|
id: string;
|
|
16
16
|
name: string;
|
|
17
|
-
|
|
17
|
+
url: string;
|
|
18
18
|
};
|
|
19
19
|
path: {
|
|
20
20
|
duration: number;
|
|
21
21
|
point: Cesium.Cartesian3;
|
|
22
22
|
speed: number;
|
|
23
23
|
}[];
|
|
24
|
-
|
|
24
|
+
movementType: EMovementType;
|
|
25
25
|
totalDuration: number;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -40,11 +40,11 @@ const usePath = () => {
|
|
|
40
40
|
}
|
|
41
41
|
if (i > 0) {
|
|
42
42
|
const distance = Cesium.Cartesian3.distance(item.path[i - 1].point, value.point).toFixed();
|
|
43
|
-
if (item.
|
|
43
|
+
if (item.movementType === EMovementType.SPEED) {
|
|
44
44
|
const time = Number(distance) / value.speed
|
|
45
45
|
item.totalDuration = item.totalDuration + time
|
|
46
46
|
property.addSample(Cesium.JulianDate.addSeconds(startTime, item.totalDuration, new Cesium.JulianDate()), value.point);
|
|
47
|
-
} else if (item.
|
|
47
|
+
} else if (item.movementType === EMovementType.TIME) {
|
|
48
48
|
item.totalDuration = item.totalDuration + Number(value.duration)
|
|
49
49
|
property.addSample(Cesium.JulianDate.addSeconds(startTime, item.totalDuration, new Cesium.JulianDate()), value.point);
|
|
50
50
|
}
|
|
@@ -62,7 +62,7 @@ const usePath = () => {
|
|
|
62
62
|
position: property,
|
|
63
63
|
orientation: new Cesium.VelocityOrientationProperty(property),
|
|
64
64
|
model: {
|
|
65
|
-
uri: item.modelParams.
|
|
65
|
+
uri: item.modelParams.url,
|
|
66
66
|
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
67
67
|
}
|
|
68
68
|
})
|
|
@@ -76,22 +76,11 @@ const usePath = () => {
|
|
|
76
76
|
|
|
77
77
|
viewer.clock.currentTime = startTime.clone();
|
|
78
78
|
viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;
|
|
79
|
-
viewer.clock.shouldAnimate = true;
|
|
80
79
|
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
const controlAction = (viewer: Cesium.Viewer, status: EControlAction) => {
|
|
84
|
-
viewer.clock.shouldAnimate = (status === EControlAction.PAUSE ? false : true)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const reset = () => {
|
|
88
|
-
//todo
|
|
89
|
-
}
|
|
90
|
-
|
|
91
82
|
return {
|
|
92
83
|
playAnimation,
|
|
93
|
-
controlAction,
|
|
94
|
-
reset
|
|
95
84
|
}
|
|
96
85
|
}
|
|
97
86
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "easy-three-utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.347",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
"author": "",
|
|
9
9
|
"license": "ISC",
|
|
10
10
|
"types": "./index.d.ts",
|
|
11
|
-
"description": "
|
|
11
|
+
"description": "更新长度测量"
|
|
12
12
|
}
|