吉安感知网项目-前端
chenyao
yesterday c567cbca3b78a7e06a827acbab56a46657e31aa1
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import * as Cesium from 'cesium'
 
export const getBoundsFromCartesians = positions => {
    const cartographics = positions
        .map(pos => (pos?.longitude ? pos : Cesium.Cartographic.fromCartesian(pos)))
        .filter(Boolean)
 
    if (!cartographics.length) return null
 
    let west = cartographics[0].longitude
    let east = cartographics[0].longitude
    let south = cartographics[0].latitude
    let north = cartographics[0].latitude
 
    cartographics.forEach(carto => {
        west = Math.min(west, carto.longitude)
        east = Math.max(east, carto.longitude)
        south = Math.min(south, carto.latitude)
        north = Math.max(north, carto.latitude)
    })
 
    return { west, east, south, north }
}
 
export const getBoundsFromLngLats = points => {
    if (!points?.length) return null
    let west = points[0].lng
    let east = points[0].lng
    let south = points[0].lat
    let north = points[0].lat
    points.forEach(point => {
        west = Math.min(west, point.lng)
        east = Math.max(east, point.lng)
        south = Math.min(south, point.lat)
        north = Math.max(north, point.lat)
    })
    return {
        west: Cesium.Math.toRadians(west),
        east: Cesium.Math.toRadians(east),
        south: Cesium.Math.toRadians(south),
        north: Cesium.Math.toRadians(north),
    }
}
 
export const rectanglePositionsFromBounds = bounds => {
    if (!bounds) return []
    const { west, east, south, north } = bounds
    return [
        Cesium.Cartesian3.fromRadians(west, south),
        Cesium.Cartesian3.fromRadians(east, south),
        Cesium.Cartesian3.fromRadians(east, north),
        Cesium.Cartesian3.fromRadians(west, north),
    ]
}
 
export const getCenterFromBounds = bounds => {
    if (!bounds) return null
    return new Cesium.Cartographic(
        (bounds.west + bounds.east) / 2,
        (bounds.south + bounds.north) / 2,
        0
    )
}
 
export const getMetersBetween = (start, end) => {
    const geodesic = new Cesium.EllipsoidGeodesic(start, end)
    return geodesic.surfaceDistance
}
 
export const buildEllipsePositions = (centerCartesian, semiMajor, semiMinor, steps = 60) => {
    if (!centerCartesian || !semiMajor || !semiMinor) return []
    const positions = []
    const frame = Cesium.Transforms.eastNorthUpToFixedFrame(centerCartesian)
    for (let i = 0; i < steps; i += 1) {
        const angle = (i / steps) * Math.PI * 2
        const x = Math.cos(angle) * semiMajor
        const y = Math.sin(angle) * semiMinor
        const local = new Cesium.Cartesian3(x, y, 0)
        const world = Cesium.Matrix4.multiplyByPoint(frame, local, new Cesium.Cartesian3())
        positions.push(world)
    }
    return positions
}
 
export const cartesianToLocal = (centerCartesian, positionCartesian) => {
    const frame = Cesium.Transforms.eastNorthUpToFixedFrame(centerCartesian)
    const inverse = Cesium.Matrix4.inverse(frame, new Cesium.Matrix4())
    return Cesium.Matrix4.multiplyByPoint(inverse, positionCartesian, new Cesium.Cartesian3())
}
 
export const formatBufferRadius = meters => {
    if (!Number.isFinite(meters)) return ''
    if (meters >= 1000) return `${(meters / 1000).toFixed(2)} km`
    return `${meters.toFixed(2)} m`
}
 
export const getBufferRadiusPoint = (centerCartesian, radius) => {
    if (!centerCartesian || !Number.isFinite(radius)) return null
    const frame = Cesium.Transforms.eastNorthUpToFixedFrame(centerCartesian)
    const local = new Cesium.Cartesian3(radius, 0, 0)
    return Cesium.Matrix4.multiplyByPoint(frame, local, new Cesium.Cartesian3())
}
 
export const getBufferRadiusLabelStyle = () => ({
    font: '14px Source Han Sans CN',
    fillColor: Cesium.Color.WHITE,
    outlineColor: Cesium.Color.fromBytes(24, 48, 92, 255),
    outlineWidth: 2,
    style: Cesium.LabelStyle.FILL_AND_OUTLINE,
    showBackground: true,
    backgroundColor: Cesium.Color.fromBytes(8, 12, 22, 180),
    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
    horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
    pixelOffset: new Cesium.Cartesian2(0, -12),
    disableDepthTestDistance: Number.POSITIVE_INFINITY,
})
 
export const addBufferRadiusLabelEntity = (dataSource, centerCartesian, radius, options = {}) => {
    if (!dataSource) return null
    const position = getBufferRadiusPoint(centerCartesian, radius)
    if (!position) return null
    const { name, customData } = options
    return dataSource.entities.add({
        ...(name ? { name } : {}),
        ...(customData ? { customData } : {}),
        position,
        label: {
            ...getBufferRadiusLabelStyle(),
            text: formatBufferRadius(radius),
        },
    })
}