diff --git a/package-lock.json b/package-lock.json index b5c2eb5cb..202595801 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index ce79c347f..377e4addc 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/public/baseConfig.js b/public/baseConfig.js index 9ab8ddd58..6d2aacfed 100644 --- a/public/baseConfig.js +++ b/public/baseConfig.js @@ -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', diff --git a/public/images/icons/10-5900-0-航空母舰.png b/public/images/icons/10-5900-0-航空母舰.png new file mode 100644 index 000000000..b48cfbddd Binary files /dev/null and b/public/images/icons/10-5900-0-航空母舰.png differ diff --git a/public/images/icons/10-5900-0-航空母舰.svg b/public/images/icons/10-5900-0-航空母舰.svg new file mode 100644 index 000000000..4c3e6ed65 --- /dev/null +++ b/public/images/icons/10-5900-0-航空母舰.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/icons/10-6000-0-巡洋舰.png b/public/images/icons/10-6000-0-巡洋舰.png new file mode 100644 index 000000000..28003077a Binary files /dev/null and b/public/images/icons/10-6000-0-巡洋舰.png differ diff --git a/public/images/icons/10-6000-0-巡洋舰.svg b/public/images/icons/10-6000-0-巡洋舰.svg new file mode 100644 index 000000000..61c7f3de5 --- /dev/null +++ b/public/images/icons/10-6000-0-巡洋舰.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/icons/10-6100-0-驱逐舰.png b/public/images/icons/10-6100-0-驱逐舰.png new file mode 100644 index 000000000..a941cd5b3 Binary files /dev/null and b/public/images/icons/10-6100-0-驱逐舰.png differ diff --git a/public/images/icons/10-6100-0-驱逐舰.svg b/public/images/icons/10-6100-0-驱逐舰.svg new file mode 100644 index 000000000..c45f1c636 --- /dev/null +++ b/public/images/icons/10-6100-0-驱逐舰.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/icons/10-6200-0-护卫舰.png b/public/images/icons/10-6200-0-护卫舰.png new file mode 100644 index 000000000..afa628eb3 Binary files /dev/null and b/public/images/icons/10-6200-0-护卫舰.png differ diff --git a/public/images/icons/10-7200-0-歼击机.png b/public/images/icons/10-7200-0-歼击机.png new file mode 100644 index 000000000..e6804fe50 Binary files /dev/null and b/public/images/icons/10-7200-0-歼击机.png differ diff --git a/public/images/icons/10-7200-0-歼击机.svg b/public/images/icons/10-7200-0-歼击机.svg new file mode 100644 index 000000000..a3050572b --- /dev/null +++ b/public/images/icons/10-7200-0-歼击机.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/icons/10-7400-0-轰炸机.png b/public/images/icons/10-7400-0-轰炸机.png new file mode 100644 index 000000000..5228a50fb Binary files /dev/null and b/public/images/icons/10-7400-0-轰炸机.png differ diff --git a/public/images/icons/10-7600-0-侦察机.png b/public/images/icons/10-7600-0-侦察机.png new file mode 100644 index 000000000..d2087ec85 Binary files /dev/null and b/public/images/icons/10-7600-0-侦察机.png differ diff --git a/public/images/icons/10-7600-0-侦察机.svg b/public/images/icons/10-7600-0-侦察机.svg new file mode 100644 index 000000000..7e7329db8 --- /dev/null +++ b/public/images/icons/10-7600-0-侦察机.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/hooks/entity.ts b/src/hooks/entity.ts index 3e0665981..905d01c61 100644 --- a/src/hooks/entity.ts +++ b/src/hooks/entity.ts @@ -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 } }) { 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 } diff --git a/src/js/Wave.js b/src/js/Wave.js new file mode 100644 index 000000000..efe16a8bf --- /dev/null +++ b/src/js/Wave.js @@ -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 + }, +}) diff --git a/src/js/satelliteEntity.js b/src/js/satelliteEntity.js index 03fd81b39..2cda28756 100644 --- a/src/js/satelliteEntity.js +++ b/src/js/satelliteEntity.js @@ -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,11 +39,13 @@ class SatelliteEntity { set sensor(showSensor) { // console.log(showSensor, 'showSensor') this._sensor = showSensor - if (showSensor && !this.sensorEntity) { - if (this._sensorType === 'conic') { - this.createConicSensor(this.entity) - } else if (this._sensorType === 'rectangle') { - this.createRectangleSensor(this.entity) + 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) { @@ -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, diff --git a/src/main.ts b/src/main.ts index 38a7c8e7f..45593b1ee 100644 --- a/src/main.ts +++ b/src/main.ts @@ -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"; diff --git a/src/utils/pos.js b/src/utils/pos.js index 5a4ab4666..72bb41bf3 100644 --- a/src/utils/pos.js +++ b/src/utils/pos.js @@ -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)) +} diff --git a/src/views/Content/index.vue b/src/views/Content/index.vue index f1ccb216b..c46a600d2 100644 --- a/src/views/Content/index.vue +++ b/src/views/Content/index.vue @@ -60,7 +60,7 @@ const types = [ { name: 'XW', value: 'wzbXw' }, ] -const showPanelName = ref('wx') +const showPanelName = ref('zb') const panelList = [ // { diff --git a/src/views/Daodan/components/hooks/testHooks.jsx b/src/views/Daodan/components/hooks/testHooks.jsx index bdbf14e47..c8fe6edbd 100644 --- a/src/views/Daodan/components/hooks/testHooks.jsx +++ b/src/views/Daodan/components/hooks/testHooks.jsx @@ -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 diff --git a/src/views/Gantt/components/Gantt/hooks/gantt.ts b/src/views/Gantt/components/Gantt/hooks/gantt.ts index f90fd89b8..40dbbb723 100644 --- a/src/views/Gantt/components/Gantt/hooks/gantt.ts +++ b/src/views/Gantt/components/Gantt/hooks/gantt.ts @@ -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', diff --git a/src/views/Mubiao/components/HisTrajectory/hooks/mbTraj.ts b/src/views/Mubiao/components/HisTrajectory/hooks/mbTraj.ts index 3ee43ee87..dacac24b2 100644 --- a/src/views/Mubiao/components/HisTrajectory/hooks/mbTraj.ts +++ b/src/views/Mubiao/components/HisTrajectory/hooks/mbTraj.ts @@ -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,13 +69,12 @@ export const useMBTrajectory = () => { ) positionProperty.addSample(time, point.position) }) - // positionProperty.setInterpolationOptions({ - // //二次多项式进行插值。二次多项式插值相较于线性插值会更光滑,但不如高阶多项式平滑 - // interpolationDegree: 2, - // //赫尔米特多项式插值算法。使得插值曲线能够平滑过渡,并且可以更好地控制运动的速度和方向变化 - // interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - // }) - // positionProperty._time.map(time => { + positionProperty.setInterpolationOptions({ + interpolationDegree: 5, + interpolationAlgorithm: Cesium.LagrangePolynomialApproximation, + }) + console.log(positionProperty, 'getValue') + // positionProperty._time.map(time => { // console.log(positionProperty.getValue(time), 'getValue') // }) // 获取 line 插值后的值 @@ -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, diff --git a/src/views/Mubiao/components/MultiHisTrajectory/hooks/multiMbTraj.ts b/src/views/Mubiao/components/MultiHisTrajectory/hooks/multiMbTraj.ts index 58ade1a4f..49a19c3d6 100644 --- a/src/views/Mubiao/components/MultiHisTrajectory/hooks/multiMbTraj.ts +++ b/src/views/Mubiao/components/MultiHisTrajectory/hooks/multiMbTraj.ts @@ -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, 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, diff --git a/src/views/Mubiao/hooks/mubiao.ts b/src/views/Mubiao/hooks/mubiao.ts index 66c05d15a..97675b5a3 100644 --- a/src/views/Mubiao/hooks/mubiao.ts +++ b/src/views/Mubiao/hooks/mubiao.ts @@ -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) => { // 添加目标实体 // 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) diff --git a/src/views/Mubiao/hooks/mubiaoDetail.jsx b/src/views/Mubiao/hooks/mubiaoDetail.jsx index dd17965b5..51e59caab 100644 --- a/src/views/Mubiao/hooks/mubiaoDetail.jsx +++ b/src/views/Mubiao/hooks/mubiaoDetail.jsx @@ -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 = () => { */}
探测载荷
- {payloadData.value.length === 0 && ( + {payloadData.value.length === 0 ? ( addCommunicationPayload(mbData)} > - 添加 + 添加载荷 + + ) : ( + removeCommunicationPayload()} + > + 删除载荷 )}
@@ -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: { diff --git a/src/views/Payload/Detection.jsx b/src/views/Payload/Detection.jsx index aa9a4f8a5..70adc15a8 100644 --- a/src/views/Payload/Detection.jsx +++ b/src/views/Payload/Detection.jsx @@ -83,6 +83,7 @@ export default defineComponent({ ) }, @@ -102,22 +103,6 @@ export default defineComponent({ }, ], conic: [ - // { - // title: '载荷类型', - // key: 'type', - // render(row) { - // return ( - // - // ) - // }, - // }, { title: '开合角', key: 'angle', @@ -127,41 +112,83 @@ export default defineComponent({ v-model:value={row.angle} max={120} min={0} - // disabled={['光学', '雷达'].includes(row.type)} > ) }, }, - // { - // title: '水平半角', - // key: 'xHalfAngle', - // width: 120, - // render(row) { - // return ( - // - // ) - // }, - // }, - // { - // title: '垂直半角', - // key: 'yHalfAngle', - // width: 120, - // render(row) { - // return ( - // - // ) - // }, - // }, + { + title: '辐射距离(km)', + key: 'radius', + render(row) { + return ( + + ) + }, + }, + { + title: '是否开启', + key: 'show', + width: 120, + render(row) { + return ( + changePayloadStatus(row)} + > + ) + }, + }, + ], + airplaneConic: [ + { + title: '开合角', + key: 'angle', + render(row) { + return ( + + ) + }, + }, + { + title: '偏航角', + key: 'heading', + render(row) { + return ( + + ) + }, + }, + { + title: '俯仰角', + key: 'pitch', + render(row) { + return ( + + ) + }, + }, + + { + title: '辐射距离(km)', + key: 'radius', + render(row) { + return ( + + ) + }, + }, { title: '是否开启', key: 'show', diff --git a/src/views/Satellite/components/SatDetail.jsx b/src/views/Satellite/components/SatDetail.jsx index d725a13aa..10a6e89ce 100644 --- a/src/views/Satellite/components/SatDetail.jsx +++ b/src/views/Satellite/components/SatDetail.jsx @@ -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) { {/*
探测载荷
*/}
探测载荷
- {detectingPayload.value.length === 0 && ( + {detectingPayload.value.length === 0 ? ( - 添加 + 添加载荷 + + ) : ( + + 删除载荷 )}
@@ -78,13 +92,21 @@ export function showDetailsSatellite(option) { )}
通信载荷
- {communicationPayload.value.length === 0 && ( + {communicationPayload.value.length === 0 ? ( - 添加 + 添加载荷 + + ) : ( + + 删除载荷 )}
@@ -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, diff --git a/src/views/Satellite/hooks/satellite.ts b/src/views/Satellite/hooks/satellite.ts index d9f0e6dc4..84aed587e 100644 --- a/src/views/Satellite/hooks/satellite.ts +++ b/src/views/Satellite/hooks/satellite.ts @@ -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)