dd and so on

This commit is contained in:
严争鸣 2025-02-14 16:33:28 +08:00
parent f1a9ca65ed
commit f642f0d705
37 changed files with 1344 additions and 493 deletions

7
package-lock.json generated
View File

@ -29,6 +29,7 @@
"pinia": "^2.0.28",
"satellite.js": "^5.0.0",
"seemly": "^0.3.9",
"store2": "^2.14.4",
"v-viewer": "^3.0.21",
"vanilla-js-wheel-zoom": "^9.0.4",
"viewerjs": "^1.11.7",
@ -14465,6 +14466,12 @@
"integrity": "sha512-0kGecIZNIReCSiznK3uheYB8sbstLjCZLiwcQwbmLhgHJj2gz6OnSPkVzJQCMnmEz1BQ4gPK59ylhBoEWOhGNA==",
"license": "BDS-3-Clause"
},
"node_modules/store2": {
"version": "2.14.4",
"resolved": "https://registry.npmmirror.com/store2/-/store2-2.14.4.tgz",
"integrity": "sha512-srTItn1GOvyvOycgxjAnPA63FZNwy0PTyUBFMHRM+hVFltAeoh0LmNBz9SZqUS9mMqGk8rfyWyXn3GH5ReJ8Zw==",
"license": "MIT"
},
"node_modules/stream-source": {
"version": "0.3.5",
"resolved": "https://registry.npmmirror.com/stream-source/-/stream-source-0.3.5.tgz",

View File

@ -32,6 +32,7 @@
"pinia": "^2.0.28",
"satellite.js": "^5.0.0",
"seemly": "^0.3.9",
"store2": "^2.14.4",
"v-viewer": "^3.0.21",
"vanilla-js-wheel-zoom": "^9.0.4",
"viewerjs": "^1.11.7",

BIN
public/images/影像.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 KiB

View File

@ -1,44 +1,162 @@
const sub = [
{
id: 0,
name: 'DD',
// start: '2024-11-15',
// end: '2024-11-21',
type: 'eventType',
children: [
{
id: 1,
name: '发射事件',
start: '2024-11-15',
end: '2024-11-17',
type: 'subEvent',
trajData: {},
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
},
],
},
{
id: 300,
name: '飞机',
type: 'eventType',
children: [
{
id: 5,
name: '起飞',
start: '2024-11-18',
end: '2024-11-21',
type: 'subEvent',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/rabbit.jpg',
},
],
},
{
name: '舰船',
type: 'eventType',
children: [
{
id: 6,
name: '停留',
start: '2024-11-20',
end: '2024-11-22',
type: 'subEvent',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/cat.jpg',
},
{
id: 7,
name: '扫描',
start: '2024-11-18',
end: '2024-11-19',
type: 'subEvent',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/flower.jpg',
},
],
},
{
name: '航J',
type: 'eventType',
children: [
{
id: 8,
name: '航J事件',
start: '2024-11-20',
end: '2024-11-21',
type: 'subEvent',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bear.jpg',
},
{
id: 9,
name: '航J事件-2',
start: '2024-11-22',
end: '2024-11-26',
type: 'subEvent',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
},
],
},
{
name: 'xx',
type: 'eventType',
children: [
{
id: 13,
name: 'xx-事件-1',
start: '2024-11-22',
end: '2024-11-25',
type: 'subEvent',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/rabbit.jpg',
},
{
id: 14,
name: 'xx-事件-2',
start: '2024-11-27',
end: '2024-11-30',
type: 'subEvent',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/cat.jpg',
},
],
},
]
const main = [
{
id: 0,
name: 'DD-1',
start: '2024-11-15',
end: '2024-11-21',
type: 'dd',
children: [
{
id: 1,
name: 'DD',
name: '事件1-1',
start: '2024-11-15',
end: '2024-11-17',
children: [
{
id: 122,
name: '发射',
start: '2024-11-15',
end: '2024-11-17',
type: 'DD',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
},
],
type: 'mainEvent',
// children: [
// {
// id: 122,
// name: '发射',
// start: '2024-11-15',
// end: '2024-11-17',
// type: 'DD',
// avatar:
// 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
// },
// ],
children: sub,
},
{
id: 2,
name: '飞机',
name: '事件1-2',
start: '2024-11-17',
end: '2024-11-18',
type: 'mainEvent',
},
{
id: 3,
name: '船',
name: '事件1-3',
start: '2024-11-19',
end: '2024-11-20',
type: 'mainEvent',
},
{
id: 4,
name: 'H景',
name: '事件1-4',
start: '2024-11-18',
end: '2024-11-19',
type: 'mainEvent',
},
],
},
@ -51,6 +169,7 @@ const main = [
name: '事件-2-1',
start: '2024-11-18',
end: '2024-11-21',
type: 'mainEvent',
},
],
},
@ -62,12 +181,14 @@ const main = [
name: '事件-3-1',
start: '2024-11-21',
end: '2024-11-22',
type: 'mainEvent',
},
{
id: 7,
name: '事件-3-2',
start: '2024-11-18',
end: '2024-11-19',
type: 'mainEvent',
},
],
},
@ -80,30 +201,35 @@ const main = [
name: '事件-4-1',
start: '2024-11-20',
end: '2024-11-21',
type: 'mainEvent',
},
{
id: 9,
name: '事件-4-2',
start: '2024-11-25',
end: '2024-11-26',
type: 'mainEvent',
},
{
id: 10,
name: '事件-4-3',
start: '2024-11-17',
end: '2024-11-18',
type: 'mainEvent',
},
{
id: 11,
name: '事件-4-4',
start: '2024-11-22',
end: '2024-11-25',
type: 'mainEvent',
},
{
id: 12,
name: '事件-4-5',
start: '2024-11-23',
end: '2024-11-24',
type: 'mainEvent',
},
],
},
@ -115,18 +241,21 @@ const main = [
name: '事件-5-1',
start: '2024-11-22',
end: '2024-11-25',
type: 'mainEvent',
},
{
id: 14,
name: '事件-5-2',
start: '2024-11-27',
end: '2024-11-30',
type: 'mainEvent',
},
{
id: 15,
name: '事件-5-3',
start: '2024-12-10',
end: '2024-12-18',
type: 'mainEvent',
},
],
},
@ -138,12 +267,14 @@ const main = [
name: '事件-6-1',
start: '2024-11-20',
end: '2024-11-30',
type: 'mainEvent',
},
{
id: 17,
name: '事件-6-2',
start: '2024-12-02',
end: '2024-12-18',
type: 'mainEvent',
},
],
},
@ -155,6 +286,7 @@ const main = [
name: '事件-7-1',
start: '2024-12-22',
end: '2024-12-28',
type: 'mainEvent',
},
],
},
@ -166,134 +298,14 @@ const main = [
name: '事件-8-1',
start: '2024-11-25',
end: '2024-11-30',
type: 'mainEvent',
},
{
id: 20,
name: '事件-8-2',
start: '2024-12-01',
end: '2024-12-18',
},
],
},
]
const sub = [
{
id: 0,
name: 'DD',
start: '2024-11-15',
end: '2024-11-21',
children: [
{
id: 1,
name: '发射',
start: '2024-11-15',
end: '2024-11-17',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
},
{
id: 2,
name: '脱离-1',
start: '2024-11-17',
end: '2024-11-18',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bear.jpg',
},
{
id: 3,
name: '脱离-2',
start: '2024-11-19',
end: '2024-11-20',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bear.jpg',
},
{
id: 4,
name: '落地',
start: '2024-11-21',
end: '2024-11-21',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
},
],
},
{
id: 300,
name: '飞机',
children: [
{
id: 5,
name: '起飞',
start: '2024-11-18',
end: '2024-11-21',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/rabbit.jpg',
},
],
},
{
name: '舰船',
children: [
{
id: 6,
name: '停留',
start: '2024-11-21',
end: '2024-11-22',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/cat.jpg',
},
{
id: 7,
name: '扫描',
start: '2024-11-18',
end: '2024-11-19',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/flower.jpg',
},
],
},
{
name: '航J',
children: [
{
id: 8,
name: '航J事件',
start: '2024-11-20',
end: '2024-11-21',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bear.jpg',
},
{
id: 9,
name: '航J事件-2',
start: '2024-11-25',
end: '2024-11-26',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
},
],
},
{
name: 'xx',
children: [
{
id: 13,
name: 'xx-事件-1',
start: '2024-11-22',
end: '2024-11-25',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/rabbit.jpg',
},
{
id: 14,
name: 'xx-事件-2',
start: '2024-11-27',
end: '2024-11-30',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/cat.jpg',
type: 'mainEvent',
},
],
},
@ -312,7 +324,15 @@ export function getMainGantt(data = {}) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(main)
}, 1000)
}, 200)
})
}
export function getEventListByDDType(ddType) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(main.find(item => item.name === ddType))
}, 200)
})
}
@ -320,7 +340,7 @@ export function getSubGantt(subId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(sub)
}, 1000)
}, 200)
})
}
@ -328,6 +348,6 @@ export function getTask() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(task)
}, 1000)
}, 200)
})
}

View File

@ -100,4 +100,11 @@
#textMsgContainer .n-alert {
height: 100%;
.n-base-close.n-alert__close {
z-index: inherit;
}
}
.n-dialog {
@apply bg-[#1c202cee];
}

View File

@ -13,6 +13,8 @@ export const useEntity = () => {
getMBEntityOpt,
iconOrModel,
changeIconOrModel,
showOrHideLoad,
changeShowOrHideLoad,
}
}
@ -104,7 +106,7 @@ function getMBEntityOpt({
minimumPixelSize: 50,
},
ellipsoid: {
show: true,
show: showOrHideLoad.value,
radii: new Cesium.Cartesian3(100000, 100000, 100000),
innerRadii: new Cesium.Cartesian3(1.0, 1.0, 1.0),
maximumCone: Cesium.Math.toRadians(90),
@ -133,3 +135,16 @@ function changeIconOrModel() {
entity.billboard.show = !entity.billboard.show._value
})
}
const showOrHideLoad = ref(true)
function changeShowOrHideLoad() {
showOrHideLoad.value = !showOrHideLoad.value
;[...mubiaoMap.values()].forEach(entity => {
entity.ellipsoid.show = !entity.ellipsoid.show._value
})
;[...satelliteMap.values()].forEach(satellite => {
satellite.sensor = showOrHideLoad.value
console.log(satellite)
})
}

View File

@ -14,7 +14,7 @@ function distanceMeasure() {
//贴地测量距离函数
// var terrainProvider = this.terrainProvider
// viewer.scene.globe.depthTestAgainstTerrain = true
viewer.scene.globe.depthTestAgainstTerrain = true
handler = new Cesium.ScreenSpaceEventHandler(
viewer.scene._imageryLayerCollection
@ -78,6 +78,7 @@ function distanceMeasure() {
// tooltip.style.display = "none";
bMeasuring = false
viewer._container.style.cursor = ''
viewer.scene.globe.depthTestAgainstTerrain = false
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
const PolyLinePrimitive = (function () {
@ -180,7 +181,7 @@ function distanceMeasure() {
},
label: {
text: textDistance,
font: '18px sans-serif',
font: '14px sans-serif',
fillColor: Cesium.Color.GOLD,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
@ -205,11 +206,11 @@ function angleMeasure() {
let floatingPoint //浮动点
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
handler.setInputAction(function (movement) {
let cartesian = viewer.scene.pickPosition(movement.endPosition)
if (!Cesium.defined(cartesian)) {
const ray = viewer.camera.getPickRay(movement.endPosition)
cartesian = viewer.scene.globe.pick(ray, viewer.scene)
}
// let cartesian = viewer.scene.pickPosition(movement.endPosition)
// if (!Cesium.defined(cartesian)) {
const ray = viewer.camera.getPickRay(movement.endPosition)
let cartesian = viewer.scene.globe.pick(ray, viewer.scene)
// }
//cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
if (distanceLineNum === 1) {
pArr.length = 1
@ -219,13 +220,13 @@ function angleMeasure() {
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
handler.setInputAction(function (movement) {
let cartesian = viewer.scene.pickPosition(movement.position)
// let cartesian = viewer.scene.pickPosition(movement.position)
// console.log('cartesian', cartesian32LonLat(cartesian))
if (!Cesium.defined(cartesian)) {
// console.log('false')
const ray = viewer.camera.getPickRay(movement.position)
cartesian = viewer.scene.globe.pick(ray, viewer.scene)
}
// if (!Cesium.defined(cartesian)) {
// console.log('false')
const ray = viewer.camera.getPickRay(movement.position)
let cartesian = viewer.scene.globe.pick(ray, viewer.scene)
// }
// var cartesian = viewer.scene.pickPosition(movement.position);
distanceLineNum++
@ -351,12 +352,10 @@ function angleMeasure() {
text: '角度:' + angle + '°\n距离:' + textDistance,
// scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
// translucencyByDistance: new Cesium.NearFarScalar(1.5e2, 2.0, 1.5e5, 0),
font: '24px 楷体',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
font: '14px sans-serif',
fillColor: Cesium.Color.GOLD,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
scale: 0.5,
pixelOffset: new Cesium.Cartesian2(0, -20),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
backgroundColor: new Cesium.Color.fromCssColorString(

View File

@ -43,6 +43,10 @@ class SatelliteEntity {
} else if (this._sensorType === 'rectangle') {
this.createRectangleSensor(this.entity)
}
} else {
// if(this.sensorEntity) {
this.removeSensor()
// }
}
}
@ -356,6 +360,9 @@ class SatelliteEntity {
})
this._listener = (scene, time) => {
if (!this.sensorEntity) {
return
}
conicSensor.show = false
let position = Cesium.Property.getValueOrUndefined(
satellite.position,
@ -485,6 +492,8 @@ class SatelliteEntity {
viewer.scene.primitives.remove(this.sensorEntity)
}
this.sensorEntity = null
viewer.scene.preRender.addEventListener(this._listener)
this._listener = null
}
}
destroy() {

View File

@ -1,6 +1,7 @@
export const useTree = () => {
return {
filterTreeNodeByField,
getAllKeys,
}
}
@ -22,3 +23,16 @@ function filterTreeNodeByField({ treeData, params, paramName, icon = '' }) {
return acc
}, [])
}
function getAllKeys(treeData, key) {
const data = 'value' in treeData ? treeData.value : treeData
return data.reduce((acc, node) => {
// console.log(node, '---')
acc.push(node[key])
if (node.children) {
acc = acc.concat(getAllKeys(node.children, key))
}
return acc
}, [])
}

View File

@ -24,7 +24,7 @@ export default defineComponent({
const wz = WZoom.create(`#image-${image.id}`, {
type: 'html',
maxScale: 3,
minScale: 0.2,
minScale: 1,
// zoomOnDoubleClick: true,
width: imageElement.naturalWidth,
height: imageElement.naturalHeight,

View File

@ -63,7 +63,7 @@ const getImage = async () => {
imageList.value = new Array(10).fill(1).map((item, index) => {
return {
id: index,
imgPath: `https://picsum.photos/300/200?random=${index}`,
imgPath: `/images/影像.jpg`,
imgId: index,
}
})

View File

@ -6,6 +6,7 @@ import { useTree } from '@/utils/tree'
import { parseWKT } from '@/utils/parseWKT'
import { useBasePopup } from './basePopup'
import { useEntity } from '@/hooks/entity'
// import { storeToRefs } from 'pinia'
const treeData = ref([])
@ -18,7 +19,7 @@ const allKeys = ref([])
let subscriber: Subscriber | null = null
const { filterTreeNodeByField } = useTree()
const { filterTreeNodeByField, getAllKeys } = useTree()
const { popupMap, createPopup } = useBasePopup()
@ -26,7 +27,7 @@ const isLoading = ref(false)
export const useBase = () => {
onMounted(async () => {
await getSheshiData()
allKeys.value = getAllKeys(treeData.value)
allKeys.value = getAllKeys(treeData.value, 'dataId')
})
const addBaseFacilities = (ids: Array<string | number>) => {
subscriber = new Subscriber(viewer, {
@ -221,18 +222,18 @@ function addEventSub(
// console.log(subscriber, '-------')
}
function getAllKeys(treeData: any) {
const data = 'value' in treeData ? treeData.value : treeData
// function getAllKeys(treeData: any) {
// const data = 'value' in treeData ? treeData.value : treeData
return data.reduce((acc, node) => {
// console.log(node, '---')
acc.push(node.dataId)
if (node.children) {
acc = acc.concat(getAllKeys(node.children))
}
return acc
}, [])
}
// return data.reduce((acc, node) => {
// // console.log(node, '---')
// acc.push(node.dataId)
// if (node.children) {
// acc = acc.concat(getAllKeys(node.children))
// }
// return acc
// }, [])
// }
function addEntity(data: TBaseNode) {
const { id, sheShiName, sheShiType, geom } = data
@ -257,9 +258,11 @@ function addEntity(data: TBaseNode) {
18000000,
0.4
),
// eyeOffset: new Cesium.Cartesian3(0.0, 20000.0, 0.0),
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
disableDepthTestDistance: 1000000000,
// disableDepthTestDistance: 30000000,
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
billboard: {
show: !iconOrModel.value,
@ -271,7 +274,7 @@ function addEntity(data: TBaseNode) {
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: 1000000000,
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
model: {
show: iconOrModel.value,

View File

@ -2,7 +2,7 @@ import { NIcon, NPopover } from 'naive-ui'
import { useEntity } from '@/hooks/entity'
export default defineComponent({
setup() {
const { changeIconOrModel } = useEntity()
const { showOrHideLoad, changeShowOrHideLoad } = useEntity()
return () => (
<>
<NPopover
@ -10,7 +10,10 @@ export default defineComponent({
placement="bottom"
v-slots={{
trigger: () => (
<div class="btn-class" onClick={changeIconOrModel}>
<div
class={`btn-class ${showOrHideLoad.value ? 'checked' : ''}`}
onClick={changeShowOrHideLoad}
>
<NIcon size="16">
<svg
t="1736488615012"

View File

@ -8,11 +8,11 @@ export default defineComponent({
const showOrHideTraj = show => {
// console.log(value, 'showOrHideTraj')
// if (show) {
// showTrajHour.value > 0 && getCurTraj()
// } else {
// removeAllCurTraj()
// }
if (show) {
showTrajHour.value > 0 && getCurTraj()
} else {
removeAllCurTraj()
}
}
return () => (
@ -53,7 +53,7 @@ export default defineComponent({
<span>航迹配置</span>
</NPopover>
{showTrajSet.value ? (
<div class="corner-border absolute top-10 z-30 flex w-[150px] flex-col gap-2 bg-[var(--color-bg)] p-2">
<div class="corner-border absolute top-10 z-30 flex w-[230px] flex-col gap-2 bg-[var(--color-bg)] p-2">
<div>轨迹时长</div>
<div class="flex items-center gap-2">
<NInputNumber
@ -67,12 +67,12 @@ export default defineComponent({
<NButton
type="primary"
size="small"
onClick={showOrHideTraj(true)}
onClick={() => showOrHideTraj(true)}
>
确定
显示所有航迹
</NButton>
<NButton size="small" onClick={showOrHideTraj(false)}>
关闭航迹
<NButton size="small" onClick={() => showOrHideTraj(false)}>
关闭所有航迹
</NButton>
{/* <NSwitch
// rail-style="railStyle"

View File

@ -18,7 +18,7 @@ import Daodan from '../Daodan'
import TextMessage from '../TextReport/components/Message'
import DaodanTestConfig from '../Daodan/components/TestConfig'
import DaodanTestConfig from '../Daodan/components/ConfigContainer'
// import HeatMap from '../Mubiao/components/HeatMap/index.vue'
// import TextDetailModal from '../TextReport/components/DetailsModal/index.vue'
@ -241,7 +241,7 @@ const showOrHideTextReport = () => {
<div
class="absolute bottom-0 flex h-full w-full flex-col items-center justify-end"
>
<text-message class="z-15 absolute h-[200px] w-full"></text-message>
<text-message class="absolute h-[200px] w-full"></text-message>
<mubiao-his-trajectory
v-if="showHisTrajCom"
class="z-30 h-[260px] w-full"

View File

@ -0,0 +1,25 @@
import { NTabs, NTabPane, NButton, NScrollbar } from 'naive-ui'
import TrajTable from './TrajTable'
import TrajUpload from './TrajUpload'
import Panel from '@/components/Panel/index.vue'
import { useDaodan } from '../ddHooks'
import TestConfig from './TestConfig'
import { useTestConfig } from './hooks/testHooks'
export default defineComponent({
name: 'ConfigContainer',
props: {},
setup() {
const { daodanData } = useDaodan()
return () => (
<div>
<Panel title={`${daodanData.value.name}试验配置`}>
<div class="flex h-full w-full flex-col gap-2 p-2">
<TestConfig />
</div>
</Panel>
</div>
)
},
})

View File

@ -9,15 +9,20 @@ const panels = ['手动配置', 'STK轨迹文件配置']
export default defineComponent({
setup() {
const { daodanData, showOrHideDdConfig } = useDaodan()
const { trajData, interceptData, addIntercept, initDaodan } =
const { trajData, interceptData, loadStoreData, addIntercept, initDaodan } =
useTestConfig()
watch(daodanData, newval => {
loadStoreData()
// console.log(newval, '-=----')
})
const name = ref('手动配置')
const handleClose = () => {}
// const handleClose = () => {}
const confirm = () => {
showOrHideDdConfig({})
initDaodan()
showOrHideDdConfig({})
}
const removeIntercept = id => {
@ -27,67 +32,67 @@ export default defineComponent({
)
}
return () => (
<div>
<Panel title={`${daodanData.value.name}试验配置`}>
<div class="flex h-full w-full flex-col gap-2 p-2">
<NTabs
class="flex h-[calc(100%-42px)] flex-col"
v-model:value={name.value}
type="card"
tab-style="min-width: 80px;"
onClose={handleClose}
// <div>
// <Panel title={`${daodanData.value.name}`}>
<div class="flex h-full w-full flex-col gap-2 p-2">
<NTabs
class="flex h-[calc(100%-42px)] flex-col"
v-model:value={name.value}
type="card"
tab-style="min-width: 80px;"
// onClose={handleClose}
>
{panels.map(panel => (
<NTabPane
class="flex-1 overflow-y-auto rounded-b-[var(--n-tab-border-radius)] border border-[var(--n-tab-border-color)] border-t-transparent"
key={panel}
tab={panel}
name={panel}
>
{panels.map(panel => (
<NTabPane
class="flex-1 overflow-y-auto rounded-b-[var(--n-tab-border-radius)] border border-[var(--n-tab-border-color)] border-t-transparent"
key={panel}
tab={panel}
name={panel}
>
<NScrollbar>
<div class="px-4 pb-4">
<div class="detail-container">
{panel === '手动配置' ? (
<>
<div class="rounded border border-blue-500 p-4">
<TrajTable title="轨迹点" data={trajData.value} />
</div>
<div class="flex flex-col gap-4 rounded border border-red-500 p-4">
{interceptData.value.map(data => (
<TrajTable
title="拦截"
data={data}
onRemoveIntercept={removeIntercept}
/>
))}
<div>
<NButton type="primary" onClick={addIntercept}>
添加拦截
</NButton>
</div>
</div>
</>
) : (
<>
<TrajUpload title="轨迹点" />
<TrajUpload title="拦截" />
</>
)}
</div>
</div>
</NScrollbar>
</NTabPane>
))}
</NTabs>
<div class="flex justify-end gap-2">
<NButton type="primary" onClick={confirm}>
确认
</NButton>
<NButton onClick={() => showOrHideDdConfig({})}>取消</NButton>
</div>
</div>
</Panel>
<NScrollbar>
<div class="px-4 pb-4">
<div class="detail-container">
{panel === '手动配置' ? (
<>
<div class="rounded border border-blue-500 p-4">
<TrajTable title="轨迹点" data={trajData.value} />
</div>
<div class="flex flex-col gap-4 rounded border border-red-500 p-4">
{interceptData.value.map(data => (
<TrajTable
title="拦截"
data={data}
onRemoveIntercept={removeIntercept}
/>
))}
<div>
<NButton type="primary" onClick={addIntercept}>
添加拦截
</NButton>
</div>
</div>
</>
) : (
<>
<TrajUpload title="轨迹点" />
<TrajUpload title="拦截" />
</>
)}
</div>
</div>
</NScrollbar>
</NTabPane>
))}
</NTabs>
<div class="flex justify-end gap-2">
<NButton type="primary" onClick={confirm}>
确认
</NButton>
<NButton onClick={() => showOrHideDdConfig({})}>取消</NButton>
</div>
</div>
// </Panel>
// </div>
)
},
})

View File

@ -21,6 +21,10 @@ export default defineComponent({
type: Object,
default: () => ({}),
},
showPosIcon: {
type: Boolean,
default: true,
},
},
setup(props, { emit }) {
const { handleClickPoint } = useTestConfig()
@ -35,35 +39,37 @@ export default defineComponent({
return (
<div class="flex items-center justify-between gap-2">
<div>{row.name} </div>
<NButton
// quaternary
// type="primary"
size="tiny"
v-slots={{
icon: () => (
<NIcon size="14">
<svg
t="1737444618400"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2312"
width="64"
height="64"
>
<path
d="M512 42.688c23.616 0 42.688 19.072 42.688 42.624v31.488c0 32.32 24.32 58.88 55.296 68.16a342.08 342.08 0 0 1 229.12 229.12c9.216 30.912 35.84 55.232 68.096 55.232h31.488a42.688 42.688 0 0 1 0 85.376h-31.488c-32.256 0-58.88 24.32-68.096 55.232a342.08 342.08 0 0 1-229.12 229.12c-30.976 9.28-55.232 35.84-55.296 68.16v31.488a42.688 42.688 0 0 1-85.312 0v-31.488c0-32.256-24.32-58.88-55.296-68.096a342.08 342.08 0 0 1-229.12-229.12c-9.28-30.976-35.84-55.296-68.096-55.296h-31.488a42.688 42.688 0 0 1 0-85.376h31.424c32.32 0 58.88-24.32 68.16-55.232a342.08 342.08 0 0 1 229.12-229.12c30.976-9.28 55.296-35.84 55.296-68.16v-31.424c0-23.616 19.072-42.688 42.624-42.688zM512 256a256 256 0 1 0 0 512 256 256 0 0 0 0-512z m0 170.688a85.312 85.312 0 1 1 0 170.624 85.312 85.312 0 0 1 0-170.624z"
p-id="2313"
></path>
</svg>
</NIcon>
),
}}
onClick={() => {
handleClickPoint(row)
}}
/>
{props.showPosIcon && (
<NButton
// quaternary
// type="primary"
size="tiny"
v-slots={{
icon: () => (
<NIcon size="14">
<svg
t="1737444618400"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2312"
width="64"
height="64"
>
<path
d="M512 42.688c23.616 0 42.688 19.072 42.688 42.624v31.488c0 32.32 24.32 58.88 55.296 68.16a342.08 342.08 0 0 1 229.12 229.12c9.216 30.912 35.84 55.232 68.096 55.232h31.488a42.688 42.688 0 0 1 0 85.376h-31.488c-32.256 0-58.88 24.32-68.096 55.232a342.08 342.08 0 0 1-229.12 229.12c-30.976 9.28-55.232 35.84-55.296 68.16v31.488a42.688 42.688 0 0 1-85.312 0v-31.488c0-32.256-24.32-58.88-55.296-68.096a342.08 342.08 0 0 1-229.12-229.12c-9.28-30.976-35.84-55.296-68.096-55.296h-31.488a42.688 42.688 0 0 1 0-85.376h31.424c32.32 0 58.88-24.32 68.16-55.232a342.08 342.08 0 0 1 229.12-229.12c30.976-9.28 55.296-35.84 55.296-68.16v-31.424c0-23.616 19.072-42.688 42.624-42.688zM512 256a256 256 0 1 0 0 512 256 256 0 0 0 0-512z m0 170.688a85.312 85.312 0 1 1 0 170.624 85.312 85.312 0 0 1 0-170.624z"
p-id="2313"
></path>
</svg>
</NIcon>
),
}}
onClick={() => {
handleClickPoint(row)
}}
/>
)}
</div>
)
},

View File

@ -3,6 +3,8 @@ import { useDaodan } from '../../ddHooks'
import { cartesian32LonLat } from '@/utils/pos'
import ExplosionEffect from '@/js/Explosion'
import { generateId } from '@/utils/id'
import store from 'store2'
// import { useDaodan } from '../../ddHooks'
const trajData = ref({
id: 'dd',
@ -36,7 +38,7 @@ const trajData = ref({
lat: 21,
alt: 2000000,
time: 1183135280000,
detached: false,
detached: true,
},
{
name: '落点',
@ -76,17 +78,45 @@ const interceptData = ref([
],
},
])
const { daodanData, showDdConfigCom } = useDaodan()
export function useTestConfig() {
return {
trajData,
interceptData,
loadStoreData,
addIntercept,
addFeaturePoint,
handleClickPoint,
initDaodan,
}
}
function saveDataToStore() {
const daodanDataRaw = toRaw(daodanData.value)
const storeData = store.get('daodanData')
store.set('daodanData', {
...storeData,
[daodanDataRaw.id]: {
...daodanDataRaw,
trajData: trajData.value,
interceptData: interceptData.value,
},
})
}
function loadStoreData() {
const storeData = store.get('daodanData')
if (storeData) {
const daodanDataRaw = toRaw(daodanData.value)
const data = storeData[daodanDataRaw.id]
if (data) {
trajData.value = data.trajData
interceptData.value = data.interceptData
}
}
}
function addIntercept() {
// d
interceptData.value.push({
@ -107,31 +137,22 @@ function addIntercept() {
time: 1183135260000,
detached: false,
},
{
name: '落点',
lon: 120,
lat: 21,
alt: 0,
time: 1183135260000,
},
trajData.value.data.at(-1),
],
})
}
function addFeaturePoint() {
//
}
let handler = null
function handleClickPoint(rowData) {
const { showDdConfigCom } = useDaodan()
//
// console.log(rowData)
showDdConfigCom.value = false
viewer._container.style.cursor = 'crosshair'
handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas)
handler.setInputAction(movement => {
const cartesian = viewer.scene.pickPosition(movement.position)
// const cartesian = viewer.scene.pickPosition(movement.position)
const ray = viewer.camera.getPickRay(movement.position)
const cartesian = viewer.scene.globe.pick(ray, viewer.scene)
const position = cartesian32LonLat(cartesian)
// console.log(position)
viewer._container.style.cursor = ''
@ -144,7 +165,8 @@ function handleClickPoint(rowData) {
let nodes = []
let ddMap = new Map()
function addDaodan(id, ddTrajData, type = 0) {
function addDaodan(trajData, type = 0) {
const { id, data: ddTrajData } = trajData
const position = Cesium.Cartesian3.fromDegrees(
ddTrajData[0].lon,
ddTrajData[0].lat,
@ -194,26 +216,28 @@ function addDaodan(id, ddTrajData, type = 0) {
model.getNode(i._name).show = false
}
})
computePath(ddPrimitive, ddTrajData, type)
computePath(ddPrimitive, trajData, type)
// setTimeout(() => {
playDaodan(ddPrimitive, nodes)
// playDaodan(ddPrimitive, nodes)
// }, 3000)
})
}
let minTime = 0
function initDaodan() {
minTime = getMinTime([
...toRaw(trajData.value.data),
...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity),
])
// console.log(minTime)
addDaodan(trajData.value.id, trajData.value.data)
interceptData.value.forEach(item => {
const { id, data } = item
addDaodan(id, data, 1)
})
saveDataToStore()
// minTime = getMinTime([
// ...toRaw(trajData.value.data),
// ...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity),
// ])
// // console.log(minTime)
// addDaodan(trajData.value)
// aniIndexMap.set(trajData.value.id, 0)
// interceptData.value.forEach(item => {
// const { id, data } = item
// addDaodan(item, 1)
// aniIndexMap.set(id, 0)
// })
}
function getMinTime(data) {
@ -224,106 +248,14 @@ function getMinTime(data) {
return minTime
}
function playDaodan(daodan, nodes) {
modelAnimationController({
primitive: daodan,
type: 'BoosterFlames Size',
initVal: 0,
maxVal: 1,
step: 0.1,
fn: () => {
console.log('1------BoosterFlames Size')
},
})
setTimeout(() => {
modelAnimationController({
primitive: daodan,
type: 'BoosterFlames Size',
initVal: 1,
minVal: 0,
step: -0.05,
fn: () => {
console.log('2------BoosterFlames Size')
},
})
modelAnimationController({
primitive: daodan,
type: 'Booster MoveZ',
initVal: 0,
minVal: -150,
step: -1,
fn: () => {
console.log(nodes, '=======')
console.log('3------Booster MoveZ')
nodes.forEach(i => {
const nodeName = i._name
// new RegExp(/Fairing\d/).test(nodeName) ||
if (new RegExp(/Booster/).test(nodeName)) {
daodan.getNode(nodeName).show = false
}
})
},
})
modelAnimationController({
primitive: daodan,
type: 'UpperStageFlames Size',
initVal: 0,
maxVal: 1,
step: 0.05,
fn: () => {
console.log('4------UpperStageFlames Size')
},
})
}, 2000)
setTimeout(() => {
modelAnimationController({
primitive: daodan,
type: 'InterstageAdapter MoveZ',
initVal: 0,
minVal: -150,
step: -1,
fn: () => {
console.log('5------InterstageAdapter MoveZ')
nodes.forEach(i => {
const nodeName = i._name
if (new RegExp(/InterstageAdapter/).test(nodeName)) {
console.log(daodan.getNode(nodeName))
daodan.getNode(nodeName).show = false
}
})
},
})
}, 4000)
setTimeout(() => {
modelAnimationController({
primitive: daodan,
type: 'UpperStageFlames Size',
initVal: 1,
maxVal: 0,
step: -0.05,
fn: () => {
console.log('6------UpperStageFlames Size')
modelAnimationController({
primitive: daodan,
type: 'UpperStage MoveZ',
initVal: 0,
minVal: -150,
step: -1,
})
},
})
}, 6000)
}
function computePath(daodan, ddTrajData, type) {
function computePath(daodan, trajData, type) {
const { data: ddTrajData } = trajData
const points = ddTrajData.map(item => {
const { time, lon, lat, alt } = item
const { time, lon, lat, alt, detached } = item
return {
position: Cesium.Cartesian3.fromDegrees(lon, lat, alt),
time: time - minTime,
detached,
}
})
const totalAnimationTime = points.at(-1).time
@ -347,21 +279,32 @@ function computePath(daodan, ddTrajData, type) {
positionProperty.addSample(time, point.position)
})
positionProperty.setInterpolationOptions({
interpolationDegree: 5,
interpolationDegree: 2,
interpolationAlgorithm: Cesium.HermitePolynomialApproximation,
// interpolationDegree: 5,
// interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
})
createLine({ totalAnimationTime, startTime, positionProperty, type })
daodanAnimation({ totalAnimationTime, startTime, positionProperty, daodan })
daodanAnimation({
totalAnimationTime,
startTime,
positionProperty,
daodan,
trajData,
})
}
function daodanAnimation(params) {
const { totalAnimationTime, startTime, positionProperty, daodan } = params
const { totalAnimationTime, startTime, positionProperty, daodan, trajData } =
params
// const { data: ddTrajData } = trajData
dianhuo(daodan)
let lastFrameTime = performance.now()
let customElapsedTime = 0
let isAnimationRunning = true
let explosion = null
viewer.scene.preRender.addEventListener(() => {
if (!isAnimationRunning) {
return
@ -374,6 +317,11 @@ function daodanAnimation(params) {
customElapsedTime = totalAnimationTime //
isAnimationRunning = false //
}
ddNodesAnimationController({
ddPrimitive: daodan,
curTime: minTime + customElapsedTime * 1000,
trajData,
})
//
const customTime = Cesium.JulianDate.addSeconds(
@ -424,6 +372,197 @@ function daodanAnimation(params) {
}
})
}
function dianhuo(ddPrimitive) {
modelAnimationController({
primitive: ddPrimitive,
type: 'BoosterFlames Size',
initVal: 0,
maxVal: 1,
step: 0.1,
fn: () => {
console.log('%c点火', 'color: red;font-size: 20px;border: 1px solid red')
},
})
}
const aniIndexMap = new Map()
function ddNodesAnimationController(params) {
const { ddPrimitive, curTime, trajData } = params
const { id: ddId, data: ddTrajData } = trajData
const nodeAniList = ddTrajData.filter(item => item.detached)
// console.log(
// curTime,
// aniIndex,
// nodeAniList[aniIndex].time,
// curTime >= nodeAniList[aniIndex].time,
// 'curTime'
// )
if (!ddPrimitive || !aniIndexMap.has(ddId)) return
const aniIndex = aniIndexMap.get(ddId)
const aniTime = nodeAniList[aniIndex]?.time || Infinity
if (curTime >= aniTime) {
if (aniIndex === 0) {
aniIndexMap.set(ddId, aniIndexMap.get(ddId) + 1)
modelAnimationController({
primitive: ddPrimitive,
type: 'BoosterFlames Size',
initVal: 1,
minVal: 0,
step: -0.05,
fn: function () {
console.log(
`%c${ddId}--熄火`,
'color: red;font-size: 20px;border: 1px solid red'
)
modelAnimationController({
primitive: ddPrimitive,
type: 'UpperStageFlames Size',
initVal: 0,
maxVal: 1,
step: 0.05,
fn: () => {
console.log(
`%c${ddId}--二级点火`,
'color: red;font-size: 20px;border: 1px solid red'
)
},
})
modelAnimationController({
primitive: ddPrimitive,
type: 'Booster MoveZ',
initVal: 0,
minVal: -450,
step: -3,
fn: () => {
console.log(
`%c${ddId}--一级脱离`,
'color: red;font-size: 20px;border: 1px solid red'
)
nodes.forEach(i => {
const nodeName = i._name
if (new RegExp(/Booster/).test(nodeName)) {
ddPrimitive.getNode(nodeName).show = false
}
})
},
})
modelAnimationController({
primitive: ddPrimitive,
type: 'Booster MoveY',
initVal: 0,
minVal: -15,
step: -0.1,
})
},
})
} else if (aniIndex === 1) {
aniIndexMap.set(ddId, aniIndexMap.get(ddId) + 1)
modelAnimationController({
primitive: ddPrimitive,
type: 'Fairing Open',
initVal: 0,
maxVal: 45,
step: 0.5,
})
modelAnimationController({
primitive: ddPrimitive,
type: 'Fairing Separate',
initVal: 0,
minVal: -10,
step: -0.1,
})
modelAnimationController({
primitive: ddPrimitive,
type: 'Fairing Drop',
initVal: 0,
minVal: -450,
step: -3,
fn: () => {
console.log(
`%c${ddId}--二级脱离`,
'color: red;font-size: 20px;border: 1px solid red'
)
nodes.forEach(i => {
const nodeName = i._name
if (new RegExp(/Fairing\d/).test(nodeName)) {
ddPrimitive.getNode(nodeName).show = false
}
})
},
})
modelAnimationController({
primitive: ddPrimitive,
type: 'Fairing MoveY',
initVal: 0,
minVal: -150,
step: -3,
})
} else if (aniIndex === 2) {
aniIndexMap.set(ddId, aniIndexMap.get(ddId) + 1)
modelAnimationController({
primitive: ddPrimitive,
type: 'InterstageAdapter MoveZ',
initVal: 0,
minVal: -200,
step: -2,
fn: () => {
console.log(
`%c${ddId}--三级脱离`,
'color: red;font-size: 20px;border: 1px solid red'
)
nodes.forEach(i => {
const nodeName = i._name
if (new RegExp(/InterstageAdapter/).test(nodeName)) {
ddPrimitive.getNode(nodeName).show = false
}
})
},
})
modelAnimationController({
primitive: ddPrimitive,
type: 'InterstageAdapter MoveY',
initVal: 0,
minVal: -300,
step: -2,
})
modelAnimationController({
primitive: ddPrimitive,
type: 'UpperStageFlames Size',
initVal: 1,
minVal: 0,
step: -0.05,
fn: () => {
console.log(
`%c${ddId}--二级熄火`,
'color: red;font-size: 20px;border: 1px solid red'
)
// modelAnimationController({
// primitive: ddPrimitive,
// type: 'Booster MoveZ',
// initVal: 0,
// minVal: -150,
// step: -1,
// fn: () => {
// console.log(
// `%c${ddId}--`,
// 'color: red;font-size: 20px;border: 1px solid red'
// )
// },
// })
},
})
}
}
}
function getHeadingPitchRoll(curPos, nextPos) {
if (!curPos || !nextPos || Cesium.Cartesian3.equals(curPos, nextPos)) {
@ -492,14 +631,15 @@ function modelAnimationController(controller) {
const { type, initVal, maxVal, fn, step, minVal, primitive } = controller
let num = initVal
let stopFrame
const max = maxVal || 1
const min = minVal || -99999
const duration = step || 0.1
const max = maxVal ?? 1
const min = minVal ?? -99999
const duration = step ?? 0.1
const render = () => {
num += duration
primitive.setArticulationStage(type, num)
primitive.applyArticulations()
stopFrame = requestAnimationFrame(render)
// console.log(num >= max || num <= min, type, num, min)
if (num > max || num <= min) {
window.cancelAnimationFrame(stopFrame)
fn && fn()

View File

@ -1,4 +1,4 @@
import { onMounted, ref } from 'vue'
import { onMounted, ref, watch } from 'vue'
import { getDaodanTree } from '@/api/Daodan'
const isLoading = ref(false)

View File

@ -1,6 +1,7 @@
import Tree from '@/components/Tree/index.vue'
import { useDaodan } from './ddHooks'
import { NButton } from 'naive-ui'
import { useTestConfig } from './components/hooks/testHooks'
export default defineComponent({
setup() {
@ -25,6 +26,10 @@ export default defineComponent({
}
return () => (
<div class="w-h-full" v-loading={isLoading.value}>
{/* <NButton type="primary" onClick={showOrHideDdConfig}>
aaaaa
</NButton> */}
<Tree
data={treeData.value}
key-field="dataId"

View File

@ -67,13 +67,13 @@ onMounted(async () => {
},
})
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
url: 'http://192.168.10.201:2022/api/maptilecache/service/terrain/taiwan-HeightMap-4326',
// url: Cesium.IonResource.fromAssetId(3956),
// url: 'http://data.marsgis.cn/terrain',
requestVertexNormals: true,
requestWaterMask: true,
})
// viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
// url: 'http://192.168.10.201:2022/api/maptilecache/service/terrain/taiwan-HeightMap-4326',
// // url: Cesium.IonResource.fromAssetId(3956),
// // url: 'http://data.marsgis.cn/terrain',
// requestVertexNormals: true,
// requestWaterMask: true,
// })
// viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(
// 'http://192.168.10.201:2022/api/maptilecache/service/terrain/taiwan-HeightMap-4326',
@ -82,7 +82,7 @@ onMounted(async () => {
// requestWaterMask: true,
// }
// )
viewer.scene.globe.depthTestAgainstTerrain = true
// viewer.scene.globe.depthTestAgainstTerrain = true
// setTimeout(() => {
// const tooltip = new MouseTooltip(window.viewer, {
// offset: [10, -10],

View File

@ -0,0 +1,94 @@
import { NTabs, NTabPane, NButton, NScrollbar } from 'naive-ui'
import TrajTable from '@/views/Daodan/components/TrajTable'
import TrajUpload from '@/views/Daodan/components/TrajUpload'
import { useEventDdConfig } from './useEventDdConfig'
const panels = ['手动配置', 'STK轨迹文件配置']
export default defineComponent({
name: 'EventDaodan',
props: {
data: {
type: Object,
default: () => ({}),
},
},
setup() {
const name = ref('手动配置')
const { trajData, interceptData, addIntercept } = useEventDdConfig()
// const { trajData, interceptData, updateInterceptData } = useEvent()
const removeIntercept = id => {
interceptData.value.splice(
interceptData.value.findIndex(item => item.id === id),
1
)
}
const showOrHideDdConfig = () => {}
return () => (
<div class="flex h-full w-[80vw] flex-col gap-2 p-2">
<NTabs
class="flex h-[calc(100%-42px)] flex-col"
v-model:value={name.value}
type="card"
tab-style="min-width: 80px;"
>
{panels.map(panel => (
<NTabPane
class="flex-1 overflow-y-auto rounded-b-[var(--n-tab-border-radius)] border border-[var(--n-tab-border-color)] border-t-transparent"
key={panel}
tab={panel}
name={panel}
>
<NScrollbar>
<div class="px-4 pb-4">
<div class="detail-container">
{panel === '手动配置' ? (
<>
<div class="rounded border border-blue-500 p-4">
<TrajTable
title="轨迹点"
showPosIcon={false}
data={trajData.value}
/>
</div>
<div class="flex flex-col gap-4 rounded border border-red-500 p-4">
{interceptData.value.map(data => (
<TrajTable
title="拦截"
data={data}
showPosIcon={false}
onRemoveIntercept={removeIntercept}
/>
))}
<div>
<NButton type="primary" onClick={addIntercept}>
添加拦截
</NButton>
</div>
</div>
</>
) : (
<>
<TrajUpload title="轨迹点" />
<TrajUpload title="拦截" />
</>
)}
</div>
</div>
</NScrollbar>
</NTabPane>
))}
</NTabs>
<div class="flex justify-end gap-2">
<NButton type="primary" onClick={confirm}>
确认
</NButton>
<NButton onClick={() => showOrHideDdConfig({})}>取消</NButton>
</div>
</div>
)
},
})

View File

@ -0,0 +1,60 @@
import {
NForm,
NFormItem,
NInput,
NButton,
NDatePicker,
NUpload,
} from 'naive-ui'
import ModalCom from '@/components/Modal/index.vue'
import { useEvent } from '../hooks'
export default defineComponent({
// props: {
// show: {
// type: Boolean,
// default: false,
// },
// },
setup() {
const { showMainEvent, mainEventData } = useEvent()
const close = () => {
showNewEvent.value = false
}
watch(
[() => mainEventData.value.start, () => mainEventData.value.end],
([start, end]) => {
timeRange.value = start ? [start, end] : null
}
)
const timeRange = ref(null)
return () => (
<ModalCom v-model:show={showMainEvent.value} title="编辑事件">
<NForm
class="w-[500px]"
model={mainEventData}
label-placement="left"
label-width="auto"
>
<NFormItem label="事件名称" path="name">
<NInput v-model:value={mainEventData.value.name} />
</NFormItem>
<NFormItem label="事件时间" path="description">
<NDatePicker
v-model:value={timeRange.value}
type="daterange"
clearable
/>
</NFormItem>
</NForm>
<div class="flex justify-end gap-2">
<NButton onClick={close}>取消</NButton>
<NButton type="primary">确认</NButton>
</div>
</ModalCom>
)
},
})

View File

@ -0,0 +1,81 @@
import {
NForm,
NFormItem,
NInput,
NButton,
NDatePicker,
NUpload,
} from 'naive-ui'
import ModalCom from '@/components/Modal/index.vue'
import { useEvent } from '../hooks'
export default defineComponent({
// props: {
// show: {
// type: Boolean,
// default: false,
// },
// },
setup() {
const { showNewEvent, eventData } = useEvent()
const close = () => {
showNewEvent.value = false
}
watch(
[
() => eventData.value.start,
() => eventData.value.end,
() => eventData.value.avatar,
],
([start, end, avatar]) => {
timeRange.value = start ? [start, end] : null
uploadImg.value = [
{
url: avatar,
status: 'finished',
},
]
}
)
const timeRange = ref(null)
const uploadImg = ref([])
return () => (
<ModalCom
v-model:show={showNewEvent.value}
title={`${eventData.value.id ? '编辑' : '添加'}子事件`}
>
<NForm
class="w-[500px]"
model={eventData}
label-placement="left"
label-width="auto"
>
<NFormItem label="事件名称" path="name">
<NInput v-model:value={eventData.value.name} />
</NFormItem>
<NFormItem label="事件时间" path="description">
<NDatePicker
v-model:value={timeRange.value}
type="daterange"
clearable
/>
</NFormItem>
<NFormItem label="上传图片" path="avatar">
<NUpload
default-file-list={uploadImg.value}
list-type="image-card"
max={1}
/>
</NFormItem>
</NForm>
<div class="flex justify-end gap-2">
<NButton onClick={close}>取消</NButton>
<NButton type="primary">确认</NButton>
</div>
</ModalCom>
)
},
})

View File

@ -0,0 +1,103 @@
export const useEventDdConfig = () => {
const trajData = ref({
id: 'dd',
data: [
{
name: '起始点',
lon: 120,
lat: 21,
alt: 0,
time: 1183135260000,
},
{
name: '中间特征点',
lon: 122,
lat: 21,
alt: 1000000,
time: 1183135265000,
detached: true,
},
{
name: '中间特征点',
lon: 124,
lat: 21,
alt: 1500000,
time: 1183135270000,
detached: true,
},
{
name: '中间特征点',
lon: 128,
lat: 21,
alt: 2000000,
time: 1183135280000,
detached: true,
},
{
name: '落点',
lon: 135,
lat: 21,
alt: 1500000,
time: 1183135290000,
},
],
})
const interceptData = ref([
{
id: 'dd1',
data: [
{
name: '起始点',
lon: 137,
lat: 25,
alt: 0,
time: 1183135270000,
},
{
name: '中间特征点',
lon: 138,
lat: 24,
alt: 1000000,
time: 1183135280000,
detached: true,
},
{
name: '落点',
lon: 135,
lat: 21,
alt: 1500000,
time: 1183135290000,
},
],
},
])
function addIntercept() {
// d
interceptData.value.push({
data: [
{
name: '起始点',
lon: 120,
lat: 21,
alt: 0,
time: 1183135260000,
},
{
name: '中间特征点',
lon: 120,
lat: 21,
alt: 0,
time: 1183135260000,
detached: false,
},
trajData.value.data.at(-1),
],
})
}
return {
trajData,
interceptData,
addIntercept,
}
}

View File

@ -0,0 +1,29 @@
import { generateId } from '@/utils/id'
const showMainEvent = ref(false)
const mainEventData = ref({
name: '',
start: '',
end: '',
type: 'mainEvent',
})
const showNewEvent = ref(false)
const eventData = ref({
name: '',
start: '',
end: '',
avatar: '',
type: 'subEvent',
})
export const useEvent = () => {
return {
showMainEvent,
mainEventData,
showNewEvent,
eventData,
}
}

View File

@ -1,5 +1,6 @@
import { NDataTable, NIcon, NButton } from 'naive-ui'
import { getMainGantt } from '@/api/gantt'
import { NDataTable, NIcon, NButton, useDialog, NTag } from 'naive-ui'
import { getEventListByDDType } from '@/api/gantt'
import { useTree } from '@/utils/tree'
import {
HelpCircleOutline,
CreateOutline,
@ -8,19 +9,47 @@ import {
EnterOutline,
} from '@vicons/ionicons5'
import MainEventEdit from './components/MainEventEdit'
import SubEventEdit from './components/SubEventEdit'
import EventDdConfig from './components/EventDdConfig'
import { useEvent } from './hooks'
export default defineComponent({
setup() {
props: {
dd: {
type: String,
require: true,
},
},
setup(props) {
const { showMainEvent, mainEventData, showNewEvent, eventData } = useEvent()
const dict = {
mainEvent: { label: '主事件', color: 'success' },
eventType: { label: '事件分类', color: 'info' },
subEvent: { label: '子事件', color: 'warning' },
}
const columns = [
{
title: '导弹类型/事件名称',
title: '事件名称',
key: 'name',
width: 220,
width: 'auto',
render: row => {
return (
<div class="inline-flex items-center gap-2">
<NIcon>
{/* <NIcon>
<HelpCircleOutline />
</NIcon>
</NIcon> */}
<NTag
size="small"
round
bordered={false}
type={dict[row.type].color}
>
{dict[row.type].label}
</NTag>
{row.name}
</div>
)
@ -34,10 +63,22 @@ export default defineComponent({
title: '结束时间',
key: 'end',
},
{
title: '类型',
key: 'type',
},
// {
// title: '',
// key: 'type',
// render(row) {
// return (
// <NTag
// size="small"
// round
// bordered={false}
// type={dict[row.type].color}
// >
// {dict[row.type].label}
// </NTag>
// )
// },
// },
{
title: '图片',
key: 'avatar',
@ -52,37 +93,81 @@ export default defineComponent({
{
title: '操作',
key: 'action',
render(row) {
render(row, rowIndex) {
// console.log(row, rowIndex)
return (
<div class="flex justify-end">
{!row.avatar ? (
{row.type === 'mainEvent' && (
<NButton
type="primary"
size="small"
quaternary
onClick={() => editMainEvent(row)}
>
<NIcon>
<CreateOutline />
</NIcon>
编辑事件
</NButton>
)}
{row.type === 'eventType' ? (
<NButton
type="success"
size="small"
quaternary
onClick={() => handleEdit(row)}
onClick={() => addSubEvent(row)}
>
<NIcon>
<AddCircleOutline />
</NIcon>
添加子事件
</NButton>
) : null}
<NButton
type="primary"
size="small"
quaternary
onClick={() => handleEdit(row)}
>
<NIcon>
<CreateOutline />
</NIcon>
</NButton>
{row.name.indexOf('DD') === -1 ? (
{row.type === 'isDD' && (
<NButton
type="primary"
size="small"
quaternary
onClick={() => editSubEvent(row)}
>
<NIcon>
<CreateOutline />
</NIcon>
编辑子事件
</NButton>
)}
{Reflect.has(row, 'trajData') && (
<NButton
type="primary"
size="small"
quaternary
onClick={() => ddConfig(row)}
>
<NIcon>
<CreateOutline />
</NIcon>
编辑DD轨迹
</NButton>
)}
{row.type === 'subEvent' && (
<NButton
type="primary"
size="small"
quaternary
onClick={() => editSubEvent(row)}
>
<NIcon>
<CreateOutline />
</NIcon>
编辑子事件
</NButton>
)}
{row.type !== 'eventType' ? (
<NButton
type="error"
size="small"
quaternary
onClick={() => handleEdit(row)}
onClick={() => deleteEvent(row)}
>
<NIcon>
<TrashBinOutline />
@ -96,20 +181,85 @@ export default defineComponent({
},
},
]
function editMainEvent(row) {
showMainEvent.value = true
mainEventData.value = row
}
function addSubEvent(row) {
showNewEvent.value = true
}
function editSubEvent(row) {
showNewEvent.value = true
eventData.value = row
}
const dialog = useDialog()
function deleteEvent(row) {
dialog.warning({
title: '删除事件',
content: `确定删除事件 ${row.name} 吗?`,
positiveText: '确定',
negativeText: '取消',
onPositiveClick: async () => {
// await deleteEventById(row.id)
// getEventList()
},
})
}
function ddConfig(row) {
console.log(row)
dialog.create({
style: 'width:auto;height:90vh',
maskClosable: false,
class: 'flex flex-col',
title: 'DD轨迹',
contentClass: 'flex-1 h-0',
content: () => <EventDdConfig />,
// positiveText: '',
// negativeText: '',
// onPositiveClick: () => {},
})
}
const tableData = ref([])
onMounted(async () => {
const res = await getMainGantt()
tableData.value = res
await getEventList()
})
const { getAllKeys } = useTree()
const expandedRowKeys = ref([])
async function getEventList() {
const res = await getEventListByDDType(props.dd)
tableData.value = res.children
expandedRowKeys.value = getAllKeys(tableData.value, 'name')
}
watch(
() => props.dd,
async () => {
getEventList()
}
)
return () => (
<NDataTable
class="h-full"
flex-height
columns={columns}
data={tableData.value}
row-key={row => row.name}
/>
<>
<NDataTable
class="h-full"
flex-height
indent={30}
v-model:expanded-row-keys={expandedRowKeys.value}
columns={columns}
data={tableData.value}
row-key={row => row.name}
/>
<MainEventEdit v-model:show={showMainEvent.value} />
<SubEventEdit v-model:show={showNewEvent.value} />
</>
)
},
})

View File

@ -20,9 +20,9 @@ export default defineComponent({
<NRadioButton value="hour" label="日" />
<NRadioButton value="day" label="月" />
</NRadioGroup>
<NButton class="ml-auto" type="primary" onClick={editEvent}>
{/* <NButton class="ml-auto" type="primary" onClick={editEvent}>
编辑事件
</NButton>
</NButton> */}
</div>
<GanttCom scale={value.value} />
</>

View File

@ -1,4 +1,5 @@
import { NDataTable, NIcon, NButton } from 'naive-ui'
import { NDataTable, NIcon, NButton, NTag } from 'naive-ui'
import { useTree } from '@/utils/tree'
import { getTask } from '@/api/gantt'
import {
HelpCircleOutline,
@ -10,17 +11,34 @@ import {
export default defineComponent({
setup() {
const dict = {
task: { label: '任务', color: 'error' },
dd: { label: '主体' },
mainEvent: { label: '主事件', color: 'success' },
eventType: { label: '事件分类', color: 'info' },
subEvent: { label: '子事件', color: 'warning' },
}
const columns = [
{
title: '任务名称/事件名称',
key: 'name',
width: 220,
width: 'auto',
render: row => {
return (
<div class="inline-flex items-center gap-2">
<NIcon>
<HelpCircleOutline />
</NIcon>
{row.type && (
<NTag
size="small"
round
bordered={false}
type={dict[row.type]?.color}
>
{dict[row.type].label}
</NTag>
)}
{row.name}
</div>
)
@ -34,10 +52,24 @@ export default defineComponent({
title: '结束时间',
key: 'end',
},
{
title: '类型',
key: 'type',
},
// {
// title: '',
// key: 'type',
// render(row) {
// return (
// row.type && (
// <NTag
// size="small"
// round
// bordered={false}
// type={dict[row.type]?.color}
// >
// {dict[row.type].label}
// </NTag>
// )
// )
// },
// },
{
title: '图片',
key: 'avatar',
@ -110,15 +142,24 @@ export default defineComponent({
},
]
const tableData = ref([])
const { getAllKeys } = useTree()
const expandedRowKeys = ref([])
onMounted(async () => {
await getTaskList()
})
async function getTaskList() {
const res = await getTask()
tableData.value = res
})
expandedRowKeys.value = getAllKeys(tableData.value, 'name')
}
return () => (
<NDataTable
class="h-full"
flex-height
indent={30}
v-model:expanded-row-keys={expandedRowKeys.value}
columns={columns}
data={tableData.value}
row-key={row => row.name}

View File

@ -8,12 +8,14 @@ import {
NDrawerContent,
NTabs,
NTabPane,
NSelect,
} from 'naive-ui'
import { ArrowForward } from '@vicons/ionicons5'
import HeaderCom from '../Content/components/Header/index.vue'
import TaskList from './components/TaskList'
import EventList from './components/EventList'
import NewTask from './components/TaskList/components/NewTask'
import useTask from './components/TaskList/components/NewTask/hooks'
export default defineComponent({
setup() {
@ -26,6 +28,13 @@ export default defineComponent({
showNewTask.value = true
}
const ddList = Array.from({ length: 8 }, (_, i) => ({
label: `DD-${i + 1}`,
value: `DD-${i + 1}`,
}))
const dd = ref(`DD-1`)
const paneClass = `border-1 h-full border-l-0 border-[var(--n-tab-border-color)] !p-2`
return () => (
<div class="flex flex-col bg-[#1c202c] w-h-full">
@ -51,7 +60,7 @@ export default defineComponent({
<NDrawer
class="h-[100vh] bg-[#1c202cee]"
v-model:show={show.value}
width={document.body.clientWidth - 300}
width={document.body.clientWidth - 200}
placement="left"
display-directive={'show'}
>
@ -95,6 +104,11 @@ export default defineComponent({
>
<div class="flex h-full flex-col gap-2">
<div class="flex justify-end gap-2 ">
<NSelect
class="w-[200px]"
v-model:value={dd.value}
options={ddList}
></NSelect>
<NDatePicker
v-model:value={range.value}
type="daterange"
@ -105,7 +119,7 @@ export default defineComponent({
</NButton> */}
</div>
<div class="flex-1">
<EventList />
<EventList dd={dd.value} />
</div>
</div>
</NTabPane>

View File

@ -3,7 +3,7 @@ import { time2Format } from '@/utils/date'
const { mubiaoMap, getHisTraj } = useEntity()
const showTrajHour = ref(0)
const showTrajHour = ref(5)
const allEntity = ref<Cesium.Entity[]>([])
@ -34,35 +34,36 @@ async function getCurTraj(mbId: string) {
const startTime = time2Format(nowDate - showTrajHour.value * 60 * 60 * 1000)
// console.log(object);
if (mbId) {
initTraj(mbId)
} else {
;[...mubiaoMap.keys()].forEach(async id => {
initTraj(id)
})
}
async function initTraj(id: string) {
if (entityMap.value.has(id)) {
entityMap.value.get(id)?.forEach(entity => {
viewer.entities.remove(entity)
})
entityMap.value.delete(id)
}
const { points, posArray } = await getHisTraj({
id: mbId,
id,
timeRange: [startTime, endDate],
})
// console.log(points, posArray, 'pos')
const color = Cesium.Color.fromRandom({ alpha: 1 })
const linePoints = Cesium.Cartesian3.fromDegreesArrayHeights(posArray)
drawLine(id, linePoints, color)
drawPoints(
mbId,
id,
points.map(point => point.position),
color
)
const linePoints = Cesium.Cartesian3.fromDegreesArrayHeights(posArray)
drawLine(mbId, linePoints, color)
}
// ;[...mubiaoMap.keys()].forEach(async id => {
// const { points, posArray } = await getHisTraj({
// id,
// timeRange: [startTime, nowDate],
// })
// const color = Cesium.Color.fromRandom({ alpha: 1 })
// drawPoints(points, color)
// const linePoints = Cesium.Cartesian3.fromDegreesArrayHeights(posArray)
// drawLine(linePoints, color)
// })
}
function drawLine(
@ -111,6 +112,7 @@ function removeAllCurTraj() {
entityMap.value.get(id)?.forEach(entity => {
viewer.entities.remove(entity)
})
entityMap.value.delete(id)
})
// allEntity.value.forEach(entity => {
// viewer.entities.remove(entity)

View File

@ -164,7 +164,10 @@ export const useMubiao = () => {
const entity = mubiaoMap.get(id)
const position = Cesium.Cartesian3.fromDegrees(lon, lat)
entity.position = position
// console.log(target_direction)
entity.billboard.rotation = Cesium.Math.toRadians(
360 - target_direction + 90
)
entity.orientation = getOrientation({
position,
heading: target_direction as number,

View File

@ -16,7 +16,7 @@ interface IBaseFilterParam {
}
const satelliteList = ref<ISatellite[]>([])
const { satelliteMap } = useEntity()
const { satelliteMap, showOrHideLoad } = useEntity()
const showPoint = ref(true)
function showPointUnderSat(id?: string) {
@ -61,7 +61,7 @@ export function useSatellite() {
setTimeout(() => {
// satellite.sensorType = Math.random() > 0.5 ? 'conic' : 'rectangle'
satellite.sensor = true
satellite.sensor = showOrHideLoad.value
}, 1000)
// viewer.clock.multiplier = 100

View File

@ -11,8 +11,19 @@ export default defineComponent({
type: String,
default: '内容',
},
app: {
type: Object,
},
div: {
type: HTMLDivElement,
},
},
setup(props, { slots }) {
const onClose = () => {
event.stopPropagation()
props.app.mount()
props.div.remove()
}
return () => (
<div class="h-[180px] w-[180px] cursor-pointer">
<NConfigProvider
@ -23,13 +34,14 @@ export default defineComponent({
date-locale={dateZhCN}
>
<NAlert
class="h-full !bg-[var(--color-bg)]"
class="relative z-30 h-full !bg-[var(--color-bg)]"
type="info"
title={props.title}
closable
v-slots={{
icon: () => slots.icon(),
}}
onClose={onClose}
>
{props.content}
</NAlert>

View File

@ -113,6 +113,8 @@ export const useTextReport = () => {
{
title: data.title,
content: data.detailContent,
app: app,
div: div,
},
{
icon: () =>
@ -133,6 +135,7 @@ export const useTextReport = () => {
app.unmount()
div.remove()
}, toastMsgTimeSec * 1000 || 10000)
// }, 100000)
}
}

View File

@ -72,7 +72,7 @@ function createWeatherPoint(data) {
height: 30,
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
disableDepthTestDistance: 1000000000,
// disableDepthTestDistance: 1000000000,
},
})
return entity