新增载荷的删除、和俯仰角辐射距离等参数、修改轨迹曲线、jb分类和颜色等
11
package-lock.json
generated
@ -21,6 +21,7 @@
|
|||||||
"chroma-js": "^3.1.2",
|
"chroma-js": "^3.1.2",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
|
"es-toolkit": "^1.32.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"maplibre-gl": "^5.0.1",
|
"maplibre-gl": "^5.0.1",
|
||||||
"moment-timezone": "^0.5.46",
|
"moment-timezone": "^0.5.46",
|
||||||
@ -10047,6 +10048,16 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"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": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.24.2",
|
"version": "0.24.2",
|
||||||
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.24.2.tgz",
|
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.24.2.tgz",
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"chroma-js": "^3.1.2",
|
"chroma-js": "^3.1.2",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
|
"es-toolkit": "^1.32.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"maplibre-gl": "^5.0.1",
|
"maplibre-gl": "^5.0.1",
|
||||||
"moment-timezone": "^0.5.46",
|
"moment-timezone": "^0.5.46",
|
||||||
|
@ -24,21 +24,27 @@ window['settings'] = {
|
|||||||
model: './models/雷达.glb',
|
model: './models/雷达.glb',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mbCountryDict: {
|
||||||
|
美国: '#fff',
|
||||||
|
中国: '#d00',
|
||||||
|
日本: '#dd0',
|
||||||
|
韩国: '#00d',
|
||||||
|
},
|
||||||
mbDict: {
|
mbDict: {
|
||||||
甲: {
|
甲: {
|
||||||
icon: './images/icons/飞机.png',
|
icon: './images/icons/10-7600-0-侦察机.svg',
|
||||||
color: '#d00',
|
color: '#d00',
|
||||||
model: './models/IDF.glb',
|
model: './models/IDF.glb',
|
||||||
payload: 'conic',
|
payload: 'airplaneConic',
|
||||||
},
|
},
|
||||||
乙: {
|
乙: {
|
||||||
icon: './images/icons/舰船.png',
|
icon: './images/icons/10-5900-0-航空母舰.svg',
|
||||||
color: '#dd0',
|
color: '#ff0',
|
||||||
model: './models/驱逐舰2.glb',
|
model: './models/驱逐舰2.glb',
|
||||||
payload: 'radar',
|
payload: 'radar',
|
||||||
},
|
},
|
||||||
丙: {
|
丙: {
|
||||||
icon: './images/icons/舰船.png',
|
icon: './images/icons/10-6100-0-驱逐舰.svg',
|
||||||
color: '#dd0',
|
color: '#dd0',
|
||||||
model: './models/驱逐舰2.glb',
|
model: './models/驱逐舰2.glb',
|
||||||
payload: 'radar',
|
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 }
|
return { points, posArray, timeArray }
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMBEntityOpt({
|
async function getMBEntityOpt({
|
||||||
id,
|
id,
|
||||||
targetType,
|
targetType,
|
||||||
|
country,
|
||||||
extendInfo,
|
extendInfo,
|
||||||
}: {
|
}: {
|
||||||
id: string
|
id: string
|
||||||
targetType: string
|
targetType: string
|
||||||
|
country: string
|
||||||
extendInfo?: { detectingPayload: Record<string, number> }
|
extendInfo?: { detectingPayload: Record<string, number> }
|
||||||
}) {
|
}) {
|
||||||
const mubiaoDict = window.settings.mbDict[targetType]
|
const mubiaoDict = window.settings.mbDict[targetType]
|
||||||
|
const countryColor = window.settings.mbCountryDict[country]
|
||||||
|
|
||||||
|
// console.log(country, countryColor)
|
||||||
let ellipsoid
|
let ellipsoid
|
||||||
if (extendInfo) {
|
if (extendInfo) {
|
||||||
const {
|
const {
|
||||||
@ -98,7 +102,7 @@ function getMBEntityOpt({
|
|||||||
maximumClock,
|
maximumClock,
|
||||||
radius,
|
radius,
|
||||||
} = extendInfo.detectingPayload
|
} = extendInfo.detectingPayload
|
||||||
if (radius) {
|
if (maximumClock || minimumClock || minimumCone) {
|
||||||
ellipsoid = {
|
ellipsoid = {
|
||||||
ellipsoid: {
|
ellipsoid: {
|
||||||
show: mbPayloadShowMap.get(id)?.detectingPayload?.show || false,
|
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 {
|
return {
|
||||||
label: {
|
label: {
|
||||||
text: `${id}`,
|
text: `${id}`,
|
||||||
font: '12pt sans-serif',
|
font: '12pt sans-serif',
|
||||||
fillColor: Cesium.Color.YELLOW,
|
fillColor: Cesium.Color.fromCssColorString(countryColor),
|
||||||
|
// fillColor: Cesium.Color.YELLOW,
|
||||||
outlineColor: Cesium.Color.BLACK,
|
outlineColor: Cesium.Color.BLACK,
|
||||||
outlineWidth: 2,
|
outlineWidth: 2,
|
||||||
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
@ -141,10 +151,12 @@ function getMBEntityOpt({
|
|||||||
},
|
},
|
||||||
billboard: {
|
billboard: {
|
||||||
show: !iconOrModel.value,
|
show: !iconOrModel.value,
|
||||||
image: mubiaoDict.icon,
|
image: image.img,
|
||||||
width: 30,
|
// image: mubiaoDict.icon,
|
||||||
height: 30,
|
width: 35,
|
||||||
color: Cesium.Color.fromCssColorString(mubiaoDict.color),
|
height: (+image.height / +image.width) * 35,
|
||||||
|
// height: 30,
|
||||||
|
color: Cesium.Color.fromCssColorString(countryColor),
|
||||||
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
|
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
|
||||||
},
|
},
|
||||||
model: {
|
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({
|
function createMBConicSensor({
|
||||||
entity,
|
entity,
|
||||||
angle,
|
angle,
|
||||||
show,
|
show,
|
||||||
|
radius,
|
||||||
|
heading,
|
||||||
|
pitch,
|
||||||
}: {
|
}: {
|
||||||
entity: Cesium.Entity
|
entity: Cesium.Entity
|
||||||
angle: number
|
angle: number
|
||||||
show: boolean
|
show: boolean
|
||||||
|
radius: number
|
||||||
|
heading: number
|
||||||
|
pitch: number
|
||||||
}) {
|
}) {
|
||||||
console.log('entity', angle)
|
console.log('entity', angle, radius, heading, pitch)
|
||||||
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
|
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
|
||||||
show,
|
show,
|
||||||
radius: 2e7,
|
radius: radius * 1000,
|
||||||
innerHalfAngle: 0,
|
innerHalfAngle: 0,
|
||||||
outerHalfAngle: Cesium.Math.toRadians(angle / 2),
|
outerHalfAngle: Cesium.Math.toRadians(angle / 2),
|
||||||
minimumClockAngle: 0,
|
minimumClockAngle: 0,
|
||||||
@ -186,9 +243,11 @@ function createMBConicSensor({
|
|||||||
Cesium.Transforms.headingPitchRollQuaternion(
|
Cesium.Transforms.headingPitchRollQuaternion(
|
||||||
entity.position._value,
|
entity.position._value,
|
||||||
new Cesium.HeadingPitchRoll(
|
new Cesium.HeadingPitchRoll(
|
||||||
Cesium.Math.toRadians(90),
|
// Cesium.Math.toRadians(heading),
|
||||||
0,
|
Cesium.Math.toRadians(heading),
|
||||||
Cesium.Math.toRadians(180)
|
Cesium.Math.toRadians(pitch),
|
||||||
|
0
|
||||||
|
// Cesium.Math.toRadians(pitch)
|
||||||
) // 初始朝向
|
) // 初始朝向
|
||||||
),
|
),
|
||||||
conicSensor: conicSensor,
|
conicSensor: conicSensor,
|
||||||
@ -214,7 +273,7 @@ watch([mbPayloadShowMap, satellitePayloadShowMap], ([newMb, newSatellite]) => {
|
|||||||
show = newMb.get(key).detectingPayload.show
|
show = newMb.get(key).detectingPayload.show
|
||||||
}
|
}
|
||||||
if (mubiaoMap.has(key)) {
|
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)
|
mubiaoMap.get(key).ellipsoid && (mubiaoMap.get(key).ellipsoid.show = show)
|
||||||
|
|
||||||
mubiaoConicMap.get(key)?.conicSensor &&
|
mubiaoConicMap.get(key)?.conicSensor &&
|
||||||
@ -237,6 +296,7 @@ function changeShowOrHideLoad() {
|
|||||||
// ;[...mubiaoMap.values()].forEach(entity => {
|
// ;[...mubiaoMap.values()].forEach(entity => {
|
||||||
// entity.ellipsoid.show = !entity.ellipsoid.show._value
|
// entity.ellipsoid.show = !entity.ellipsoid.show._value
|
||||||
// })
|
// })
|
||||||
|
console.log(showOrHideLoad.value)
|
||||||
for (const [key] of mbPayloadShowMap.entries()) {
|
for (const [key] of mbPayloadShowMap.entries()) {
|
||||||
mbPayloadShowMap.get(key).detectingPayload.show = showOrHideLoad.value
|
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.entity = null
|
||||||
this._underPoint = false
|
this._underPoint = false
|
||||||
this.underPointEntity = null
|
this.underPointEntity = null
|
||||||
|
this._sensorRadius = 200
|
||||||
this._sensorAngle = 30
|
this._sensorAngle = 30
|
||||||
this._sensorType = 'conic'
|
this._sensorType = 'conic'
|
||||||
this._listener = null
|
this._listener = null
|
||||||
@ -38,11 +39,13 @@ class SatelliteEntity {
|
|||||||
set sensor(showSensor) {
|
set sensor(showSensor) {
|
||||||
// console.log(showSensor, 'showSensor')
|
// console.log(showSensor, 'showSensor')
|
||||||
this._sensor = showSensor
|
this._sensor = showSensor
|
||||||
if (showSensor && !this.sensorEntity) {
|
if (showSensor) {
|
||||||
if (this._sensorType === 'conic') {
|
if (!this.sensorEntity) {
|
||||||
this.createConicSensor(this.entity)
|
if (this._sensorType === 'conic') {
|
||||||
} else if (this._sensorType === 'rectangle') {
|
this.createConicSensor(this.entity)
|
||||||
this.createRectangleSensor(this.entity)
|
} else if (this._sensorType === 'rectangle') {
|
||||||
|
this.createRectangleSensor(this.entity)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if(this.sensorEntity) {
|
// if(this.sensorEntity) {
|
||||||
@ -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() {
|
get underPoint() {
|
||||||
return this._underPoint
|
return this._underPoint
|
||||||
}
|
}
|
||||||
@ -353,7 +366,7 @@ class SatelliteEntity {
|
|||||||
)
|
)
|
||||||
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
|
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
|
||||||
show: true,
|
show: true,
|
||||||
radius: 2e7,
|
radius: this._sensorRadius * 1000,
|
||||||
innerHalfAngle: 0,
|
innerHalfAngle: 0,
|
||||||
outerHalfAngle: Cesium.Math.toRadians(this._sensorAngle / 2),
|
outerHalfAngle: Cesium.Math.toRadians(this._sensorAngle / 2),
|
||||||
minimumClockAngle: 0,
|
minimumClockAngle: 0,
|
||||||
|
@ -11,6 +11,7 @@ import 'normalize.css'
|
|||||||
import 'virtual:windi.css'
|
import 'virtual:windi.css'
|
||||||
|
|
||||||
import './js/polylineTrail.js'
|
import './js/polylineTrail.js'
|
||||||
|
import './js/Wave.js'
|
||||||
|
|
||||||
import Loading from '@/components/Loading/Loading'
|
import Loading from '@/components/Loading/Loading'
|
||||||
// import { Viewer } from "cesium";
|
// import { Viewer } from "cesium";
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { lineString, bezierSpline } from '@turf/turf'
|
||||||
|
|
||||||
export function cartesian32LonLat(cartesian3) {
|
export function cartesian32LonLat(cartesian3) {
|
||||||
const cartographic =
|
const cartographic =
|
||||||
viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian3)
|
viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian3)
|
||||||
@ -8,3 +10,28 @@ export function cartesian32LonLat(cartesian3) {
|
|||||||
const height = cartographic.height
|
const height = cartographic.height
|
||||||
return [lon, lat, 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' },
|
{ name: 'XW', value: 'wzbXw' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const showPanelName = ref('wx')
|
const showPanelName = ref('zb')
|
||||||
|
|
||||||
const panelList = [
|
const panelList = [
|
||||||
// {
|
// {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { ref, toRaw } from 'vue'
|
import { ref, toRaw } from 'vue'
|
||||||
import { useDaodan } from '../../ddHooks'
|
import { useDaodan } from '../../ddHooks'
|
||||||
import { cartesian32LonLat } from '@/utils/pos'
|
import { cartesian32LonLat, getPositionFromTime } from '@/utils/pos'
|
||||||
import ExplosionEffect from '@/js/Explosion'
|
import ExplosionEffect from '@/js/Explosion'
|
||||||
import { generateId } from '@/utils/id'
|
import { generateId } from '@/utils/id'
|
||||||
import store from 'store2'
|
import store from 'store2'
|
||||||
|
// import { getPositionFromTime } from '@/utils/pos'
|
||||||
// import { useDaodan } from '../../ddHooks'
|
// import { useDaodan } from '../../ddHooks'
|
||||||
|
|
||||||
const trajData = ref({
|
const trajData = ref({
|
||||||
@ -611,21 +612,21 @@ function createLine({ totalAnimationTime, startTime, positionProperty, type }) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function getPositionFromTime(startTime, pos, totalAnimationTime) {
|
// function getPositionFromTime(startTime, pos, totalAnimationTime) {
|
||||||
const points = []
|
// const points = []
|
||||||
|
|
||||||
for (let i = 0; i <= totalAnimationTime / 100; i++) {
|
// for (let i = 0; i <= totalAnimationTime / 100; i++) {
|
||||||
const time = Cesium.JulianDate.addSeconds(
|
// const time = Cesium.JulianDate.addSeconds(
|
||||||
startTime,
|
// startTime,
|
||||||
i,
|
// i,
|
||||||
new Cesium.JulianDate()
|
// new Cesium.JulianDate()
|
||||||
)
|
// )
|
||||||
const point = pos.getValue(time)
|
// const point = pos.getValue(time)
|
||||||
point && points.push(point)
|
// point && points.push(point)
|
||||||
}
|
// }
|
||||||
|
|
||||||
return points
|
// return points
|
||||||
}
|
// }
|
||||||
|
|
||||||
function modelAnimationController(controller) {
|
function modelAnimationController(controller) {
|
||||||
const { type, initVal, maxVal, fn, step, minVal, primitive } = controller
|
const { type, initVal, maxVal, fn, step, minVal, primitive } = controller
|
||||||
|
@ -52,8 +52,8 @@ const useGantt = ({ router, route }: GanttParams) => {
|
|||||||
},
|
},
|
||||||
// verticalSplitLineHighlight: {
|
// verticalSplitLineHighlight: {
|
||||||
// lineColor: 'green',
|
// lineColor: 'green',
|
||||||
// lineWidth: 3
|
// lineWidth: 3,
|
||||||
// }
|
// },
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
// backgroundColor: bgColor,
|
// backgroundColor: bgColor,
|
||||||
@ -61,11 +61,11 @@ const useGantt = ({ router, route }: GanttParams) => {
|
|||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
lineColor: textColorWithOp,
|
lineColor: textColorWithOp,
|
||||||
},
|
},
|
||||||
verticalLine: {
|
// verticalLine: {
|
||||||
lineWidth: 1,
|
// lineWidth: 1,
|
||||||
lineColor: textColorWithOp,
|
// lineColor: textColorWithOp,
|
||||||
lineDash: [4, 8],
|
// lineDash: [4, 8],
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
taskList: {
|
taskList: {
|
||||||
// backgroundColor: bgColor,
|
// backgroundColor: bgColor,
|
||||||
@ -83,21 +83,39 @@ const useGantt = ({ router, route }: GanttParams) => {
|
|||||||
timelineHeader: {
|
timelineHeader: {
|
||||||
backgroundColor: headerBgColor,
|
backgroundColor: headerBgColor,
|
||||||
colWidth: 140,
|
colWidth: 140,
|
||||||
verticalLine: {
|
// colWidth: 1040,
|
||||||
lineColor: textColorWithOp,
|
// verticalLine: {
|
||||||
lineWidth: 1,
|
// lineColor: textColorWithOp,
|
||||||
lineDash: [4, 2],
|
// lineWidth: 1,
|
||||||
},
|
// lineDash: [4, 2],
|
||||||
|
// },
|
||||||
horizontalLine: {
|
horizontalLine: {
|
||||||
lineColor: textColorWithOp,
|
lineColor: textColorWithOp,
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
lineDash: [4, 2],
|
lineDash: [4, 2],
|
||||||
},
|
},
|
||||||
scales: getTimeScales('day'),
|
scales: getTimeScales('month'),
|
||||||
},
|
},
|
||||||
minDate: '2024-11-14',
|
minDate: '2023-11-14',
|
||||||
maxDate: '2024-12-30',
|
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: {
|
scrollStyle: {
|
||||||
scrollRailColor: 'RGBA(246,246,246,0)',
|
scrollRailColor: 'RGBA(246,246,246,0)',
|
||||||
visible: 'focus',
|
visible: 'focus',
|
||||||
@ -343,10 +361,10 @@ const useGantt = ({ router, route }: GanttParams) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const day = new Text({
|
const day = new Text({
|
||||||
text:
|
text: startDate.toLocaleDateString(),
|
||||||
scale === 'day'
|
// scale === 'day'
|
||||||
? startDate.toLocaleDateString()
|
// ? startDate.toLocaleDateString()
|
||||||
: startDate.toLocaleTimeString(),
|
// : startDate.toLocaleTimeString(),
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
fontFamily: 'sans-serif',
|
fontFamily: 'sans-serif',
|
||||||
|
@ -2,6 +2,7 @@ import { ref } from 'vue'
|
|||||||
import { point, bearing } from '@turf/turf'
|
import { point, bearing } from '@turf/turf'
|
||||||
import { cartesian32LonLat } from '@/utils/pos'
|
import { cartesian32LonLat } from '@/utils/pos'
|
||||||
import { useEntity } from '@/hooks/entity'
|
import { useEntity } from '@/hooks/entity'
|
||||||
|
import { getPositionFromTime } from '@/utils/pos'
|
||||||
|
|
||||||
type TPoints = { time: number; position: Cesium.Cartesian3 }[]
|
type TPoints = { time: number; position: Cesium.Cartesian3 }[]
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ export const useMBTrajectory = () => {
|
|||||||
removeEntities()
|
removeEntities()
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTarget(points: TPoints, posArray: number[]) {
|
async function createTarget(points: TPoints, posArray: number[]) {
|
||||||
const totalAnimationTime = points[points.length - 1].time
|
const totalAnimationTime = points[points.length - 1].time
|
||||||
// console.log('totalAnimationTime', totalAnimationTime)
|
// console.log('totalAnimationTime', totalAnimationTime)
|
||||||
|
|
||||||
@ -59,8 +60,8 @@ export const useMBTrajectory = () => {
|
|||||||
const startTime = Cesium.JulianDate.now()
|
const startTime = Cesium.JulianDate.now()
|
||||||
// 添加路径点到位置属性
|
// 添加路径点到位置属性
|
||||||
points.forEach(point => {
|
points.forEach(point => {
|
||||||
const pointEntity = createPoint(point.position)
|
// const pointEntity = createPoint(point.position)
|
||||||
entities.push(pointEntity)
|
// entities.push(pointEntity)
|
||||||
const time = Cesium.JulianDate.addSeconds(
|
const time = Cesium.JulianDate.addSeconds(
|
||||||
Cesium.JulianDate.now(),
|
Cesium.JulianDate.now(),
|
||||||
point.time,
|
point.time,
|
||||||
@ -68,13 +69,12 @@ export const useMBTrajectory = () => {
|
|||||||
)
|
)
|
||||||
positionProperty.addSample(time, point.position)
|
positionProperty.addSample(time, point.position)
|
||||||
})
|
})
|
||||||
// positionProperty.setInterpolationOptions({
|
positionProperty.setInterpolationOptions({
|
||||||
// //二次多项式进行插值。二次多项式插值相较于线性插值会更光滑,但不如高阶多项式平滑
|
interpolationDegree: 5,
|
||||||
// interpolationDegree: 2,
|
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
|
||||||
// //赫尔米特多项式插值算法。使得插值曲线能够平滑过渡,并且可以更好地控制运动的速度和方向变化
|
})
|
||||||
// interpolationAlgorithm: Cesium.HermitePolynomialApproximation,
|
console.log(positionProperty, 'getValue')
|
||||||
// })
|
// positionProperty._time.map(time => {
|
||||||
// positionProperty._time.map(time => {
|
|
||||||
// console.log(positionProperty.getValue(time), 'getValue')
|
// console.log(positionProperty.getValue(time), 'getValue')
|
||||||
// })
|
// })
|
||||||
// 获取 line 插值后的值
|
// 获取 line 插值后的值
|
||||||
@ -91,9 +91,16 @@ export const useMBTrajectory = () => {
|
|||||||
// now = Cesium.JulianDate.addSeconds(now, 30, new Cesium.JulianDate())
|
// now = Cesium.JulianDate.addSeconds(now, 30, new Cesium.JulianDate())
|
||||||
// }
|
// }
|
||||||
// console.log(linePositions)
|
// console.log(linePositions)
|
||||||
|
const positionList = getPositionFromTime(
|
||||||
const mbEntityOpt = getMBEntityOpt({
|
startTime,
|
||||||
|
positionProperty,
|
||||||
|
totalAnimationTime,
|
||||||
|
1
|
||||||
|
)
|
||||||
|
console.log(positionList, '====')
|
||||||
|
const mbEntityOpt = await getMBEntityOpt({
|
||||||
id: mbData.value.id,
|
id: mbData.value.id,
|
||||||
|
country: mbData.value.country,
|
||||||
targetType: mbData.value.targetType,
|
targetType: mbData.value.targetType,
|
||||||
})
|
})
|
||||||
// 创建实体
|
// 创建实体
|
||||||
@ -107,8 +114,8 @@ export const useMBTrajectory = () => {
|
|||||||
}, false),
|
}, false),
|
||||||
// point: { pixelSize: 10, color: Cesium.Color.RED },
|
// point: { pixelSize: 10, color: Cesium.Color.RED },
|
||||||
polyline: {
|
polyline: {
|
||||||
positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
|
// positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
|
||||||
// positions: linePositions,
|
positions: positionList,
|
||||||
width: 5,
|
width: 5,
|
||||||
// material: new Cesium.PolylineTrailLinkMaterialProperty({
|
// material: new Cesium.PolylineTrailLinkMaterialProperty({
|
||||||
// color: Cesium.Color.YELLOW,
|
// color: Cesium.Color.YELLOW,
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { getPositionFromTime } from '@/utils/pos'
|
||||||
import { useEntity } from '@/hooks/entity'
|
import { useEntity } from '@/hooks/entity'
|
||||||
|
import { useMubiao } from '../../../hooks/mubiao'
|
||||||
|
import { useTree } from '@/utils/tree'
|
||||||
|
|
||||||
type TPoints = { time: number; position: Cesium.Cartesian3 }[]
|
type TPoints = { time: number; position: Cesium.Cartesian3 }[]
|
||||||
|
|
||||||
const { mubiaoMap, showEntity, getHisTraj, getMBEntityOpt } = useEntity()
|
const { mubiaoMap, showEntity, getHisTraj, getMBEntityOpt } = useEntity()
|
||||||
const showMultiHisTrajCom = ref(false)
|
const showMultiHisTrajCom = ref(false)
|
||||||
|
|
||||||
|
const { filterTreeNodeByField, getLeafNode } = useTree()
|
||||||
|
|
||||||
export const useMultiMBTrajectory = () => {
|
export const useMultiMBTrajectory = () => {
|
||||||
let pointsEntities: Cesium.Entity[] = []
|
let pointsEntities: Cesium.Entity[] = []
|
||||||
|
|
||||||
@ -25,11 +30,17 @@ export const useMultiMBTrajectory = () => {
|
|||||||
async function loadMultiHisTraj(timeRange: string[]) {
|
async function loadMultiHisTraj(timeRange: string[]) {
|
||||||
removeEntities()
|
removeEntities()
|
||||||
|
|
||||||
|
const { data: mbTree } = useMubiao()
|
||||||
const mbIds = [...mubiaoMap.keys()]
|
const mbIds = [...mubiaoMap.keys()]
|
||||||
showEntity(false)
|
showEntity(false)
|
||||||
if (mbIds.length === 0) {
|
if (mbIds.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const nodes = filterTreeNodeByField({
|
||||||
|
treeData: mbTree.value,
|
||||||
|
params: mbIds,
|
||||||
|
paramName: 'dataId',
|
||||||
|
})
|
||||||
for (const mbId of mbIds) {
|
for (const mbId of mbIds) {
|
||||||
const { points, posArray, timeArray } = await getHisTraj({
|
const { points, posArray, timeArray } = await getHisTraj({
|
||||||
id: mbId,
|
id: mbId,
|
||||||
@ -41,8 +52,10 @@ export const useMultiMBTrajectory = () => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mbData = nodes.find(node => node.dataId === mbId).data
|
||||||
|
|
||||||
const color = Cesium.Color.fromRandom({ alpha: 1 })
|
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()
|
const allTime = [...timesMap.value.values()].flat()
|
||||||
@ -62,8 +75,9 @@ export const useMultiMBTrajectory = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTarget(
|
async function createTarget(
|
||||||
mbId: string,
|
mbId: string,
|
||||||
|
mbData: Record<string, string | number>,
|
||||||
points: TPoints,
|
points: TPoints,
|
||||||
posArray: number[],
|
posArray: number[],
|
||||||
color: Cesium.Color,
|
color: Cesium.Color,
|
||||||
@ -73,19 +87,38 @@ export const useMultiMBTrajectory = () => {
|
|||||||
// console.log('totalAnimationTime', totalAnimationTime)
|
// console.log('totalAnimationTime', totalAnimationTime)
|
||||||
const positionProperty = new Cesium.SampledPositionProperty()
|
const positionProperty = new Cesium.SampledPositionProperty()
|
||||||
// const startTime = Cesium.JulianDate.now()
|
// 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) => {
|
points.forEach((point, index) => {
|
||||||
const pointEntity = createPoint(point.position, color)
|
// const pointEntity = createPoint(point.position, color)
|
||||||
pointsEntities.push(pointEntity)
|
// pointsEntities.push(pointEntity)
|
||||||
const time = Cesium.JulianDate.fromDate(new Date(timeArray[index]))
|
const time = Cesium.JulianDate.fromDate(new Date(timeArray[index]))
|
||||||
// console.log(new Date(timeArray[index]).toLocaleString())
|
// console.log(new Date(timeArray[index]).toLocaleString())
|
||||||
positionProperty.addSample(time, point.position)
|
positionProperty.addSample(time, point.position)
|
||||||
})
|
})
|
||||||
|
positionProperty.setInterpolationOptions({
|
||||||
const mbEntityOpt = getMBEntityOpt({
|
interpolationDegree: 5,
|
||||||
id: mbId,
|
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
|
||||||
targetType: '甲',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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)
|
// console.log(mbEntityOpt)
|
||||||
// 创建实体
|
// 创建实体
|
||||||
const mbTarget = viewer.entities.add({
|
const mbTarget = viewer.entities.add({
|
||||||
@ -93,7 +126,8 @@ export const useMultiMBTrajectory = () => {
|
|||||||
position: positionProperty,
|
position: positionProperty,
|
||||||
// point: { pixelSize: 10, color: Cesium.Color.RED },
|
// point: { pixelSize: 10, color: Cesium.Color.RED },
|
||||||
polyline: {
|
polyline: {
|
||||||
positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
|
// positions: Cesium.Cartesian3.fromDegreesArrayHeights(posArray),
|
||||||
|
positions: positionList,
|
||||||
width: 5,
|
width: 5,
|
||||||
material: new Cesium.PolylineGlowMaterialProperty({
|
material: new Cesium.PolylineGlowMaterialProperty({
|
||||||
glowPower: 0.1,
|
glowPower: 0.1,
|
||||||
|
@ -76,15 +76,16 @@ export const useMubiao = () => {
|
|||||||
|
|
||||||
// console.log('mbPos', mbPos)
|
// console.log('mbPos', mbPos)
|
||||||
|
|
||||||
nodes.forEach(({ data, dataId: id }: IMubiao) => {
|
nodes.forEach(async ({ data, dataId: id }: IMubiao) => {
|
||||||
const { target_time, target_geom } =
|
const { target_time, target_geom } =
|
||||||
mbPos.find(item => item.target_id === id) ?? {}
|
mbPos.find(item => item.target_id === id) ?? {}
|
||||||
const pos = parseWKT(target_geom).coordinates
|
const pos = parseWKT(target_geom).coordinates
|
||||||
|
|
||||||
const mbEntity = addMubiaoEntity({
|
const mbEntity = await addMubiaoEntity({
|
||||||
id,
|
id,
|
||||||
position: pos,
|
position: pos,
|
||||||
target_time,
|
target_time,
|
||||||
|
country: data.country,
|
||||||
targetType: data.targetType,
|
targetType: data.targetType,
|
||||||
extendInfo: data.extendInfo,
|
extendInfo: data.extendInfo,
|
||||||
})
|
})
|
||||||
@ -101,16 +102,22 @@ export const useMubiao = () => {
|
|||||||
const res = await sendCheckedTargetIds(ids)
|
const res = await sendCheckedTargetIds(ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addMubiaoEntity = ({
|
const addMubiaoEntity = async ({
|
||||||
id,
|
id,
|
||||||
position,
|
position,
|
||||||
|
country,
|
||||||
target_time,
|
target_time,
|
||||||
targetType,
|
targetType,
|
||||||
extendInfo,
|
extendInfo,
|
||||||
}: Record<string, string | number | number[]>) => {
|
}: Record<string, string | number | number[]>) => {
|
||||||
// 添加目标实体
|
// 添加目标实体
|
||||||
// console.log(window.settings, targetType, '-----')
|
// console.log(window.settings, targetType, '-----')
|
||||||
const mbEntityOpt = getMBEntityOpt({ id, targetType, extendInfo })
|
const mbEntityOpt = await getMBEntityOpt({
|
||||||
|
id,
|
||||||
|
country,
|
||||||
|
targetType,
|
||||||
|
extendInfo,
|
||||||
|
})
|
||||||
|
|
||||||
const mubiaoEntity = viewer.entities.add({
|
const mubiaoEntity = viewer.entities.add({
|
||||||
name: id,
|
name: id,
|
||||||
@ -124,7 +131,11 @@ export const useMubiao = () => {
|
|||||||
if (extendInfo?.detectingPayload?.angle) {
|
if (extendInfo?.detectingPayload?.angle) {
|
||||||
const conic = createMBConicSensor({
|
const conic = createMBConicSensor({
|
||||||
entity: mubiaoEntity,
|
entity: mubiaoEntity,
|
||||||
|
radius: extendInfo?.detectingPayload?.radius,
|
||||||
|
|
||||||
angle: extendInfo?.detectingPayload?.angle,
|
angle: extendInfo?.detectingPayload?.angle,
|
||||||
|
heading: extendInfo?.detectingPayload?.heading,
|
||||||
|
pitch: extendInfo?.detectingPayload?.pitch,
|
||||||
show: mbPayloadShowMap.get(id).detectingPayload.show,
|
show: mbPayloadShowMap.get(id).detectingPayload.show,
|
||||||
})
|
})
|
||||||
mubiaoConicMap.set(id, conic)
|
mubiaoConicMap.set(id, conic)
|
||||||
|
@ -6,6 +6,7 @@ import Communication from '@/views/Payload/Communication.jsx'
|
|||||||
import { updateMbPayload } from '@/api/Mubiao'
|
import { updateMbPayload } from '@/api/Mubiao'
|
||||||
import { useEntity } from '@/hooks/entity'
|
import { useEntity } from '@/hooks/entity'
|
||||||
import { useMubiao } from './mubiao'
|
import { useMubiao } from './mubiao'
|
||||||
|
import { isNull, isUndefined } from 'es-toolkit'
|
||||||
|
|
||||||
const { openDetailsModal } = useModal()
|
const { openDetailsModal } = useModal()
|
||||||
export const useMubiaoDetail = () => {
|
export const useMubiaoDetail = () => {
|
||||||
@ -27,16 +28,23 @@ export const useMubiaoDetail = () => {
|
|||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
} else if (payLoadType === 'conic') {
|
} else if (payLoadType === 'airplaneConic') {
|
||||||
payloadData.value = [
|
payloadData.value = [
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
angle: null,
|
angle: 30,
|
||||||
|
radius: 10,
|
||||||
|
heading: 90,
|
||||||
|
pitch: 180,
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeCommunicationPayload() {
|
||||||
|
payloadData.value = []
|
||||||
|
}
|
||||||
const { mbPayloadShowMap } = useEntity()
|
const { mbPayloadShowMap } = useEntity()
|
||||||
|
|
||||||
function renderMubiaoDetailsContent(mbData) {
|
function renderMubiaoDetailsContent(mbData) {
|
||||||
@ -72,13 +80,21 @@ export const useMubiaoDetail = () => {
|
|||||||
*/}
|
*/}
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<div class="detail-item-title">探测载荷</div>
|
<div class="detail-item-title">探测载荷</div>
|
||||||
{payloadData.value.length === 0 && (
|
{payloadData.value.length === 0 ? (
|
||||||
<NButton
|
<NButton
|
||||||
quaternary
|
quaternary
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => addCommunicationPayload(mbData)}
|
onClick={() => addCommunicationPayload(mbData)}
|
||||||
>
|
>
|
||||||
添加
|
添加载荷
|
||||||
|
</NButton>
|
||||||
|
) : (
|
||||||
|
<NButton
|
||||||
|
quaternary
|
||||||
|
type="error"
|
||||||
|
onClick={() => removeCommunicationPayload()}
|
||||||
|
>
|
||||||
|
删除载荷
|
||||||
</NButton>
|
</NButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -113,6 +129,15 @@ export const useMubiaoDetail = () => {
|
|||||||
function updateMbLoad({ mbData, detection }) {
|
function updateMbLoad({ mbData, detection }) {
|
||||||
const { getMubiaoData } = useMubiao()
|
const { getMubiaoData } = useMubiao()
|
||||||
const { id, show, ...detectionData } = detection[0]
|
const { id, show, ...detectionData } = detection[0]
|
||||||
|
|
||||||
|
if (
|
||||||
|
Object.values(detectionData).some(
|
||||||
|
item => isNull(item) || isUndefined(item)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
window.$message.error('探测载荷信息不完整')
|
||||||
|
return
|
||||||
|
}
|
||||||
const payloadData = {
|
const payloadData = {
|
||||||
id: mbData.id,
|
id: mbData.id,
|
||||||
extendInfo: {
|
extendInfo: {
|
||||||
|
@ -83,6 +83,7 @@ export default defineComponent({
|
|||||||
<NInputNumber
|
<NInputNumber
|
||||||
v-model:value={row.radius}
|
v-model:value={row.radius}
|
||||||
// disabled={['光学', '雷达'].includes(row.type)}
|
// disabled={['光学', '雷达'].includes(row.type)}
|
||||||
|
min={0}
|
||||||
></NInputNumber>
|
></NInputNumber>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -102,22 +103,6 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
conic: [
|
conic: [
|
||||||
// {
|
|
||||||
// title: '载荷类型',
|
|
||||||
// key: 'type',
|
|
||||||
// render(row) {
|
|
||||||
// return (
|
|
||||||
// <NSelect
|
|
||||||
// v-model:value={row.type}
|
|
||||||
// options={[
|
|
||||||
// { label: '电子', value: '电子' },
|
|
||||||
// { label: '雷达', value: '雷达' },
|
|
||||||
// { label: '光学', value: '光学' },
|
|
||||||
// ]}
|
|
||||||
// ></NSelect>
|
|
||||||
// )
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
title: '开合角',
|
title: '开合角',
|
||||||
key: 'angle',
|
key: 'angle',
|
||||||
@ -127,41 +112,83 @@ export default defineComponent({
|
|||||||
v-model:value={row.angle}
|
v-model:value={row.angle}
|
||||||
max={120}
|
max={120}
|
||||||
min={0}
|
min={0}
|
||||||
// disabled={['光学', '雷达'].includes(row.type)}
|
|
||||||
></NInputNumber>
|
></NInputNumber>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// title: '水平半角',
|
title: '辐射距离(km)',
|
||||||
// key: 'xHalfAngle',
|
key: 'radius',
|
||||||
// width: 120,
|
render(row) {
|
||||||
// render(row) {
|
return (
|
||||||
// return (
|
<NInputNumber v-model:value={row.radius} min={0}></NInputNumber>
|
||||||
// <NInputNumber
|
)
|
||||||
// v-model:value={row.angle}
|
},
|
||||||
// max={120}
|
},
|
||||||
// min={0}
|
{
|
||||||
// disabled={['电子'].includes(row.type)}
|
title: '是否开启',
|
||||||
// ></NInputNumber>
|
key: 'show',
|
||||||
// )
|
width: 120,
|
||||||
// },
|
render(row) {
|
||||||
// },
|
return (
|
||||||
// {
|
<NSwitch
|
||||||
// title: '垂直半角',
|
v-model:value={row.show}
|
||||||
// key: 'yHalfAngle',
|
onUpdate:value={() => changePayloadStatus(row)}
|
||||||
// width: 120,
|
></NSwitch>
|
||||||
// render(row) {
|
)
|
||||||
// return (
|
},
|
||||||
// <NInputNumber
|
},
|
||||||
// v-model:value={row.angle}
|
],
|
||||||
// max={120}
|
airplaneConic: [
|
||||||
// min={0}
|
{
|
||||||
// disabled={['电子'].includes(row.type)}
|
title: '开合角',
|
||||||
// ></NInputNumber>
|
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: '是否开启',
|
title: '是否开启',
|
||||||
key: 'show',
|
key: 'show',
|
||||||
|
@ -6,6 +6,8 @@ import Communication from '@/views/Payload/Communication.jsx'
|
|||||||
import { useEntity } from '@/hooks/entity'
|
import { useEntity } from '@/hooks/entity'
|
||||||
import { updateSatellitePayload } from '@/api/Satellite'
|
import { updateSatellitePayload } from '@/api/Satellite'
|
||||||
import { useSatellite } from '../hooks/satellite'
|
import { useSatellite } from '../hooks/satellite'
|
||||||
|
import { isNull, isUndefined } from 'es-toolkit'
|
||||||
|
|
||||||
const { openDetailsModal } = useModal()
|
const { openDetailsModal } = useModal()
|
||||||
|
|
||||||
export function showDetailsSatellite(option) {
|
export function showDetailsSatellite(option) {
|
||||||
@ -16,9 +18,13 @@ export function showDetailsSatellite(option) {
|
|||||||
detectingPayload.value.push({
|
detectingPayload.value.push({
|
||||||
id,
|
id,
|
||||||
angle: null,
|
angle: null,
|
||||||
|
radius: null,
|
||||||
show: false,
|
show: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
function removeDetectingPayload() {
|
||||||
|
detectingPayload.value = []
|
||||||
|
}
|
||||||
const communicationPayload = ref([])
|
const communicationPayload = ref([])
|
||||||
function addCommunicationPayload() {
|
function addCommunicationPayload() {
|
||||||
communicationPayload.value.push({
|
communicationPayload.value.push({
|
||||||
@ -27,12 +33,16 @@ export function showDetailsSatellite(option) {
|
|||||||
show: false,
|
show: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
function removeCommunicationPayload() {
|
||||||
|
detectingPayload.value = []
|
||||||
|
}
|
||||||
|
|
||||||
const { satellitePayloadShowMap } = useEntity()
|
const { satellitePayloadShowMap } = useEntity()
|
||||||
if (extendInfo?.detectingPayload) {
|
if (extendInfo?.detectingPayload) {
|
||||||
detectingPayload.value.push({
|
detectingPayload.value.push({
|
||||||
id,
|
id,
|
||||||
angle: extendInfo.detectingPayload.angle,
|
angle: extendInfo.detectingPayload.angle,
|
||||||
|
radius: extendInfo.detectingPayload.radius,
|
||||||
show: satellitePayloadShowMap.get(id).detectingPayload.show,
|
show: satellitePayloadShowMap.get(id).detectingPayload.show,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -63,9 +73,13 @@ export function showDetailsSatellite(option) {
|
|||||||
{/* <div class="detail-item-title">探测载荷</div> */}
|
{/* <div class="detail-item-title">探测载荷</div> */}
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<div class="detail-item-title">探测载荷</div>
|
<div class="detail-item-title">探测载荷</div>
|
||||||
{detectingPayload.value.length === 0 && (
|
{detectingPayload.value.length === 0 ? (
|
||||||
<NButton quaternary type="primary" onClick={addDetectingPayload}>
|
<NButton quaternary type="primary" onClick={addDetectingPayload}>
|
||||||
添加
|
添加载荷
|
||||||
|
</NButton>
|
||||||
|
) : (
|
||||||
|
<NButton quaternary type="error" onClick={removeDetectingPayload}>
|
||||||
|
删除载荷
|
||||||
</NButton>
|
</NButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -78,13 +92,21 @@ export function showDetailsSatellite(option) {
|
|||||||
)}
|
)}
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<div class="detail-item-title">通信载荷</div>
|
<div class="detail-item-title">通信载荷</div>
|
||||||
{communicationPayload.value.length === 0 && (
|
{communicationPayload.value.length === 0 ? (
|
||||||
<NButton
|
<NButton
|
||||||
quaternary
|
quaternary
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={addCommunicationPayload}
|
onClick={addCommunicationPayload}
|
||||||
>
|
>
|
||||||
添加
|
添加载荷
|
||||||
|
</NButton>
|
||||||
|
) : (
|
||||||
|
<NButton
|
||||||
|
quaternary
|
||||||
|
type="error"
|
||||||
|
onClick={removeCommunicationPayload}
|
||||||
|
>
|
||||||
|
删除载荷
|
||||||
</NButton>
|
</NButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -115,6 +137,18 @@ function updateSatelliteLoad({ sat: sateData, detection, communication }) {
|
|||||||
if (!detection[0] && !communication[0]) {
|
if (!detection[0] && !communication[0]) {
|
||||||
return
|
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 { getSatelliteList } = useSatellite()
|
||||||
const payloadData = {
|
const payloadData = {
|
||||||
id: sateData.id,
|
id: sateData.id,
|
||||||
|
@ -66,6 +66,8 @@ export function useSatellite() {
|
|||||||
// satellite.sensorType = Math.random() > 0.5 ? 'conic' : 'rectangle'
|
// satellite.sensorType = Math.random() > 0.5 ? 'conic' : 'rectangle'
|
||||||
const satPayload = satellitePayloadShowMap.get(id)
|
const satPayload = satellitePayloadShowMap.get(id)
|
||||||
if (satPayload && satPayload.detectingPayload) {
|
if (satPayload && satPayload.detectingPayload) {
|
||||||
|
satPayload.detectingPayload.radius &&
|
||||||
|
(satellite.sensorRadius = satPayload.detectingPayload.radius)
|
||||||
satPayload.detectingPayload.angle &&
|
satPayload.detectingPayload.angle &&
|
||||||
(satellite.sensorAngle = satPayload.detectingPayload.angle)
|
(satellite.sensorAngle = satPayload.detectingPayload.angle)
|
||||||
satPayload.detectingPayload.show && (satellite.sensor = true)
|
satPayload.detectingPayload.show && (satellite.sensor = true)
|
||||||
|