目前在做一个综合DEMO,部分功能实现的代码
代码:
文件:Satellite.js
import * as Cesium from 'cesium'
import { useCesiumStore } from '@/stores/useCesiumStore.js' //我这里将viewer加入pinia中管理
import { toRaw } from 'vue' //需要将仓库的viwer进行去除响应式
import * as satellite from 'satellite.js' //一个计算轨道的插件
// 加载卫星模型
export const loadSatellite = () => {
const viewer = toRaw(useCesiumStore().viewer); // Get the viewer instance
satlliteTest()
function satlliteTest() {
// Sample TLE-tle数据示例,来源于satellite.js 官网,哨兵2号
const tleLine1 = '1 40697U 15028A 24094.83685398 .00000178 00000-0 84347-4 0 9997',
tleLine2 = '2 40697 98.5687 170.1617 0001271 93.4314 266.7014 14.30826534458716'
const satrec = satellite.twoline2satrec(tleLine1, tleLine2) // 解析tle数据
let totalIntervalsInDay = satrec.no * 1440 * 0.159155 //1440 = min && 0.159155 = 1turn
// 获得运行一圈的分钟数
let minsPerInterval = 1440 / totalIntervalsInDay // mins for 1 revolution around earth
// 获取startTime && endTime
const { startTime, endTime } = getStratEndTime(minsPerInterval)
viewer.clock.startTime = startTime.clone()
viewer.clock.endTime = endTime.clone()
viewer.clock.currentTime = startTime.clone()
viewer.clock.multiplier = 100 // 设置播放速度,数值越大,卫星转动越快
viewer.clock.clockRange = Cesium.ClockRange.LOOP_REPEAT // 设置循环播放
// viewer.timeline.zoomTo(startTime, endTime) // 缩放到时间轴范围
// 获取positionProperty
const positionProperty = getPositionSample(satrec, minsPerInterval)
// const headingCorrection = Cesium.Math.toRadians(90)
const entity = viewer.entities.add({
name: '卫星',
availability: new Cesium.TimeIntervalCollection([ // 时间区间
new Cesium.TimeInterval({
start: startTime,
stop: endTime
})
]),
position: positionProperty,
orientation: new Cesium.VelocityOrientationProperty(positionProperty), // 方向
// 卫星模型
model: {
uri: 'src/assets/satelite/satelite.glb', // 模型uri
// minimumPixelSize: 128,
scale: 80000
// maximumScale: 20000,
},
path: {
resolution: 1,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.5,
color: Cesium.Color.RED
}),
width: 2
// leadTime: 720,
// trailTime: 720
},
cylinder: {
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 贴地
length: 1000000, // 圆柱体高度
topRadius: 0, // 顶部半径
bottomRadius: 700000, // 底部半径
material: Cesium.Color.BLUE.withAlpha(0.1), // 颜色
outline: 1, // 轮廓线
numberOfVerticalLines: 0, // 竖线数量
outlineColor: Cesium.Color.BLUE.withAlpha(0.1), // 轮廓线颜色
//改变位置为model的下方
position: Cesium.Cartesian3.fromDegrees(116.3975, 39.909, 10000)
// position:
}
})
// 插值
entity.position.setInterpolationOptions({ // 设置插值选项
interpolationDegree: 5, // 插值阶数
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation // 插值算法
})
}
/**
* 计算 startTime && endTime
* minsPerInterval: 一圈分钟数
*/
function getStratEndTime(minsPerInterval) {
const startTimeStamp = Date.now()
// 结束时间为一圈后的时间
const endTimeStamp = startTimeStamp + minsPerInterval * 60 * 1000
let startTime = new Cesium.JulianDate.fromDate(new Date(startTimeStamp))
startTime = Cesium.JulianDate.addHours(startTime, 8, new Cesium.JulianDate())
let endTime = new Cesium.JulianDate.fromDate(new Date(endTimeStamp))
endTime = Cesium.JulianDate.addHours(endTime, 8, new Cesium.JulianDate())
return {
startTime,
endTime
}
}
/**
* 计算SampledPositionProperty
* satrec: satellite.twoline2satrec返回值
* minsPerInterval:一圈分钟数
*/
function getPositionSample(satrec, minsPerInterval) {
const positionProperty = new Cesium.SampledPositionProperty()
const now = Date.now()
for (let i = 0; i <= minsPerInterval; i++) {
// 从现在起,获取一圈内每分钟的位置;生成一个数组,用作插值
const curTimeDate = new Date(now + i * 60 * 10000)
var positionAndVelocity = satellite.propagate(satrec, curTimeDate) // 此方法拿到的是惯性系坐标
// var gmst = satellite.gstime(new Date(curTimeDate))
// 惯性
const positionEci = positionAndVelocity.position
// 惯性转成地固
// const positionEcf = satellite.eciToEcf(positionEci, gmst)
// julian日期
const curJulianDate = new Cesium.JulianDate.fromDate(curTimeDate)
// 北京时
const d = new Cesium.JulianDate.addHours(curJulianDate, 8, new Cesium.JulianDate())
positionProperty.addSample(
d,
// 这里使用惯性或者地固都行,但是地固系在端点处偏差较大,因此使用惯性系
new Cesium.Cartesian3(positionEci.x * 1000, positionEci.y * 1000, positionEci.z * 1000)
)
}
return positionProperty
}
}