fuchengshen
2022-07-09 3a25c05b5ab837714f30469cdcb1e2a77d8d7f6c
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import * as mars3d from "mars3d"
 
export let map // mars3d.Map三维地图对象
export let graphicLayer // 矢量图层对象
 
// 需要覆盖config.json中地图属性参数(当前示例框架中自动处理合并)
export const mapOptions = {
  scene: {
    // 此处参数会覆盖config.json中的对应配置
    center: { lat: 40, lng: 111.833884, alt: 20000000, heading: 0, pitch: -90 },
    cameraController: {
      zoomFactor: 3.0,
      minimumZoomDistance: 1,
      maximumZoomDistance: 300000000,
      constrainedAxis: false // 解除在南北极区域鼠标操作限制
    }
  }
}
 
/**
 * 初始化地图业务,生命周期钩子函数(必须)
 * 框架在地图初始化完成后自动调用该函数
 * @param {mars3d.Map} mapInstance 地图对象
 * @returns {void} 无
 */
export function onMounted(mapInstance) {
  map = mapInstance // 记录map
 
  // 创建矢量数据图层
  graphicLayer = new mars3d.layer.GraphicLayer()
  map.addLayer(graphicLayer)
 
  showLoading()
 
  const czml = Cesium.CzmlDataSource.load("//data.mars3d.cn/file/czml/satellite-one.czml")
  czml
    .then(function (dataSource) {
      hideLoading()
 
      map.dataSources.add(dataSource)
 
      const satelliteEntity = dataSource.entities.values[0]
 
      const swathWidth = swathWidthDict[satelliteEntity.id]
      satelliteFoot.start(satelliteEntity, swathWidth)
    })
    .catch(function (error) {
      globalAlert(error, "加载数据出错")
    })
}
 
/**
 * 释放当前地图业务的生命周期函数
 * @returns {void} 无
 */
export function onUnmounted() {
  map = null
}
 
// 多个卫星时可以可配置【卫星地面投射圆半径,足迹宽度】
const swathWidthDict = {
  "Satellite/CBERS 4": 650000.0
}
 
// 地球观测的轨道预测,包含绘制卫星到地球的足迹功能。
const satelliteFoot = {
  start: function (entity, instrumentFOV) {
    if (!instrumentFOV) {
      // 默认值;
      instrumentFOV = 2000 * 1000
    }
 
    const secondMultiplier = instrumentFOV / 250000.0 // 每间隔多少公里进行显示一次足迹。
    const intervalBetweenFootPrints = 40 * secondMultiplier // setInterval间隔脚印的时长
    const numberOfFootPrintsAtAtime = parseInt(90 / Math.ceil(secondMultiplier)) * 5 // 保持足迹的数量个数
 
    const point = mars3d.LngLatPoint.fromCartesian(entity.position, map.clock.currentTime)
    this.drawOneFoot(point, instrumentFOV)
 
    let timeLast = map.clock.currentTime.secondsOfDay + intervalBetweenFootPrints
 
    map.on(mars3d.EventType.clockTick, (event) => {
      const sxTimes = Math.abs(map.clock.currentTime.secondsOfDay - timeLast) // 剩下时长
 
      if (sxTimes < 1 || sxTimes > intervalBetweenFootPrints) {
        timeLast = map.clock.currentTime.secondsOfDay + intervalBetweenFootPrints
 
        if (graphicLayer.length >= numberOfFootPrintsAtAtime) {
          graphicLayer.clear()
        }
 
        const point = mars3d.LngLatPoint.fromCartesian(entity.position, map.clock.currentTime)
        this.drawOneFoot(point, instrumentFOV)
      }
    })
  },
 
  // 绘制一个足迹
  drawOneFoot: function (point, instrumentFOV) {
    // 卫星到地面的垂直线
    this._drawLineGroundToSatellite(point)
 
    // 投射圆锥体
    this._drawInstrumentFootPrintSwathWidth(instrumentFOV, point)
 
    // 在地球表面上绘制可见足迹椭圆
    this._drawVisibleFootPrint(point)
  },
 
  // 卫星到地面的垂直线,point: 卫星在天空中的位置
  _drawLineGroundToSatellite: function (point) {
    const groundPoint = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, 0.0)
 
    const point1 = new mars3d.graphic.PointPrimitive({
      position: point,
      style: {
        pixelSize: 2,
        color: Cesium.Color.RED
      }
    })
    graphicLayer.addGraphic(point1)
 
    const point2 = new mars3d.graphic.PointPrimitive({
      position: groundPoint,
      style: {
        pixelSize: 2,
        color: Cesium.Color.RED
      }
    })
    graphicLayer.addGraphic(point2)
 
    const primitiveLine = new mars3d.graphic.PolylinePrimitive({
      positions: [point, groundPoint],
      style: {
        width: 1,
        color: Cesium.Color.YELLOW
      }
    })
    graphicLayer.addGraphic(primitiveLine)
  },
  // 投射圆锥体
  _drawInstrumentFootPrintSwathWidth: function (instrumentFOV, point) {
    const primitive = new mars3d.graphic.CylinderPrimitive({
      name: "视锥体",
      position: Cesium.Cartesian3.fromDegrees(point.lng, point.lat, point.alt / 2),
      style: {
        length: point.alt,
        topRadius: 0.0,
        bottomRadius: instrumentFOV,
        color: Cesium.Color.GREEN.withAlpha(0.3),
        outline: true,
        outlineColor: Cesium.Color.RED.withAlpha(0.5)
      }
    })
    graphicLayer.addGraphic(primitive)
  },
  // 在地球表面上绘制可见足迹椭圆(红色外圈线)
  _drawVisibleFootPrint: function (point) {
    const groundPoint = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, 0.0)
 
    const radiusOfEarth = Cesium.Cartesian3.distance(new Cesium.Cartesian3(0, 0, 0), groundPoint)
    const satToOrignEarth = radiusOfEarth + point.alt // point to origin of earth
    const groundPointToSatPointToTangentAngle = Cesium.Math.toDegrees(Math.asin(radiusOfEarth / satToOrignEarth))
    const groundPointToOriginToTangentAngle = 90.0 - groundPointToSatPointToTangentAngle
    const distanceAlongGround = Cesium.Math.TWO_PI * radiusOfEarth * (groundPointToOriginToTangentAngle / 360.0)
 
    const primitive = new mars3d.graphic.CirclePrimitive({
      name: "可视卫星范围(45度)",
      position: groundPoint,
      style: {
        radius: distanceAlongGround,
        color: "#ff0000",
        opacity: 0.1,
        outline: true,
        outlineColor: "#ff0000"
      }
    })
    graphicLayer.addGraphic(primitive)
  }
}