feat:新增未完成的卫星通信载荷

This commit is contained in:
严争鸣 2025-02-25 15:59:30 +08:00
parent de9d1a4db5
commit f4d452c196
8 changed files with 329 additions and 112 deletions

View File

@ -5,6 +5,7 @@ const baseMap = new Map()
const mubiaoMap = new Map()
const mubiaoConicMap = new Map()
const satelliteMap = new Map()
const satelliteBeamMap = new Map()
const mbPayloadShowMap = reactive(new Map())
// const satDetectingPayloadMap = reactive(new Map())
@ -17,6 +18,7 @@ export const useEntity = () => {
mubiaoMap,
mubiaoConicMap,
satelliteMap,
satelliteBeamMap,
mbPayloadShowMap,
// satDetectingPayloadMap,
// satCommunicationPayloadMap,

242
src/js/Beam.js Normal file
View File

@ -0,0 +1,242 @@
class BeamPrimitiveMaterialProperty {
constructor(option) {
this.opts = {
color: Cesium.Color.RED,
duration: 2000,
time: new Date().getTime(),
repeat: 30,
offset: 0,
thickness: 0.3,
}
this.opts = Object.assign(this.opts, option)
this._definitionChanged = new Cesium.Event()
this._color = undefined
this._colorSubscription = undefined
this.color = this.opts.color
this.duration = this.opts.duration
this._time = this.opts.time
}
}
Object.defineProperties(BeamPrimitiveMaterialProperty.prototype, {
isConstant: {
get: function () {
return false
},
},
definitionChanged: {
get: function () {
return this._definitionChanged
},
},
})
BeamPrimitiveMaterialProperty.prototype.getType = function (time) {
return 'BeamPrimitive'
}
BeamPrimitiveMaterialProperty.prototype.getValue = function (time, result) {
if (!Cesium.defined(result)) {
result = {}
}
result.color = Cesium.Property.getValueOrClonedDefault(
this._color,
time,
Cesium.Color.WHITE,
result.color
)
result.time =
((new Date().getTime() - this._time) % this.duration) / this.duration / 10
result.repeat = this.opts.repeat
result.offset = this.opts.offset
result.thickness = this.opts.thickness
return result
}
BeamPrimitiveMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof BeamPrimitiveMaterialProperty &&
Cesium.Property.equals(this._color, other._color))
)
}
Cesium.BeamPrimitiveMaterialProperty = BeamPrimitiveMaterialProperty
Cesium.Material.BeamPrimitiveType = 'BeamPrimitive'
Cesium.Material.BeamPrimitiveSource =
'uniform vec4 color;\n\
uniform float repeat;\n\
uniform float offset;\n\
uniform float thickness;\n\
czm_material czm_getMaterial(czm_materialInput materialInput){\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
float sp = 1.0/repeat;\n\
vec2 st = materialInput.st;\n\
float dis = distance(st, vec2(0.5));\n\
float m = mod(dis + offset-time, sp);\n\
float a = step(sp*(1.0-thickness), m); \n\
material.diffuse = color.rgb;\n\
material.alpha = a * color.a;\n\
return material;\n\
}'
Cesium.Material._materialCache.addMaterial(Cesium.Material.BeamPrimitiveType, {
fabric: {
type: Cesium.Material.BeamPrimitiveType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
time: 0,
repeat: 30,
offset: 0,
thickness: 0.3,
},
source: Cesium.Material.BeamPrimitiveSource,
},
translucent: function (material) {
return true
},
})
export class Beam {
constructor(opt) {
this.topEntity = opt.topEntity
this.bottomEntity = opt.bottomEntity
this.color = opt.color || '#00dcff82'
this.topRadius = opt.topRadius || 0
this.bottomRadius = opt.bottomRadius || 10000
this.duration = opt.duration || 2000
this.repeat = opt.repeat || 160
this.centerPoint = null
this.distance = null
this.beamEntity = null
this._listener = null
}
create() {
const cylinder = viewer.entities.add({
// name: 'Red cone',
position: this.centerPoint,
// orientation: null,
cylinder: {
topRadius: 0,
bottomRadius: 10000,
length: this.distance,
topSurface: true, //新增参数,控制顶部是否渲染
bottomSurface: true, //新增参数,控制底部是否渲染
material: new Cesium.BeamPrimitiveMaterialProperty({
color: Cesium.Color.fromCssColorString(this.color),
thickness: 0.2,
duration: this.duration,
repeat: this.repeat,
}),
},
})
this.beamEntity = cylinder
this._listener = (scene, time) => {
if (!this.beamEntity) {
return
}
let topPosition = Cesium.Property.getValueOrUndefined(
this.topEntity.position,
time,
new Cesium.Cartesian3()
)
let bottomPosition = this.bottomEntity.position
console.log(bottomPosition, 'bottomPosition')
this.centerPoint = this._getCenterPoint(topPosition, bottomPosition)
console.log(this.centerPoint, 'centerPoint')
this.beamEntity.position = this.centerPoint
this.distance = this._getDistance(topPosition, bottomPosition)
this.beamEntity.cylinder.length = this.distance
console.log(this.distance)
const orientation = this._getOrientation(topPosition, bottomPosition)
this.beamEntity.orientation = orientation
}
viewer.scene.preRender.addEventListener(this._listener)
}
_getCenterPoint(t, b) {
this.centerPoint = Cesium.Cartesian3.lerp(
t,
b,
0.5,
new Cesium.Cartesian3()
)
}
_getDistance(t, b) {
this.distance = Cesium.Cartesian3.distance(t, b)
}
_getOrientation(t, b) {
let m = this._getModelMatrix(t, b)
let hpr = this._getHeadingPitchRoll(m)
hpr.pitch = hpr.pitch + Cesium.Math.PI / 2 + Cesium.Math.PI
let orientation = Cesium.Transforms.headingPitchRollQuaternion(t, hpr)
return orientation
}
_getModelMatrix(pointA, pointB) {
//向量AB
const vector2 = Cesium.Cartesian3.subtract(
pointB,
pointA,
new Cesium.Cartesian3()
)
//归一化
const normal = Cesium.Cartesian3.normalize(vector2, new Cesium.Cartesian3())
//旋转矩阵
const rotationMatrix3 =
Cesium.Transforms.rotationMatrixFromPositionVelocity(
pointA,
normal,
Cesium.Ellipsoid.WGS84
)
const modelMatrix4 = Cesium.Matrix4.fromRotationTranslation(
rotationMatrix3,
pointA
)
return modelMatrix4
}
_getHeadingPitchRoll(m) {
const m1 = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Matrix4.getTranslation(m, new Cesium.Cartesian3()),
Cesium.Ellipsoid.WGS84,
new Cesium.Matrix4()
)
// 矩阵相除
const m3 = Cesium.Matrix4.multiply(
Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()),
m,
new Cesium.Matrix4()
)
// 旋转矩阵
const mat3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3())
// 计算四元数
const q = Cesium.Quaternion.fromRotationMatrix(mat3)
// 计算旋转角(弧度)
const hpr = Cesium.HeadingPitchRoll.fromQuaternion(q)
return hpr
}
remove() {
if (this.entity) {
viewer.entities.remove(this.entity)
this._removeListener()
}
}
_removeListener() {
if (this._listener) {
viewer.scene.preRender.removeEventListener(this._listener)
}
this._listener = null
}
}

View File

@ -1,98 +0,0 @@
class WavePrimitiveMaterialProperty {
constructor(option) {
this.opts = {
color: Cesium.Color.RED,
duration: 2000,
time: new Date().getTime(),
repeat: 30,
offset: 0,
thickness: 0.3,
}
this.opts = Object.assign(this.opts, option)
this._definitionChanged = new Cesium.Event()
this._color = undefined
this._colorSubscription = undefined
this.color = this.opts.color
this.duration = this.opts.duration
this._time = this.opts.time
}
}
Object.defineProperties(WavePrimitiveMaterialProperty.prototype, {
isConstant: {
get: function () {
return false
},
},
definitionChanged: {
get: function () {
return this._definitionChanged
},
},
})
WavePrimitiveMaterialProperty.prototype.getType = function (time) {
return 'WavePrimitive'
}
WavePrimitiveMaterialProperty.prototype.getValue = function (time, result) {
if (!Cesium.defined(result)) {
result = {}
}
result.color = Cesium.Property.getValueOrClonedDefault(
this._color,
time,
Cesium.Color.WHITE,
result.color
)
result.time =
((new Date().getTime() - this._time) % this.duration) / this.duration / 10
result.repeat = this.opts.repeat
result.offset = this.opts.offset
result.thickness = this.opts.thickness
return result
}
WavePrimitiveMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof WavePrimitiveMaterialProperty &&
Cesium.Property.equals(this._color, other._color))
)
}
Cesium.wavePrimitiveProperty = WavePrimitiveMaterialProperty
Cesium.Material.wavePrimitiveType = 'WavePrimitive'
Cesium.Material.wavePrimitiveSource =
'uniform vec4 color;\n\
uniform float repeat;\n\
uniform float offset;\n\
uniform float thickness;\n\
czm_material czm_getMaterial(czm_materialInput materialInput){\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
float sp = 1.0/repeat;\n\
vec2 st = materialInput.st;\n\
float dis = distance(st, vec2(0.5));\n\
float m = mod(dis + offset-time, sp);\n\
float a = step(sp*(1.0-thickness), m); \n\
material.diffuse = color.rgb;\n\
material.alpha = a * color.a;\n\
return material;\n\
}'
Cesium.Material._materialCache.addMaterial(Cesium.Material.wavePrimitiveType, {
fabric: {
type: Cesium.Material.wavePrimitiveType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
time: 0,
repeat: 30,
offset: 0,
thickness: 0.3,
},
source: Cesium.Material.wavePrimitiveSource,
},
translucent: function (material) {
return true
},
})

View File

@ -26,6 +26,8 @@ class SatelliteEntity {
this._sensorAngle = 30
this._sensorType = 'conic'
this._listener = null
// this._beam = false
// this.beamEntityMap = new Map()
}
get sensorType() {
return this._sensorType
@ -85,6 +87,20 @@ class SatelliteEntity {
}
}
// get beam() {
// return this._beam
// }
// set beam(showBeam) {
// this._beam = showBeam
// if (showBeam) {
// if (!this.beamEntityMap.has()) {
// this.createBeam(this.entity)
// }
// } else {
// this.removeBeam()
// }
// }
_checkTle(tle) {
let elements = tle.split('\n')
if (elements.length !== 3) {
@ -521,6 +537,10 @@ class SatelliteEntity {
this._listener = null
}
}
// createBeam() {
// }
destroy() {
this.removeSensor()
viewer.entities.remove(this.entity)

View File

@ -11,7 +11,7 @@ import 'normalize.css'
import 'virtual:windi.css'
import './js/polylineTrail.js'
import './js/Wave.js'
import './js/Beam.js'
import Loading from '@/components/Loading/Loading'
// import { Viewer } from "cesium";

View File

@ -94,19 +94,19 @@ const useGantt = ({ router, route }: GanttParams) => {
lineWidth: 1,
lineDash: [4, 2],
},
scales: getTimeScales('month'),
scales: getTimeScales('day'),
},
minDate: '2023-11-14',
minDate: '2024-11-14',
maxDate: '2024-12-30',
markLine: [
// {
// date: '2024-07-29',
// style: {
// lineWidth: 1,
// lineColor: 'blue',
// lineDash: [8, 4],
// },
// },
{
date: '2024-07-29',
style: {
lineWidth: 1,
lineColor: 'blue',
lineDash: [8, 4],
},
},
// {
// date: '2024-08-17',
// style: {

View File

@ -1,4 +1,3 @@
import { defineExpose } from 'vue'
import {
NDataTable,
NButton,

View File

@ -3,6 +3,7 @@ import { difference } from 'lodash'
import { useEntity } from '@/hooks/entity'
import { useTree } from '@/utils/tree'
import { getSatellite } from '@/api/Satellite'
import { Beam } from '@/js/Beam'
// import CreateFrustum from '@/js/Sensor'
@ -21,7 +22,8 @@ const { filterTreeNodeByField } = useTree()
const satelliteList = ref<ISatellite[]>([])
const checkedKeys = ref<Array<string | number>>([])
const { satelliteMap, showOrHideLoad, satellitePayloadShowMap } = useEntity()
const { mubiaoMap, satelliteMap, satelliteBeamMap, satellitePayloadShowMap } =
useEntity()
const showPoint = ref(true)
function showPointUnderSat(id?: string) {
@ -72,6 +74,8 @@ export function useSatellite() {
(satellite.sensorAngle = satPayload.detectingPayload.angle)
satPayload.detectingPayload.show && (satellite.sensor = true)
}
createSatelliteCommunicationPayload(id)
}, 1000)
// viewer.clock.multiplier = 100
@ -119,6 +123,54 @@ export function useSatellite() {
}
}
function createSatelliteCommunicationPayload(satId: string) {
if (
!satelliteMap.has(satId) ||
!satellitePayloadShowMap.get(satId)?.communicationPayload ||
satellitePayloadShowMap.get(satId)?.communicationPayload?.show
) {
return
}
removeSatelliteCommunicationPayload(satId)
// console.log(satellitePayloadShowMap.get(id)?.communicationPayload)
satellitePayloadShowMap
.get(satId)
?.communicationPayload?.target.forEach((mbId: string) => {
console.log(mbId, 'mbId')
if (mubiaoMap.has(mbId)) {
const beam = new Beam({
topEntity: satelliteMap.get(satId),
bottomEntity: mubiaoMap.get(mbId),
})
beam.create()
console.log(beam)
if (!satelliteBeamMap.has(satId)) {
satelliteBeamMap.set(satId, new Map())
}
const beamMap = satelliteBeamMap.get(satId)
beamMap.set(mbId, beam)
}
})
}
function removeSatelliteCommunicationPayload(satId: string) {
if (!satelliteBeamMap.has(satId)) {
return
}
const beamMap = satelliteBeamMap.get(satId)
;[...beamMap.keys()].forEach((mbId: string) => {
beamMap.get(mbId)?.remove()
beamMap.delete(mbId)
})
satelliteBeamMap.delete(satId)
}
// function filterTreeNodeByField({
// treeData,
// params,
@ -175,7 +227,7 @@ function getAllNodesToPayload() {
? { ...detectingPayload, show: detectingShow }
: null,
communicationPayload: communicationPayload
? { ...communicationPayload, show: communicationShow }
? { target: communicationPayload, show: communicationShow }
: null,
})
}