新增载荷的删除、和俯仰角辐射距离等参数、修改轨迹曲线、jb分类和颜色等
11
package-lock.json
generated
@ -21,6 +21,7 @@
|
||||
"chroma-js": "^3.1.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^5.5.1",
|
||||
"es-toolkit": "^1.32.0",
|
||||
"lodash": "^4.17.21",
|
||||
"maplibre-gl": "^5.0.1",
|
||||
"moment-timezone": "^0.5.46",
|
||||
@ -10047,6 +10048,16 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/es-toolkit": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-toolkit/-/es-toolkit-1.32.0.tgz",
|
||||
"integrity": "sha512-ZfSfHP1l6ubgW/B/FRtqb9bYdMvI6jizbOSfbwwJNcOQ1QE6TFsC3jpQkZ900uUPSR3t3SU5Ds7UWKnYz+uP8Q==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"docs",
|
||||
"benchmarks"
|
||||
]
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.24.2",
|
||||
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.24.2.tgz",
|
||||
|
@ -24,6 +24,7 @@
|
||||
"chroma-js": "^3.1.2",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^5.5.1",
|
||||
"es-toolkit": "^1.32.0",
|
||||
"lodash": "^4.17.21",
|
||||
"maplibre-gl": "^5.0.1",
|
||||
"moment-timezone": "^0.5.46",
|
||||
|
@ -24,21 +24,27 @@ window['settings'] = {
|
||||
model: './models/雷达.glb',
|
||||
},
|
||||
},
|
||||
mbCountryDict: {
|
||||
美国: '#fff',
|
||||
中国: '#d00',
|
||||
日本: '#dd0',
|
||||
韩国: '#00d',
|
||||
},
|
||||
mbDict: {
|
||||
甲: {
|
||||
icon: './images/icons/飞机.png',
|
||||
icon: './images/icons/10-7600-0-侦察机.svg',
|
||||
color: '#d00',
|
||||
model: './models/IDF.glb',
|
||||
payload: 'conic',
|
||||
payload: 'airplaneConic',
|
||||
},
|
||||
乙: {
|
||||
icon: './images/icons/舰船.png',
|
||||
color: '#dd0',
|
||||
icon: './images/icons/10-5900-0-航空母舰.svg',
|
||||
color: '#ff0',
|
||||
model: './models/驱逐舰2.glb',
|
||||
payload: 'radar',
|
||||
},
|
||||
丙: {
|
||||
icon: './images/icons/舰船.png',
|
||||
icon: './images/icons/10-6100-0-驱逐舰.svg',
|
||||
color: '#dd0',
|
||||
model: './models/驱逐舰2.glb',
|
||||
payload: 'radar',
|
||||
|
BIN
public/images/icons/10-5900-0-航空母舰.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
1
public/images/icons/10-5900-0-航空母舰.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="756" height="352" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.5"><path fill="rgb(255, 102, 102)" stroke="#f66" stroke-width="0" opacity="1" d="M 278 40 L 280 52 L 728 52 L 728 308 L 282 308 L 280 314 L 274 312 L 28 178 L 278 40 Z M 280 84 L 280 162 L 282 164 L 696 164 L 696 86 L 694 84 L 280 84 Z M 242 96 L 96 178 L 248 260 L 248 98 L 242 96 Z M 280 196 L 280 274 L 282 276 L 696 276 L 696 198 L 694 196 L 280 196 Z "></path></svg>
|
After Width: | Height: | Size: 496 B |
BIN
public/images/icons/10-6000-0-巡洋舰.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
1
public/images/icons/10-6000-0-巡洋舰.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="756" height="352" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.5"><path fill="rgb(255, 102, 102)" stroke="#f66" stroke-width="0" opacity="1" d="M 278 44 L 280 56 L 728 56 L 728 312 L 282 312 L 280 318 L 274 316 L 28 182 L 278 44 Z M 280 88 L 280 278 L 282 280 L 304 280 L 304 90 L 302 88 L 280 88 Z M 336 88 L 336 280 L 696 280 L 696 88 L 336 88 Z M 242 100 L 96 182 L 248 264 L 248 102 L 242 100 Z "></path></svg>
|
After Width: | Height: | Size: 476 B |
BIN
public/images/icons/10-6100-0-驱逐舰.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
1
public/images/icons/10-6100-0-驱逐舰.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="756" height="364" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.5"><path fill="rgb(255, 102, 102)" stroke="#f66" stroke-width="0" opacity="1" d="M 278 48 L 280 60 L 728 60 L 728 316 L 282 316 L 280 322 L 274 320 L 28 186 L 278 48 Z M 280 92 L 280 284 L 696 284 L 696 92 L 280 92 Z M 242 104 L 96 186 L 248 268 L 248 106 L 242 104 Z "></path></svg>
|
After Width: | Height: | Size: 408 B |
BIN
public/images/icons/10-6200-0-护卫舰.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
public/images/icons/10-7200-0-歼击机.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
1
public/images/icons/10-7200-0-歼击机.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="408" height="564" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.5"><path fill="rgb(255, 102, 102)" stroke="#f66" stroke-width="0" opacity="1" d="M 184 28 L 214 28 L 216 30 L 216 170 L 372 326 L 350 348 L 216 218 L 216 470 L 260 518 L 238 536 L 202 500 L 166 536 L 144 518 L 184 474 L 184 222 L 54 348 L 32 326 L 184 174 L 184 28 Z "></path></svg>
|
After Width: | Height: | Size: 407 B |
BIN
public/images/icons/10-7400-0-轰炸机.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
public/images/icons/10-7600-0-侦察机.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
1
public/images/icons/10-7600-0-侦察机.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="408" height="520" version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version 1.2.5"><path fill="rgb(255, 102, 102)" stroke="#f66" stroke-width="0" opacity="1" d="M 184 28 L 214 28 L 216 30 L 216 170 L 372 326 L 350 348 L 216 218 L 216 458 L 232 460 L 232 492 L 172 492 L 172 460 L 184 458 L 184 222 L 54 348 L 32 326 L 184 174 L 184 28 Z "></path></svg>
|
After Width: | Height: | Size: 397 B |
@ -77,17 +77,21 @@ async function getHisTraj({
|
||||
return { points, posArray, timeArray }
|
||||
}
|
||||
|
||||
function getMBEntityOpt({
|
||||
async function getMBEntityOpt({
|
||||
id,
|
||||
targetType,
|
||||
country,
|
||||
extendInfo,
|
||||
}: {
|
||||
id: string
|
||||
targetType: string
|
||||
country: string
|
||||
extendInfo?: { detectingPayload: Record<string, number> }
|
||||
}) {
|
||||
const mubiaoDict = window.settings.mbDict[targetType]
|
||||
const countryColor = window.settings.mbCountryDict[country]
|
||||
|
||||
// console.log(country, countryColor)
|
||||
let ellipsoid
|
||||
if (extendInfo) {
|
||||
const {
|
||||
@ -98,7 +102,7 @@ function getMBEntityOpt({
|
||||
maximumClock,
|
||||
radius,
|
||||
} = extendInfo.detectingPayload
|
||||
if (radius) {
|
||||
if (maximumClock || minimumClock || minimumCone) {
|
||||
ellipsoid = {
|
||||
ellipsoid: {
|
||||
show: mbPayloadShowMap.get(id)?.detectingPayload?.show || false,
|
||||
@ -122,11 +126,17 @@ function getMBEntityOpt({
|
||||
}
|
||||
}
|
||||
}
|
||||
const image = await getImageByColor({
|
||||
img: mubiaoDict.icon,
|
||||
color: countryColor,
|
||||
})
|
||||
// console.log(image.img, (+image.height / +image.width) * 30)
|
||||
return {
|
||||
label: {
|
||||
text: `${id}`,
|
||||
font: '12pt sans-serif',
|
||||
fillColor: Cesium.Color.YELLOW,
|
||||
fillColor: Cesium.Color.fromCssColorString(countryColor),
|
||||
// fillColor: Cesium.Color.YELLOW,
|
||||
outlineColor: Cesium.Color.BLACK,
|
||||
outlineWidth: 2,
|
||||
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||
@ -141,10 +151,12 @@ function getMBEntityOpt({
|
||||
},
|
||||
billboard: {
|
||||
show: !iconOrModel.value,
|
||||
image: mubiaoDict.icon,
|
||||
width: 30,
|
||||
height: 30,
|
||||
color: Cesium.Color.fromCssColorString(mubiaoDict.color),
|
||||
image: image.img,
|
||||
// image: mubiaoDict.icon,
|
||||
width: 35,
|
||||
height: (+image.height / +image.width) * 35,
|
||||
// height: 30,
|
||||
color: Cesium.Color.fromCssColorString(countryColor),
|
||||
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
|
||||
},
|
||||
model: {
|
||||
@ -157,19 +169,64 @@ function getMBEntityOpt({
|
||||
}
|
||||
}
|
||||
|
||||
async function getImageByColor({ img: url, color: newColor }) {
|
||||
// 步骤 1: 获取 SVG 内容
|
||||
const svg = await fetch(url)
|
||||
const svgContent = await svg.text()
|
||||
|
||||
// 步骤 2: 修改 SVG 的颜色
|
||||
const parser = new DOMParser()
|
||||
const svgDoc = parser.parseFromString(svgContent, 'image/svg+xml')
|
||||
|
||||
// 修改所有路径、圆形、矩形等元素的填充颜色
|
||||
const elements = svgDoc.querySelectorAll('path, circle, rect, polygon, line')
|
||||
elements.forEach(element => {
|
||||
// 修改 fill 属性
|
||||
element.setAttribute('fill', newColor)
|
||||
// 也可以修改 stroke 颜色,防止可能的边框颜色问题
|
||||
element.setAttribute('stroke', newColor)
|
||||
})
|
||||
|
||||
const svgElement = svgDoc.documentElement
|
||||
// console.log(svgElement)
|
||||
|
||||
// const transformValue = `rotate(${90}, 50, 50)`
|
||||
// svgElement.setAttribute('transform', transformValue)
|
||||
|
||||
// 获取 SVG 的宽度和高度
|
||||
const width = svgElement.getAttribute('width')
|
||||
const height = svgElement.getAttribute('height')
|
||||
|
||||
// 步骤 3: 转换为 Base64 编码
|
||||
const serializer = new XMLSerializer()
|
||||
const modifiedSVG = serializer.serializeToString(svgDoc.documentElement)
|
||||
|
||||
// 输出修改后的 SVG,确保颜色正确
|
||||
const base64SVG = 'data:image/svg+xml;base64,' + btoa(modifiedSVG)
|
||||
|
||||
console.log(base64SVG)
|
||||
return { img: base64SVG, width, height }
|
||||
}
|
||||
|
||||
function createMBConicSensor({
|
||||
entity,
|
||||
angle,
|
||||
show,
|
||||
radius,
|
||||
heading,
|
||||
pitch,
|
||||
}: {
|
||||
entity: Cesium.Entity
|
||||
angle: number
|
||||
show: boolean
|
||||
radius: number
|
||||
heading: number
|
||||
pitch: number
|
||||
}) {
|
||||
console.log('entity', angle)
|
||||
console.log('entity', angle, radius, heading, pitch)
|
||||
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
|
||||
show,
|
||||
radius: 2e7,
|
||||
radius: radius * 1000,
|
||||
innerHalfAngle: 0,
|
||||
outerHalfAngle: Cesium.Math.toRadians(angle / 2),
|
||||
minimumClockAngle: 0,
|
||||
@ -186,9 +243,11 @@ function createMBConicSensor({
|
||||
Cesium.Transforms.headingPitchRollQuaternion(
|
||||
entity.position._value,
|
||||
new Cesium.HeadingPitchRoll(
|
||||
Cesium.Math.toRadians(90),
|
||||
0,
|
||||
Cesium.Math.toRadians(180)
|
||||
// Cesium.Math.toRadians(heading),
|
||||
Cesium.Math.toRadians(heading),
|
||||
Cesium.Math.toRadians(pitch),
|
||||
0
|
||||
// Cesium.Math.toRadians(pitch)
|
||||
) // 初始朝向
|
||||
),
|
||||
conicSensor: conicSensor,
|
||||
@ -214,7 +273,7 @@ watch([mbPayloadShowMap, satellitePayloadShowMap], ([newMb, newSatellite]) => {
|
||||
show = newMb.get(key).detectingPayload.show
|
||||
}
|
||||
if (mubiaoMap.has(key)) {
|
||||
// if(console.log(mubiaoMap.get(key).ellipsoid)
|
||||
// console.log(mubiaoMap.get(key).ellipsoid)
|
||||
mubiaoMap.get(key).ellipsoid && (mubiaoMap.get(key).ellipsoid.show = show)
|
||||
|
||||
mubiaoConicMap.get(key)?.conicSensor &&
|
||||
@ -237,6 +296,7 @@ function changeShowOrHideLoad() {
|
||||
// ;[...mubiaoMap.values()].forEach(entity => {
|
||||
// entity.ellipsoid.show = !entity.ellipsoid.show._value
|
||||
// })
|
||||
console.log(showOrHideLoad.value)
|
||||
for (const [key] of mbPayloadShowMap.entries()) {
|
||||
mbPayloadShowMap.get(key).detectingPayload.show = showOrHideLoad.value
|
||||
}
|
||||
|
98
src/js/Wave.js
Normal file
@ -0,0 +1,98 @@
|
||||
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
|
||||
},
|
||||
})
|
@ -22,6 +22,7 @@ class SatelliteEntity {
|
||||
this.entity = null
|
||||
this._underPoint = false
|
||||
this.underPointEntity = null
|
||||
this._sensorRadius = 200
|
||||
this._sensorAngle = 30
|
||||
this._sensorType = 'conic'
|
||||
this._listener = null
|
||||
@ -38,12 +39,14 @@ class SatelliteEntity {
|
||||
set sensor(showSensor) {
|
||||
// console.log(showSensor, 'showSensor')
|
||||
this._sensor = showSensor
|
||||
if (showSensor && !this.sensorEntity) {
|
||||
if (showSensor) {
|
||||
if (!this.sensorEntity) {
|
||||
if (this._sensorType === 'conic') {
|
||||
this.createConicSensor(this.entity)
|
||||
} else if (this._sensorType === 'rectangle') {
|
||||
this.createRectangleSensor(this.entity)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if(this.sensorEntity) {
|
||||
this.removeSensor()
|
||||
@ -61,6 +64,16 @@ class SatelliteEntity {
|
||||
}
|
||||
}
|
||||
|
||||
get sensorRadius() {
|
||||
return this._sensorRadius
|
||||
}
|
||||
set sensorRadius(radius) {
|
||||
this._sensorRadius = radius
|
||||
if (this._sensorEntity) {
|
||||
this._sensorEntity.radius = radius * 1000
|
||||
}
|
||||
}
|
||||
|
||||
get underPoint() {
|
||||
return this._underPoint
|
||||
}
|
||||
@ -353,7 +366,7 @@ class SatelliteEntity {
|
||||
)
|
||||
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
|
||||
show: true,
|
||||
radius: 2e7,
|
||||
radius: this._sensorRadius * 1000,
|
||||
innerHalfAngle: 0,
|
||||
outerHalfAngle: Cesium.Math.toRadians(this._sensorAngle / 2),
|
||||
minimumClockAngle: 0,
|
||||
|
@ -11,6 +11,7 @@ import 'normalize.css'
|
||||
import 'virtual:windi.css'
|
||||
|
||||
import './js/polylineTrail.js'
|
||||
import './js/Wave.js'
|
||||
|
||||
import Loading from '@/components/Loading/Loading'
|
||||
// import { Viewer } from "cesium";
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { lineString, bezierSpline } from '@turf/turf'
|
||||
|
||||
export function cartesian32LonLat(cartesian3) {
|
||||
const cartographic =
|
||||
viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian3)
|
||||
@ -8,3 +10,28 @@ export function cartesian32LonLat(cartesian3) {
|
||||
const height = cartographic.height
|
||||
return [lon, lat, height]
|
||||
}
|
||||
|
||||
export function getPositionFromTime(
|
||||
startTime,
|
||||
pos,
|
||||
totalAnimationTime,
|
||||
interval = 100
|
||||
) {
|
||||
const points = []
|
||||
|
||||
for (let i = 0; i <= totalAnimationTime / interval; i++) {
|
||||
const time = Cesium.JulianDate.addSeconds(
|
||||
startTime,
|
||||
i,
|
||||
new Cesium.JulianDate()
|
||||
)
|
||||
const point = pos.getValue(time)
|
||||
point && points.push(point)
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
export function getBezierSpline(points) {
|
||||
return bezierSpline(lineString(points))
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ const types = [
|
||||
{ name: 'XW', value: 'wzbXw' },
|
||||
]
|
||||
|
||||
const showPanelName = ref('wx')
|
||||
const showPanelName = ref('zb')
|
||||
|
||||
const panelList = [
|
||||
// {
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { ref, toRaw } from 'vue'
|
||||
import { useDaodan } from '../../ddHooks'
|
||||
import { cartesian32LonLat } from '@/utils/pos'
|
||||
import { cartesian32LonLat, getPositionFromTime } from '@/utils/pos'
|
||||
import ExplosionEffect from '@/js/Explosion'
|
||||
import { generateId } from '@/utils/id'
|
||||
import store from 'store2'
|
||||
// import { getPositionFromTime } from '@/utils/pos'
|
||||
// import { useDaodan } from '../../ddHooks'
|
||||
|
||||
const trajData = ref({
|
||||
@ -611,21 +612,21 @@ function createLine({ totalAnimationTime, startTime, positionProperty, type }) {
|
||||
},
|
||||
})
|
||||
}
|
||||
function getPositionFromTime(startTime, pos, totalAnimationTime) {
|
||||
const points = []
|
||||
// function getPositionFromTime(startTime, pos, totalAnimationTime) {
|
||||
// const points = []
|
||||
|
||||
for (let i = 0; i <= totalAnimationTime / 100; i++) {
|
||||
const time = Cesium.JulianDate.addSeconds(
|
||||
startTime,
|
||||
i,
|
||||
new Cesium.JulianDate()
|
||||
)
|
||||
const point = pos.getValue(time)
|
||||
point && points.push(point)
|
||||
}
|
||||
// for (let i = 0; i <= totalAnimationTime / 100; i++) {
|
||||
// const time = Cesium.JulianDate.addSeconds(
|
||||
// startTime,
|
||||
// i,
|
||||
// new Cesium.JulianDate()
|
||||
// )
|
||||
// const point = pos.getValue(time)
|
||||
// point && points.push(point)
|
||||
// }
|
||||
|
||||
return points
|
||||
}
|
||||
// return points
|
||||
// }
|
||||
|
||||
function modelAnimationController(controller) {
|
||||
const { type, initVal, maxVal, fn, step, minVal, primitive } = controller
|
||||
|
@ -52,8 +52,8 @@ const useGantt = ({ router, route }: GanttParams) => {
|
||||
},
|
||||
// verticalSplitLineHighlight: {
|
||||
// lineColor: 'green',
|
||||
// lineWidth: 3
|
||||
// }
|
||||
// lineWidth: 3,
|
||||
// },
|
||||
},
|
||||
grid: {
|
||||
// backgroundColor: bgColor,
|
||||
@ -61,11 +61,11 @@ const useGantt = ({ router, route }: GanttParams) => {
|
||||
lineWidth: 1,
|
||||
lineColor: textColorWithOp,
|
||||
},
|
||||
verticalLine: {
|
||||
lineWidth: 1,
|
||||
lineColor: textColorWithOp,
|
||||
lineDash: [4, 8],
|
||||
},
|
||||
// verticalLine: {
|
||||
// lineWidth: 1,
|
||||
// lineColor: textColorWithOp,
|
||||
// lineDash: [4, 8],
|
||||
// },
|
||||
},
|
||||
taskList: {
|
||||
// backgroundColor: bgColor,
|
||||
@ -83,21 +83,39 @@ const useGantt = ({ router, route }: GanttParams) => {
|
||||
timelineHeader: {
|
||||
backgroundColor: headerBgColor,
|
||||
colWidth: 140,
|
||||
verticalLine: {
|
||||
lineColor: textColorWithOp,
|
||||
lineWidth: 1,
|
||||
lineDash: [4, 2],
|
||||
},
|
||||
// colWidth: 1040,
|
||||
// verticalLine: {
|
||||
// lineColor: textColorWithOp,
|
||||
// lineWidth: 1,
|
||||
// lineDash: [4, 2],
|
||||
// },
|
||||
horizontalLine: {
|
||||
lineColor: textColorWithOp,
|
||||
lineWidth: 1,
|
||||
lineDash: [4, 2],
|
||||
},
|
||||
scales: getTimeScales('day'),
|
||||
scales: getTimeScales('month'),
|
||||
},
|
||||
minDate: '2024-11-14',
|
||||
minDate: '2023-11-14',
|
||||
maxDate: '2024-12-30',
|
||||
|
||||
markLine: [
|
||||
// {
|
||||
// date: '2024-07-29',
|
||||
// style: {
|
||||
// lineWidth: 1,
|
||||
// lineColor: 'blue',
|
||||
// lineDash: [8, 4],
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// date: '2024-08-17',
|
||||
// style: {
|
||||
// lineWidth: 2,
|
||||
// lineColor: 'red',
|
||||
// lineDash: [8, 4],
|
||||
// },
|
||||
// },
|
||||
],
|
||||
scrollStyle: {
|
||||
scrollRailColor: 'RGBA(246,246,246,0)',
|
||||
visible: 'focus',
|
||||
@ -343,10 +361,10 @@ const useGantt = ({ router, route }: GanttParams) => {
|
||||
})
|
||||
|
||||
const day = new Text({
|
||||
text:
|
||||
scale === 'day'
|
||||
? startDate.toLocaleDateString()
|
||||
: startDate.toLocaleTimeString(),
|
||||
text: startDate.toLocaleDateString(),
|
||||
// scale === 'day'
|
||||
// ? startDate.toLocaleDateString()
|
||||
// : startDate.toLocaleTimeString(),
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold',
|
||||
fontFamily: 'sans-serif',
|
||||
|
@ -2,6 +2,7 @@ import { ref } from 'vue'
|
||||
import { point, bearing } from '@turf/turf'
|
||||
import { cartesian32LonLat } from '@/utils/pos'
|
||||
import { useEntity } from '@/hooks/entity'
|
||||
import { getPositionFromTime } from '@/utils/pos'
|
||||
|
||||
type TPoints = { time: number; position: Cesium.Cartesian3 }[]
|
||||
|
||||
@ -51,7 +52,7 @@ export const useMBTrajectory = () => {
|
||||
removeEntities()
|
||||
}
|
||||
|
||||
function createTarget(points: TPoints, posArray: number[]) {
|
||||
async function createTarget(points: TPoints, posArray: number[]) {
|
||||
const totalAnimationTime = points[points.length - 1].time
|
||||
// console.log('totalAnimationTime', totalAnimationTime)
|
||||
|
||||
@ -59,8 +60,8 @@ export const useMBTrajectory = () => {
|
||||
const startTime = Cesium.JulianDate.now()
|
||||
// 添加路径点到位置属性
|
||||
points.forEach(point => {
|
||||
const pointEntity = createPoint(point.position)
|
||||
entities.push(pointEntity)
|
||||
// const pointEntity = createPoint(point.position)
|
||||
// entities.push(pointEntity)
|
||||
const time = Cesium.JulianDate.addSeconds(
|
||||
Cesium.JulianDate.now(),
|
||||
point.time,
|
||||
@ -68,12 +69,11 @@ export const useMBTrajectory = () => {
|
||||
)
|
||||
positionProperty.addSample(time, point.position)
|
||||
})
|
||||
// positionProperty.setInterpolationOptions({
|
||||
// //二次多项式进行插值。二次多项式插值相较于线性插值会更光滑,但不如高阶多项式平滑
|
||||
// interpolationDegree: 2,
|
||||
// //赫尔米特多项式插值算法。使得插值曲线能够平滑过渡,并且可以更好地控制运动的速度和方向变化
|
||||
// interpolationAlgorithm: Cesium.HermitePolynomialApproximation,
|
||||
// })
|
||||
positionProperty.setInterpolationOptions({
|
||||
interpolationDegree: 5,
|
||||
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
|
||||
})
|
||||
console.log(positionProperty, 'getValue')
|
||||
// positionProperty._time.map(time => {
|
||||
// console.log(positionProperty.getValue(time), 'getValue')
|
||||
// })
|
||||
@ -91,9 +91,16 @@ export const useMBTrajectory = () => {
|
||||
// now = Cesium.JulianDate.addSeconds(now, 30, new Cesium.JulianDate())
|
||||
// }
|
||||
// console.log(linePositions)
|
||||
|
||||
const mbEntityOpt = getMBEntityOpt({
|
||||
const positionList = getPositionFromTime(
|
||||
startTime,
|
||||
positionProperty,
|
||||
totalAnimationTime,
|
||||
1
|
||||
)
|
||||
console.log(positionList, '====')
|
||||
const mbEntityOpt = await getMBEntityOpt({
|
||||
id: mbData.value.id,
|
||||
country: mbData.value.country,
|
||||
targetType: mbData.value.targetType,
|
||||
})
|
||||
// 创建实体
|
||||
@ -107,8 +114,8 @@ export const useMBTrajectory = () => {
|
||||
}, false),
|
||||
// point: { pixelSize: 10, color: Cesium.Color.RED },
|
||||
polyline: {
|
||||
positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
|
||||
// positions: linePositions,
|
||||
// positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
|
||||
positions: positionList,
|
||||
width: 5,
|
||||
// material: new Cesium.PolylineTrailLinkMaterialProperty({
|
||||
// color: Cesium.Color.YELLOW,
|
||||
|
@ -1,11 +1,16 @@
|
||||
import { ref } from 'vue'
|
||||
import { getPositionFromTime } from '@/utils/pos'
|
||||
import { useEntity } from '@/hooks/entity'
|
||||
import { useMubiao } from '../../../hooks/mubiao'
|
||||
import { useTree } from '@/utils/tree'
|
||||
|
||||
type TPoints = { time: number; position: Cesium.Cartesian3 }[]
|
||||
|
||||
const { mubiaoMap, showEntity, getHisTraj, getMBEntityOpt } = useEntity()
|
||||
const showMultiHisTrajCom = ref(false)
|
||||
|
||||
const { filterTreeNodeByField, getLeafNode } = useTree()
|
||||
|
||||
export const useMultiMBTrajectory = () => {
|
||||
let pointsEntities: Cesium.Entity[] = []
|
||||
|
||||
@ -25,11 +30,17 @@ export const useMultiMBTrajectory = () => {
|
||||
async function loadMultiHisTraj(timeRange: string[]) {
|
||||
removeEntities()
|
||||
|
||||
const { data: mbTree } = useMubiao()
|
||||
const mbIds = [...mubiaoMap.keys()]
|
||||
showEntity(false)
|
||||
if (mbIds.length === 0) {
|
||||
return
|
||||
}
|
||||
const nodes = filterTreeNodeByField({
|
||||
treeData: mbTree.value,
|
||||
params: mbIds,
|
||||
paramName: 'dataId',
|
||||
})
|
||||
for (const mbId of mbIds) {
|
||||
const { points, posArray, timeArray } = await getHisTraj({
|
||||
id: mbId,
|
||||
@ -41,8 +52,10 @@ export const useMultiMBTrajectory = () => {
|
||||
continue
|
||||
}
|
||||
|
||||
const mbData = nodes.find(node => node.dataId === mbId).data
|
||||
|
||||
const color = Cesium.Color.fromRandom({ alpha: 1 })
|
||||
createTarget(mbId, points, posArray as number[], color, timeArray)
|
||||
createTarget(mbId, mbData, points, posArray as number[], color, timeArray)
|
||||
}
|
||||
|
||||
const allTime = [...timesMap.value.values()].flat()
|
||||
@ -62,8 +75,9 @@ export const useMultiMBTrajectory = () => {
|
||||
}
|
||||
}
|
||||
|
||||
function createTarget(
|
||||
async function createTarget(
|
||||
mbId: string,
|
||||
mbData: Record<string, string | number>,
|
||||
points: TPoints,
|
||||
posArray: number[],
|
||||
color: Cesium.Color,
|
||||
@ -73,19 +87,38 @@ export const useMultiMBTrajectory = () => {
|
||||
// console.log('totalAnimationTime', totalAnimationTime)
|
||||
const positionProperty = new Cesium.SampledPositionProperty()
|
||||
// const startTime = Cesium.JulianDate.now()
|
||||
|
||||
const startTime = Cesium.JulianDate.fromDate(new Date(timeArray[0]))
|
||||
const totalAnimationTime = timeArray[timeArray.length - 1] - timeArray[0]
|
||||
|
||||
// const bezierPoints = getBezierSpline(chunk(posArray, 3))
|
||||
// console.log(bezierPoints)
|
||||
// 添加路径点到位置属性
|
||||
points.forEach((point, index) => {
|
||||
const pointEntity = createPoint(point.position, color)
|
||||
pointsEntities.push(pointEntity)
|
||||
// const pointEntity = createPoint(point.position, color)
|
||||
// pointsEntities.push(pointEntity)
|
||||
const time = Cesium.JulianDate.fromDate(new Date(timeArray[index]))
|
||||
// console.log(new Date(timeArray[index]).toLocaleString())
|
||||
positionProperty.addSample(time, point.position)
|
||||
})
|
||||
|
||||
const mbEntityOpt = getMBEntityOpt({
|
||||
id: mbId,
|
||||
targetType: '甲',
|
||||
positionProperty.setInterpolationOptions({
|
||||
interpolationDegree: 5,
|
||||
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
|
||||
})
|
||||
|
||||
console.log(mbData, 'mbData')
|
||||
const mbEntityOpt = await getMBEntityOpt({
|
||||
id: mbId,
|
||||
targetType: mbData.targetType,
|
||||
country: mbData.country,
|
||||
})
|
||||
const positionList = getPositionFromTime(
|
||||
startTime,
|
||||
positionProperty,
|
||||
totalAnimationTime,
|
||||
1000
|
||||
)
|
||||
// console.log(positionList)
|
||||
// console.log(mbEntityOpt)
|
||||
// 创建实体
|
||||
const mbTarget = viewer.entities.add({
|
||||
@ -93,7 +126,8 @@ export const useMultiMBTrajectory = () => {
|
||||
position: positionProperty,
|
||||
// point: { pixelSize: 10, color: Cesium.Color.RED },
|
||||
polyline: {
|
||||
positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
|
||||
// positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
|
||||
positions: positionList,
|
||||
width: 5,
|
||||
material: new Cesium.PolylineGlowMaterialProperty({
|
||||
glowPower: 0.1,
|
||||
|
@ -76,15 +76,16 @@ export const useMubiao = () => {
|
||||
|
||||
// console.log('mbPos', mbPos)
|
||||
|
||||
nodes.forEach(({ data, dataId: id }: IMubiao) => {
|
||||
nodes.forEach(async ({ data, dataId: id }: IMubiao) => {
|
||||
const { target_time, target_geom } =
|
||||
mbPos.find(item => item.target_id === id) ?? {}
|
||||
const pos = parseWKT(target_geom).coordinates
|
||||
|
||||
const mbEntity = addMubiaoEntity({
|
||||
const mbEntity = await addMubiaoEntity({
|
||||
id,
|
||||
position: pos,
|
||||
target_time,
|
||||
country: data.country,
|
||||
targetType: data.targetType,
|
||||
extendInfo: data.extendInfo,
|
||||
})
|
||||
@ -101,16 +102,22 @@ export const useMubiao = () => {
|
||||
const res = await sendCheckedTargetIds(ids)
|
||||
}
|
||||
|
||||
const addMubiaoEntity = ({
|
||||
const addMubiaoEntity = async ({
|
||||
id,
|
||||
position,
|
||||
country,
|
||||
target_time,
|
||||
targetType,
|
||||
extendInfo,
|
||||
}: Record<string, string | number | number[]>) => {
|
||||
// 添加目标实体
|
||||
// console.log(window.settings, targetType, '-----')
|
||||
const mbEntityOpt = getMBEntityOpt({ id, targetType, extendInfo })
|
||||
const mbEntityOpt = await getMBEntityOpt({
|
||||
id,
|
||||
country,
|
||||
targetType,
|
||||
extendInfo,
|
||||
})
|
||||
|
||||
const mubiaoEntity = viewer.entities.add({
|
||||
name: id,
|
||||
@ -124,7 +131,11 @@ export const useMubiao = () => {
|
||||
if (extendInfo?.detectingPayload?.angle) {
|
||||
const conic = createMBConicSensor({
|
||||
entity: mubiaoEntity,
|
||||
radius: extendInfo?.detectingPayload?.radius,
|
||||
|
||||
angle: extendInfo?.detectingPayload?.angle,
|
||||
heading: extendInfo?.detectingPayload?.heading,
|
||||
pitch: extendInfo?.detectingPayload?.pitch,
|
||||
show: mbPayloadShowMap.get(id).detectingPayload.show,
|
||||
})
|
||||
mubiaoConicMap.set(id, conic)
|
||||
|
@ -6,6 +6,7 @@ import Communication from '@/views/Payload/Communication.jsx'
|
||||
import { updateMbPayload } from '@/api/Mubiao'
|
||||
import { useEntity } from '@/hooks/entity'
|
||||
import { useMubiao } from './mubiao'
|
||||
import { isNull, isUndefined } from 'es-toolkit'
|
||||
|
||||
const { openDetailsModal } = useModal()
|
||||
export const useMubiaoDetail = () => {
|
||||
@ -27,16 +28,23 @@ export const useMubiaoDetail = () => {
|
||||
show: false,
|
||||
},
|
||||
]
|
||||
} else if (payLoadType === 'conic') {
|
||||
} else if (payLoadType === 'airplaneConic') {
|
||||
payloadData.value = [
|
||||
{
|
||||
id,
|
||||
angle: null,
|
||||
angle: 30,
|
||||
radius: 10,
|
||||
heading: 90,
|
||||
pitch: 180,
|
||||
show: false,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
function removeCommunicationPayload() {
|
||||
payloadData.value = []
|
||||
}
|
||||
const { mbPayloadShowMap } = useEntity()
|
||||
|
||||
function renderMubiaoDetailsContent(mbData) {
|
||||
@ -72,13 +80,21 @@ export const useMubiaoDetail = () => {
|
||||
*/}
|
||||
<div class="flex justify-between">
|
||||
<div class="detail-item-title">探测载荷</div>
|
||||
{payloadData.value.length === 0 && (
|
||||
{payloadData.value.length === 0 ? (
|
||||
<NButton
|
||||
quaternary
|
||||
type="primary"
|
||||
onClick={() => addCommunicationPayload(mbData)}
|
||||
>
|
||||
添加
|
||||
添加载荷
|
||||
</NButton>
|
||||
) : (
|
||||
<NButton
|
||||
quaternary
|
||||
type="error"
|
||||
onClick={() => removeCommunicationPayload()}
|
||||
>
|
||||
删除载荷
|
||||
</NButton>
|
||||
)}
|
||||
</div>
|
||||
@ -113,6 +129,15 @@ export const useMubiaoDetail = () => {
|
||||
function updateMbLoad({ mbData, detection }) {
|
||||
const { getMubiaoData } = useMubiao()
|
||||
const { id, show, ...detectionData } = detection[0]
|
||||
|
||||
if (
|
||||
Object.values(detectionData).some(
|
||||
item => isNull(item) || isUndefined(item)
|
||||
)
|
||||
) {
|
||||
window.$message.error('探测载荷信息不完整')
|
||||
return
|
||||
}
|
||||
const payloadData = {
|
||||
id: mbData.id,
|
||||
extendInfo: {
|
||||
|
@ -83,6 +83,7 @@ export default defineComponent({
|
||||
<NInputNumber
|
||||
v-model:value={row.radius}
|
||||
// disabled={['光学', '雷达'].includes(row.type)}
|
||||
min={0}
|
||||
></NInputNumber>
|
||||
)
|
||||
},
|
||||
@ -102,22 +103,6 @@ export default defineComponent({
|
||||
},
|
||||
],
|
||||
conic: [
|
||||
// {
|
||||
// title: '载荷类型',
|
||||
// key: 'type',
|
||||
// render(row) {
|
||||
// return (
|
||||
// <NSelect
|
||||
// v-model:value={row.type}
|
||||
// options={[
|
||||
// { label: '电子', value: '电子' },
|
||||
// { label: '雷达', value: '雷达' },
|
||||
// { label: '光学', value: '光学' },
|
||||
// ]}
|
||||
// ></NSelect>
|
||||
// )
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '开合角',
|
||||
key: 'angle',
|
||||
@ -127,41 +112,83 @@ export default defineComponent({
|
||||
v-model:value={row.angle}
|
||||
max={120}
|
||||
min={0}
|
||||
// disabled={['光学', '雷达'].includes(row.type)}
|
||||
></NInputNumber>
|
||||
)
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: '水平半角',
|
||||
// key: 'xHalfAngle',
|
||||
// width: 120,
|
||||
// render(row) {
|
||||
// return (
|
||||
// <NInputNumber
|
||||
// v-model:value={row.angle}
|
||||
// max={120}
|
||||
// min={0}
|
||||
// disabled={['电子'].includes(row.type)}
|
||||
// ></NInputNumber>
|
||||
// )
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: '垂直半角',
|
||||
// key: 'yHalfAngle',
|
||||
// width: 120,
|
||||
// render(row) {
|
||||
// return (
|
||||
// <NInputNumber
|
||||
// v-model:value={row.angle}
|
||||
// max={120}
|
||||
// min={0}
|
||||
// disabled={['电子'].includes(row.type)}
|
||||
// ></NInputNumber>
|
||||
// )
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: '辐射距离(km)',
|
||||
key: 'radius',
|
||||
render(row) {
|
||||
return (
|
||||
<NInputNumber v-model:value={row.radius} min={0}></NInputNumber>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '是否开启',
|
||||
key: 'show',
|
||||
width: 120,
|
||||
render(row) {
|
||||
return (
|
||||
<NSwitch
|
||||
v-model:value={row.show}
|
||||
onUpdate:value={() => changePayloadStatus(row)}
|
||||
></NSwitch>
|
||||
)
|
||||
},
|
||||
},
|
||||
],
|
||||
airplaneConic: [
|
||||
{
|
||||
title: '开合角',
|
||||
key: 'angle',
|
||||
render(row) {
|
||||
return (
|
||||
<NInputNumber
|
||||
v-model:value={row.angle}
|
||||
max={120}
|
||||
min={0}
|
||||
></NInputNumber>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '偏航角',
|
||||
key: 'heading',
|
||||
render(row) {
|
||||
return (
|
||||
<NInputNumber
|
||||
v-model:value={row.heading}
|
||||
max={180}
|
||||
min={-180}
|
||||
></NInputNumber>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '俯仰角',
|
||||
key: 'pitch',
|
||||
render(row) {
|
||||
return (
|
||||
<NInputNumber
|
||||
v-model:value={row.pitch}
|
||||
max={180}
|
||||
min={-180}
|
||||
></NInputNumber>
|
||||
)
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: '辐射距离(km)',
|
||||
key: 'radius',
|
||||
render(row) {
|
||||
return (
|
||||
<NInputNumber v-model:value={row.radius} min={0}></NInputNumber>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '是否开启',
|
||||
key: 'show',
|
||||
|
@ -6,6 +6,8 @@ import Communication from '@/views/Payload/Communication.jsx'
|
||||
import { useEntity } from '@/hooks/entity'
|
||||
import { updateSatellitePayload } from '@/api/Satellite'
|
||||
import { useSatellite } from '../hooks/satellite'
|
||||
import { isNull, isUndefined } from 'es-toolkit'
|
||||
|
||||
const { openDetailsModal } = useModal()
|
||||
|
||||
export function showDetailsSatellite(option) {
|
||||
@ -16,9 +18,13 @@ export function showDetailsSatellite(option) {
|
||||
detectingPayload.value.push({
|
||||
id,
|
||||
angle: null,
|
||||
radius: null,
|
||||
show: false,
|
||||
})
|
||||
}
|
||||
function removeDetectingPayload() {
|
||||
detectingPayload.value = []
|
||||
}
|
||||
const communicationPayload = ref([])
|
||||
function addCommunicationPayload() {
|
||||
communicationPayload.value.push({
|
||||
@ -27,12 +33,16 @@ export function showDetailsSatellite(option) {
|
||||
show: false,
|
||||
})
|
||||
}
|
||||
function removeCommunicationPayload() {
|
||||
detectingPayload.value = []
|
||||
}
|
||||
|
||||
const { satellitePayloadShowMap } = useEntity()
|
||||
if (extendInfo?.detectingPayload) {
|
||||
detectingPayload.value.push({
|
||||
id,
|
||||
angle: extendInfo.detectingPayload.angle,
|
||||
radius: extendInfo.detectingPayload.radius,
|
||||
show: satellitePayloadShowMap.get(id).detectingPayload.show,
|
||||
})
|
||||
}
|
||||
@ -63,9 +73,13 @@ export function showDetailsSatellite(option) {
|
||||
{/* <div class="detail-item-title">探测载荷</div> */}
|
||||
<div class="flex justify-between">
|
||||
<div class="detail-item-title">探测载荷</div>
|
||||
{detectingPayload.value.length === 0 && (
|
||||
{detectingPayload.value.length === 0 ? (
|
||||
<NButton quaternary type="primary" onClick={addDetectingPayload}>
|
||||
添加
|
||||
添加载荷
|
||||
</NButton>
|
||||
) : (
|
||||
<NButton quaternary type="error" onClick={removeDetectingPayload}>
|
||||
删除载荷
|
||||
</NButton>
|
||||
)}
|
||||
</div>
|
||||
@ -78,13 +92,21 @@ export function showDetailsSatellite(option) {
|
||||
)}
|
||||
<div class="flex justify-between">
|
||||
<div class="detail-item-title">通信载荷</div>
|
||||
{communicationPayload.value.length === 0 && (
|
||||
{communicationPayload.value.length === 0 ? (
|
||||
<NButton
|
||||
quaternary
|
||||
type="primary"
|
||||
onClick={addCommunicationPayload}
|
||||
>
|
||||
添加
|
||||
添加载荷
|
||||
</NButton>
|
||||
) : (
|
||||
<NButton
|
||||
quaternary
|
||||
type="error"
|
||||
onClick={removeCommunicationPayload}
|
||||
>
|
||||
删除载荷
|
||||
</NButton>
|
||||
)}
|
||||
</div>
|
||||
@ -115,6 +137,18 @@ function updateSatelliteLoad({ sat: sateData, detection, communication }) {
|
||||
if (!detection[0] && !communication[0]) {
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
detection[0] &&
|
||||
Object.values(detection[0]).some(item => isNull(item) || isUndefined(item))
|
||||
) {
|
||||
window.$message.error('探测载荷信息不完整')
|
||||
return
|
||||
}
|
||||
if (communication[0] && communication[0].target.length > 0) {
|
||||
window.$message.error('通信载荷信息不完整')
|
||||
return
|
||||
}
|
||||
const { getSatelliteList } = useSatellite()
|
||||
const payloadData = {
|
||||
id: sateData.id,
|
||||
|
@ -66,6 +66,8 @@ export function useSatellite() {
|
||||
// satellite.sensorType = Math.random() > 0.5 ? 'conic' : 'rectangle'
|
||||
const satPayload = satellitePayloadShowMap.get(id)
|
||||
if (satPayload && satPayload.detectingPayload) {
|
||||
satPayload.detectingPayload.radius &&
|
||||
(satellite.sensorRadius = satPayload.detectingPayload.radius)
|
||||
satPayload.detectingPayload.angle &&
|
||||
(satellite.sensorAngle = satPayload.detectingPayload.angle)
|
||||
satPayload.detectingPayload.show && (satellite.sensor = true)
|
||||
|