吉安感知网项目-前端
张含笑
2026-01-30 6c4bd2467bb6651c6edcf8a9741dcd4e9b1aa6d3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import * as Cesium from 'cesium'
 
// 获取正射影像4至点
export function getOrthoImageBoundaryPoints (data) {
    const arr = JSON.parse(data)
 
    if (arr.length !== 4) return undefined
 
    const west = Math.min(arr[0], arr[2])
    const east = Math.max(arr[0], arr[2])
    const south = Math.min(arr[1], arr[3])
    const north = Math.max(arr[1], arr[3])
 
    return Cesium.Rectangle.fromDegrees(
        west,
        south,
        east,
        north
    )
}
 
/**
 * 飞到中心点并且所有点在可视范围
 *  @param positionsData 二维数组,每项为 [lon, lat] 或 三维数组 [lon, lat, height]
 *  @param viewer Cesium.Viewer 实例
 *  @param multiple 缩放倍数-默认为4
 *  @param pitch 俯仰角-默认为-90
 */
export function flyVisual({ positionsData, viewer, multiple = 4, pitch = -90 }) {
    if (!Array.isArray(positionsData) || positionsData.length === 0) return
 
    // 如果是一个点,加两个点方便后续生成外包围盒
    if (positionsData.length === 1) {
        const [lon, lat, height = 0] = positionsData[0]
        positionsData = [
            [lon + 0.001, lat + 0.001, height],
            [lon - 0.001, lat - 0.001, height],
            [lon, lat, height],
        ]
    }
    const positions = positionsData.map(([lon, lat, height = 0]) =>
        Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat), Number(height || 0))
    )
 
    // 计算最高高度和中心点经纬度
    let maxHeight = -Infinity
    let sumLon = 0,
        sumLat = 0
    for (const [lon, lat, height] of positionsData) {
        sumLon += Number(lon)
        sumLat += Number(lat)
        maxHeight = Math.max(maxHeight, Number(height || 0))
    }
    const centerLon = sumLon / positionsData.length
    const centerLat = sumLat / positionsData.length
    const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
    // 暂时飞向 BoundingSphere
    viewer.camera.flyToBoundingSphere(Cesium.BoundingSphere.fromPoints(positions), {
        duration: 0,
        offset: {
            heading: Cesium.Math.toRadians(0),
            pitch: Cesium.Math.toRadians(pitch),
            range: boundingSphere.radius * multiple,
        },
        complete: () => {
            // 飞行完成后检查相机高度是否小于最高点
            const cameraHeight = Cesium.Cartographic.fromCartesian(viewer.camera.position).height
            if (cameraHeight < maxHeight) {
                viewer.camera.flyTo({
                    destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, maxHeight + 100), // 加100米缓冲
                    duration: 1.5,
                    orientation: {
                        heading: viewer.camera.heading,
                        pitch: viewer.camera.pitch,
                        roll: viewer.camera.roll,
                    },
                })
            }
        },
    })
}