ts/src/js/satelliteEntity.js

357 lines
12 KiB
JavaScript
Raw Normal View History

2024-12-09 06:44:52 +00:00
import { twoline2satrec, propagate } from 'satellite.js'
import CreateFrustum from './sensor.js'
// import './polylineTrail.js'
import chroma from 'chroma-js'
class SatelliteEntity {
constructor(tle = '', options = {}) {
const [name, tleLine1, tleLine2] = this._checkTle(tle)
let circle = tleLine2.slice(52, 64)
this.name = name.trim()
this.tleLine1 = tleLine1.trim()
this.tleLine2 = tleLine2.trim()
this.satrec = twoline2satrec(this.tleLine1, this.tleLine2)
this.totalSeconds = 7 * 86400 // 24小时
2024-12-09 06:44:52 +00:00
this.stepSeconds = 100
this.leadTime = parseInt((24 * 3600) / circle)
this.trailTime = 0
this.sensor = false
this.entity = null
this.sensorType = 'rectangle'
2024-12-09 06:44:52 +00:00
}
get sensor() {
return this.sensor
}
set sensor(showSensor) {
console.log(showSensor, 'showSensor')
if (showSensor) {
if (this.sensorType === 'conic') {
this.createConicSensor(this.entity)
} else {
this.createRectangleSensor(this.entity)
}
}
//showSensor &&
2024-12-09 06:44:52 +00:00
}
_checkTle(tle) {
let elements = tle.split('\n')
if (elements.length !== 3) {
throw new Error('tle data error')
}
return elements
}
// 获取地心惯性坐标系坐标
getPositionEci(time) {
return propagate(this.satrec, time).position
}
// 创建PositionProperty
_getPositionProperty() {
const start = Cesium.JulianDate.fromIso8601(new Date().toISOString())
const positionProperty = new Cesium.SampledPositionProperty(
Cesium.ReferenceFrame.INERTIAL
)
let now = Date.now()
for (let i = 0; i < this.totalSeconds / this.stepSeconds; i++) {
let sateTime = new Date(now + i * this.stepSeconds * 1000)
let sateCoord = this.getPositionEci(sateTime)
if (!sateCoord) {
continue
}
const cesiumTime = Cesium.JulianDate.addSeconds(
start,
i * this.stepSeconds,
new Cesium.JulianDate()
)
const cesiumPosition = {
x: sateCoord.x * 1000,
y: sateCoord.y * 1000,
z: sateCoord.z * 1000,
}
positionProperty.addSample(cesiumTime, cesiumPosition)
}
return positionProperty
}
// 创建卫星实例
createSatelliteEntity() {
const start = Cesium.JulianDate.fromIso8601(new Date().toISOString())
const stop = Cesium.JulianDate.addSeconds(
start,
this.totalSeconds,
new Cesium.JulianDate()
)
const color = Cesium.Color.fromCssColorString(
chroma.random().brighten().hex()
)
// const color = Cesium.Color.fromRandom({ alpha: 0.5 })
let satelliteEntity = {
name: this.name,
description: this.name,
show: true,
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({ start: start, stop: stop }),
]),
position: this._getPositionProperty(),
// point: {
// pixelSize: 8,
// color: color,
// // scaleByDistance: new Cesium.NearFarScalar(1.5e3, 1, 8.0e8, 0.5),
// },
path: new Cesium.PathGraphics({
width: 2,
show: true,
leadTime: this.leadTime,
trailTime: this.trailTime,
// material: color,
material: new Cesium.PolylineTrailLinkMaterialProperty({
color,
duration: 86400 * 1000,
2024-12-09 06:44:52 +00:00
}),
}),
label: {
show: true,
text: this.name,
font: '12px sans-serif',
showBackground: true,
backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.5),
backgroundPadding: new Cesium.Cartesian2(4, 4),
outlineWidth: 1,
verticalOrigin: Cesium.VerticalOrigin.TOP,
horizontalOrigin: Cesium.VerticalOrigin.LEFT,
pixelOffset: new Cesium.Cartesian2(0, 5),
fillColor: Cesium.Color.WHITE,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10.0, 50000000),
},
billboard: {
image: '/images/satellite.png',
width: 40,
height: 40,
show: true,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
10.0,
50000000
),
},
// model: {
// uri: '/GV/resources/model/wx.glb',
// minimumPixelSize: 64,
// maximumScale: 20000,
// show: true,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 10.0,
// 50000000
// ),
// },
// cylinder: {
// HeightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
// length: 1700000,
// topRadius: 0,
// bottomRadius: 700000 / 2,
// material: Cesium.Color.RED.withAlpha(0.4),
// outline: !0,
// numberOfVerticalLines: 0,
// outlineColor: Cesium.Color.RED.withAlpha(0.8),
// horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
// },
orientation: new Cesium.VelocityOrientationProperty(
this._getPositionProperty()
),
}
// this.createSensor(satelliteEntity)
// return satelliteEntity
this.entity = viewer.entities.add(satelliteEntity)
return this.entity
}
createSensor(satellite) {
// const color = '#00ffff'
// let customSensor = new CesiumSensorVolumes.RectangularPyramidSensorVolume()
// // const sate = tasks.value.find((item) => item.satId === sate_id);
// // radius 是指波束的长度
// customSensor.radius = 40000000.0
// // customSensor.id = `${sate_id}_sensor`;
// customSensor.id = `test_sensor`
// customSensor.intersectionWidth = 1
// customSensor.xHalfAngle = Cesium.Math.toRadians(1)
// customSensor.yHalfAngle = Cesium.Math.toRadians(1)
// customSensor.lateralSurfaceMaterial = Cesium.Material.fromType('Color')
// customSensor.lateralSurfaceMaterial.uniforms.color =
// new Cesium.Color.fromCssColorString(color).withAlpha(0.3)
// // 默认矩阵
// customSensor.modelMatrix = new Cesium.Matrix4()
// // 使用preRender 监听卫星每帧运动
// viewer.scene.preRender.addEventListener((scene, time) => {
// customSensor.show = false
// // 判断数据源中所有实体是否准备就绪viewer.dataSourceDisplay.dataSources = viewer.dataSources
// if (viewer.dataSourceDisplay.ready) {
// // const satellite = viewer.dataSources
// // .getByName("simDemon")[0]
// // .entities.getById(sate_id);
// // 根据时间获取卫星实时笛卡尔位置
// let position = Cesium.Property.getValueOrUndefined(
// satellite.position,
// time,
// new Cesium.Cartesian3()
// )
// // 根据卫星位置和朝向转换为矩阵信息此处使用的是后台计算的四元数实际一般情况应该使用Cesium.Transforms+position转换
// console.log(
// satellite.orientation.getValue(time),
// 'satellite.orientation.getValue(time)'
// )
// // let m = Cesium.Matrix4.fromRotationTranslation(
// // Cesium.Matrix3.fromQuaternion(
// // satellite.orientation.getValue(time),
// // new Cesium.Matrix3()
// // ),
// // position,
// // new Cesium.Matrix4()
// // )
// let m = this.getModelMatrix(position, satellite.orientation)
// console.log(m, 'm')
// // // let m = Cesium.Transforms.northUpEastToFixedFrame(position)
// customSensor.modelMatrix = m
// // customSensor.modelMatrix = this.getModelMatrix()
// customSensor.show = true
// }
// })
// viewer.scene.primitives.add(customSensor)
// let position = Cesium.Property.getValueOrUndefined(
// satellite.position,
// viewer.clock.currentTime,
// new Cesium.Cartesian3()
// )
}
createRectangleSensor(satellite) {
// viewer.scene.primitives.removeAll()
let position = Cesium.Property.getValueOrUndefined(
satellite.position,
viewer.clock.currentTime,
new Cesium.Cartesian3()
)
const rectangularPyramidSensor =
new CesiumSensorVolumes.RectangularPyramidSensorVolume()
rectangularPyramidSensor.modelMatrix = this.getModelMatrix(position)
rectangularPyramidSensor.radius = 20000000.0
rectangularPyramidSensor.xHalfAngle = Cesium.Math.toRadians(20.0)
rectangularPyramidSensor.yHalfAngle = Cesium.Math.toRadians(10.0)
rectangularPyramidSensor.lateralSurfaceMaterial =
Cesium.Material.fromType('Color')
rectangularPyramidSensor.lateralSurfaceMaterial.uniforms.color =
new Cesium.Color(0.0, 1.0, 1.0, 0.3)
viewer.scene.preRender.addEventListener((scene, time) => {
rectangularPyramidSensor.show = false
let position = Cesium.Property.getValueOrUndefined(
satellite.position,
time,
new Cesium.Cartesian3()
)
rectangularPyramidSensor.modelMatrix = this.getModelMatrix(position)
rectangularPyramidSensor.show = true
})
viewer.scene.primitives.add(rectangularPyramidSensor)
}
getModelMatrix(location) {
// let ellipsoid = viewer.scene.globe.ellipsoid
// console.log(position, '----')
// let location = ellipsoid.cartographicToCartesian(
// new Cesium.Cartographic(
// Cesium.Math.toRadians(120.0),
// Cesium.Math.toRadians(24.0),
// 1300000
// )
// )
let modelMatrix = Cesium.Transforms.northEastDownToFixedFrame(location)
let orientation = Cesium.Matrix3.multiply(
Cesium.Matrix3.multiply(
Cesium.Matrix3.fromRotationZ(0.0),
Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(0.0)),
new Cesium.Matrix3()
),
Cesium.Matrix3.fromRotationX(0.0),
new Cesium.Matrix3()
)
return Cesium.Matrix4.multiply(
modelMatrix,
Cesium.Matrix4.fromRotationTranslation(
orientation,
Cesium.Cartesian3.ZERO
),
new Cesium.Matrix4()
)
}
createConicSensor(satellite) {
let position = Cesium.Property.getValueOrUndefined(
satellite.position,
viewer.clock.currentTime,
new Cesium.Cartesian3()
)
// const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics()
// conicSensor.radius = 20000000.0
// conicSensor.modelMatrix = this.getModelMatrix(position)
// conicSensor.intersectionColor = new Cesium.ConstantProperty(
// new Cesium.Color(0.1, 0.2, 0.3, 0.4)
// )
const customSensor = new CesiumSensorVolumes.CustomSensorVolume()
customSensor.modelMatrix = this.getModelMatrix(position)
customSensor.radius = 20000000.0
// customSensor.directions = directions;
viewer.scene.primitives.add(customSensor)
viewer.scene.preRender.addEventListener((scene, time) => {
customSensor.show = false
let position = Cesium.Property.getValueOrUndefined(
satellite.position,
time,
new Cesium.Cartesian3()
)
customSensor.modelMatrix = this.getModelMatrix(position)
customSensor.show = true
})
viewer.scene.primitives.add(customSensor)
}
2024-12-09 06:44:52 +00:00
// createSensor(satellite) {
// // let sensor = new Sensor({
// // position: satellite.position,
// // orientation: satellite.orientation,
// // aspectRatio: 1000,
// // })
// // viewer.scene.preRender.addEventListener((scene, time) => {
// let position = Cesium.Property.getValueOrUndefined(
// satellite.position,
// viewer.clock.currentTime,
// new Cesium.Cartesian3()
// )
// console.log(position, 'position')
// let heading = 0
// let pitch = 0
// let roll = 90
// let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
// let orientation = Cesium.Quaternion.fromHeadingPitchRoll(hpr)
// let sensor = new CreateFrustum({
// position: position,
// orientation: orientation,
// far: 1000000,
// aspectRatio: 600 / 1080,
// })
// console.log(sensor, 'sensor')
// // })
// }
}
export default SatelliteEntity