载荷等

This commit is contained in:
严争鸣 2025-02-19 16:06:46 +08:00
parent f642f0d705
commit 516a54ee59
37 changed files with 934 additions and 286 deletions

View File

@ -29,16 +29,19 @@ window['settings'] = {
icon: './images/icons/飞机.png', icon: './images/icons/飞机.png',
color: '#d00', color: '#d00',
model: './models/IDF.glb', model: './models/IDF.glb',
payload: 'conic',
}, },
: { : {
icon: './images/icons/舰船.png', icon: './images/icons/舰船.png',
color: '#dd0', color: '#dd0',
model: './models/驱逐舰2.glb', model: './models/驱逐舰2.glb',
payload: 'radar',
}, },
: { : {
icon: './images/icons/舰船.png', icon: './images/icons/舰船.png',
color: '#dd0', color: '#dd0',
model: './models/驱逐舰2.glb', model: './models/驱逐舰2.glb',
payload: 'radar',
}, },
}, },
@ -68,4 +71,15 @@ window['settings'] = {
name: '卫星影像', name: '卫星影像',
}, },
}, },
gantt: {
task: { label: '任务', color: 'error' },
dd: { label: '主体' },
mainEvent: { label: '主事件', color: 'success' },
eventType: { label: '事件分类', color: 'info' },
subEvent: { label: '子事件', color: 'warning' },
},
} }

View File

@ -13,8 +13,7 @@ const sub = [
end: '2024-11-17', end: '2024-11-17',
type: 'subEvent', type: 'subEvent',
trajData: {}, trajData: {},
avatar: avatar: '/images/影像.jpg',
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
}, },
], ],
}, },
@ -29,8 +28,7 @@ const sub = [
start: '2024-11-18', start: '2024-11-18',
end: '2024-11-21', end: '2024-11-21',
type: 'subEvent', type: 'subEvent',
avatar: avatar: '/images/影像.jpg',
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/rabbit.jpg',
}, },
], ],
}, },
@ -44,8 +42,7 @@ const sub = [
start: '2024-11-20', start: '2024-11-20',
end: '2024-11-22', end: '2024-11-22',
type: 'subEvent', type: 'subEvent',
avatar: avatar: '/images/影像.jpg',
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/cat.jpg',
}, },
{ {
id: 7, id: 7,
@ -53,8 +50,7 @@ const sub = [
start: '2024-11-18', start: '2024-11-18',
end: '2024-11-19', end: '2024-11-19',
type: 'subEvent', type: 'subEvent',
avatar: avatar: '/images/影像.jpg',
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/flower.jpg',
}, },
], ],
}, },
@ -69,8 +65,7 @@ const sub = [
start: '2024-11-20', start: '2024-11-20',
end: '2024-11-21', end: '2024-11-21',
type: 'subEvent', type: 'subEvent',
avatar: avatar: '/images/影像.jpg',
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bear.jpg',
}, },
{ {
id: 9, id: 9,
@ -78,8 +73,7 @@ const sub = [
start: '2024-11-22', start: '2024-11-22',
end: '2024-11-26', end: '2024-11-26',
type: 'subEvent', type: 'subEvent',
avatar: avatar: '/images/影像.jpg',
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/wolf.jpg',
}, },
], ],
}, },
@ -93,9 +87,7 @@ const sub = [
start: '2024-11-22', start: '2024-11-22',
end: '2024-11-25', end: '2024-11-25',
type: 'subEvent', type: 'subEvent',
avatar: '/images/影像.jpg',
avatar:
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/rabbit.jpg',
}, },
{ {
id: 14, id: 14,
@ -103,8 +95,7 @@ const sub = [
start: '2024-11-27', start: '2024-11-27',
end: '2024-11-30', end: '2024-11-30',
type: 'subEvent', type: 'subEvent',
avatar: avatar: '/images/影像.jpg',
'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/cat.jpg',
}, },
], ],
}, },
@ -114,8 +105,6 @@ const main = [
{ {
id: 0, id: 0,
name: 'DD-1', name: 'DD-1',
start: '2024-11-15',
end: '2024-11-21',
type: 'dd', type: 'dd',
children: [ children: [
{ {

View File

@ -31,3 +31,11 @@ export function getMubiaoHisTraj(params) {
params, params,
}) })
} }
export function updateMbPayload(data = {}) {
return request({
url: `${baseUrl}/traj/extendInfo`,
method: 'put',
data,
})
}

View File

@ -23,4 +23,12 @@ export function getSatellite() {
}) })
} }
export function updateSatellitePayload(data = {}) {
return request({
url: `${baseUrl}/satellite/extendInfo`,
method: 'put',
data,
})
}
export { getTleDataFromExternal } export { getTleDataFromExternal }

View File

@ -26,6 +26,10 @@ const props = defineProps({
type: Function as TreeNodeProps, type: Function as TreeNodeProps,
default: undefined, default: undefined,
}, },
renderLabel: {
type: Function as RenderTreePart,
default: undefined,
},
renderSuffix: { renderSuffix: {
type: Function as RenderTreePart, type: Function as RenderTreePart,
default: undefined, default: undefined,
@ -81,6 +85,7 @@ const updateChecked = (keys: Array<string | number>) => {
@update:checked-keys="updateChecked" @update:checked-keys="updateChecked"
:node-props="nodeProps" :node-props="nodeProps"
:render-suffix="renderSuffix" :render-suffix="renderSuffix"
:render-label="renderLabel"
/> />
<!-- :default-checked-keys="defaultCheckedKeys" --> <!-- :default-checked-keys="defaultCheckedKeys" -->
</n-scrollbar> </n-scrollbar>

View File

@ -1,16 +1,30 @@
import { reactive } from 'vue'
import { getMubiaoHisTraj } from '@/api/Mubiao' import { getMubiaoHisTraj } from '@/api/Mubiao'
const baseMap = new Map() const baseMap = new Map()
const mubiaoMap = new Map() const mubiaoMap = new Map()
const mubiaoConicMap = new Map()
const satelliteMap = new Map() const satelliteMap = new Map()
const mbPayloadShowMap = reactive(new Map())
// const satDetectingPayloadMap = reactive(new Map())
// const satCommunicationPayloadMap = reactive(new Map())
const satellitePayloadShowMap = reactive(new Map())
export const useEntity = () => { export const useEntity = () => {
return { return {
baseMap, baseMap,
mubiaoMap, mubiaoMap,
mubiaoConicMap,
satelliteMap, satelliteMap,
mbPayloadShowMap,
// satDetectingPayloadMap,
// satCommunicationPayloadMap,
satellitePayloadShowMap,
showEntity, showEntity,
getHisTraj, getHisTraj,
getMBEntityOpt, getMBEntityOpt,
createMBConicSensor,
iconOrModel, iconOrModel,
changeIconOrModel, changeIconOrModel,
showOrHideLoad, showOrHideLoad,
@ -66,14 +80,48 @@ async function getHisTraj({
function getMBEntityOpt({ function getMBEntityOpt({
id, id,
targetType, targetType,
name, extendInfo,
}: { }: {
id: string id: string
targetType: string targetType: string
name?: string extendInfo?: { detectingPayload: Record<string, number> }
}) { }) {
const mubiaoDict = window.settings.mbDict[targetType] const mubiaoDict = window.settings.mbDict[targetType]
let ellipsoid
if (extendInfo) {
const {
angle,
maximumCone,
minimumCone,
minimumClock,
maximumClock,
radius,
} = extendInfo.detectingPayload
if (radius) {
ellipsoid = {
ellipsoid: {
show: mbPayloadShowMap.get(id)?.detectingPayload?.show || false,
radii: new Cesium.Cartesian3(radius, radius, radius),
innerRadii: new Cesium.Cartesian3(1.0, 1.0, 1.0),
maximumCone: Cesium.Math.toRadians(90),
minimumCone: Cesium.Math.toRadians(minimumCone),
minimumClock: Cesium.Math.toRadians(minimumClock),
maximumClock: Cesium.Math.toRadians(maximumClock),
material: Cesium.Color.fromCssColorString('#00dcff44'),
outline: true,
outlineColor: Cesium.Color.fromCssColorString('#00dcff'),
outlineWidth: 1,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
0.0,
10.5e8
),
slicePartitions: 24,
stackPartitions: 36,
},
}
}
}
return { return {
label: { label: {
text: `${id}`, text: `${id}`,
@ -105,28 +153,49 @@ function getMBEntityOpt({
scale: 1000, scale: 1000,
minimumPixelSize: 50, minimumPixelSize: 50,
}, },
ellipsoid: { ...ellipsoid,
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),
minimumCone: Cesium.Math.toRadians(40),
minimumClock: Cesium.Math.toRadians(20),
maximumClock: Cesium.Math.toRadians(90),
material: Cesium.Color.fromCssColorString('#00dcff44'),
outline: true,
outlineColor: Cesium.Color.fromCssColorString('#00dcff'),
outlineWidth: 1,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
0.0,
10.5e8
),
slicePartitions: 24,
stackPartitions: 36,
},
} }
} }
function createMBConicSensor({
entity,
angle,
show,
}: {
entity: Cesium.Entity
angle: number
show: boolean
}) {
console.log('entity', angle)
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
show,
radius: 2e7,
innerHalfAngle: 0,
outerHalfAngle: Cesium.Math.toRadians(angle / 2),
minimumClockAngle: 0,
maximumClockAngle: 2 * Math.PI,
showIntersection: true,
intersectionColor: new Cesium.Color(1, 1, 1, 1),
intersectionWidth: 3,
lateralSurfaceMaterial: new Cesium.Color(0.0, 1.0, 1.0, 0.3),
})
const mbConic = viewer.entities.add({
position: entity.position,
orientation:
entity.position &&
Cesium.Transforms.headingPitchRollQuaternion(
entity.position._value,
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(90),
0,
Cesium.Math.toRadians(180)
) // 初始朝向
),
conicSensor: conicSensor,
})
return mbConic
}
const iconOrModel = ref(false) const iconOrModel = ref(false)
function changeIconOrModel() { function changeIconOrModel() {
iconOrModel.value = !iconOrModel.value iconOrModel.value = !iconOrModel.value
@ -136,15 +205,51 @@ function changeIconOrModel() {
}) })
} }
const showOrHideLoad = ref(true) const showOrHideLoad = ref(false)
watch([mbPayloadShowMap, satellitePayloadShowMap], ([newMb, newSatellite]) => {
;[...newMb.keys()].forEach(key => {
let show = false
if (newMb.get(key).detectingPayload) {
show = newMb.get(key).detectingPayload.show
}
if (mubiaoMap.has(key)) {
// if(console.log(mubiaoMap.get(key).ellipsoid)
mubiaoMap.get(key).ellipsoid && (mubiaoMap.get(key).ellipsoid.show = show)
mubiaoConicMap.get(key)?.conicSensor &&
(mubiaoConicMap.get(key).conicSensor.show = show)
}
})
;[...newSatellite.keys()].forEach(key => {
let show = false
if (newSatellite.get(key).detectingPayload) {
show = newSatellite.get(key).detectingPayload.show
// console.log(newSatellite.get(key).detectingPayload.show)
}
if (satelliteMap.has(key)) {
satelliteMap.get(key).sensor = show
}
})
})
function changeShowOrHideLoad() { function changeShowOrHideLoad() {
showOrHideLoad.value = !showOrHideLoad.value showOrHideLoad.value = !showOrHideLoad.value
;[...mubiaoMap.values()].forEach(entity => { // ;[...mubiaoMap.values()].forEach(entity => {
entity.ellipsoid.show = !entity.ellipsoid.show._value // entity.ellipsoid.show = !entity.ellipsoid.show._value
}) // })
;[...satelliteMap.values()].forEach(satellite => { for (const [key] of mbPayloadShowMap.entries()) {
satellite.sensor = showOrHideLoad.value mbPayloadShowMap.get(key).detectingPayload.show = showOrHideLoad.value
console.log(satellite) }
})
for (const [key] of satellitePayloadShowMap.entries()) {
satellitePayloadShowMap.get(key).detectingPayload &&
(satellitePayloadShowMap.get(key).detectingPayload.show =
showOrHideLoad.value)
satellitePayloadShowMap.get(key).communicationPayload &&
(satellitePayloadShowMap.get(key).communicationPayload.show =
showOrHideLoad.value)
}
// ;[...satelliteMap.values()].forEach(satellite => {
// satellite.sensor = showOrHideLoad.value
// })
} }

View File

@ -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._sensorAngle = 30
this._sensorType = 'conic' this._sensorType = 'conic'
this._listener = null this._listener = null
} }
@ -50,6 +51,16 @@ class SatelliteEntity {
} }
} }
get sensorAngle() {
return this._sensorAngle
}
set sensorAngle(angle) {
this._sensorAngle = angle
if (this._sensorEntity) {
this._sensorEntity.angle = angle
}
}
get underPoint() { get underPoint() {
return this._underPoint return this._underPoint
} }
@ -344,7 +355,7 @@ class SatelliteEntity {
show: true, show: true,
radius: 2e7, radius: 2e7,
innerHalfAngle: 0, innerHalfAngle: 0,
outerHalfAngle: Cesium.Math.toRadians(20), outerHalfAngle: Cesium.Math.toRadians(this._sensorAngle / 2),
minimumClockAngle: 0, minimumClockAngle: 0,
maximumClockAngle: 2 * Math.PI, maximumClockAngle: 2 * Math.PI,
showIntersection: true, showIntersection: true,

View File

@ -2,6 +2,8 @@ export const useTree = () => {
return { return {
filterTreeNodeByField, filterTreeNodeByField,
getAllKeys, getAllKeys,
getLeafNodeIds,
getLeafNode,
} }
} }
@ -36,3 +38,37 @@ function getAllKeys(treeData, key) {
return acc return acc
}, []) }, [])
} }
function getLeafNodeIds(tree, idKey) {
let leafIds = []
function traverse(node) {
if (!node.children && node.data) {
leafIds.push(node[idKey])
} else {
for (let child of node.children) {
traverse(child)
}
}
}
traverse(tree)
return leafIds
}
function getLeafNode(tree) {
let leafNodes = []
function traverse(node) {
if (!node.children && node.data) {
leafNodes.push(node)
} else {
for (let child of node.children) {
traverse(child)
}
}
}
traverse(tree)
return leafNodes
}

View File

@ -86,10 +86,14 @@ const isCompare = ref(false)
const compareImages = () => { const compareImages = () => {
if (!isCompare.value) { if (!isCompare.value) {
if (checkedImage.value && checkedImage.value.length === 2) { if (checkedImage.value && checkedImage.value.length === 2) {
showPreview.value = true
previewIndex.value = 0
// showPreview.value = true
isCompare.value = true isCompare.value = true
} }
} else { } else {
isCompare.value = false isCompare.value = false
showPreview.value = false
checkedImage.value = null checkedImage.value = null
} }
} }
@ -130,9 +134,14 @@ const largeImageList = computed(() => {
format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss"
/> />
<n-button type="primary" @click="getImage">搜索</n-button> <n-button type="primary" @click="getImage">搜索</n-button>
<n-button type="primary" @click="compareImages">{{ <n-button
isCompare ? '取消对比' : '对比' type="primary"
}}</n-button> :disabled="
!isCompare && (!checkedImage || checkedImage.length < 2)
"
@click="compareImages"
>{{ isCompare ? '取消对比' : '对比' }}</n-button
>
</div> </div>
<div v-if="imageList.length === 0" class="m-auto flex"> <div v-if="imageList.length === 0" class="m-auto flex">
<n-empty description="暂无数据"> </n-empty> <n-empty description="暂无数据"> </n-empty>

View File

@ -12,7 +12,7 @@ import Hangjing from '../Hangjing/index.vue'
import Mubiao from '../Mubiao/index.vue' import Mubiao from '../Mubiao/index.vue'
import MubiaoHisTrajectory from '../Mubiao/components/HisTrajectory/index.vue' import MubiaoHisTrajectory from '../Mubiao/components/HisTrajectory/index.vue'
import MultiHisTrajectory from '../Mubiao/components/MultiHisTrajectory/index.vue' import MultiHisTrajectory from '../Mubiao/components/MultiHisTrajectory/index.vue'
import YsHangjing from '../YsHangjing/index.vue' // import YsHangjing from '../YsHangjing/index.vue'
import Daodan from '../Daodan' import Daodan from '../Daodan'
@ -60,7 +60,7 @@ const types = [
{ name: 'XW', value: 'wzbXw' }, { name: 'XW', value: 'wzbXw' },
] ]
const showPanelName = ref('dd') const showPanelName = ref('wx')
const panelList = [ const panelList = [
// { // {
@ -149,13 +149,13 @@ const showOrHideTextReport = () => {
}}</label> }}</label>
</template> </template>
</div> </div>
<transition name="slide"> <!-- <transition name="slide">
<div class="left-panel-wrapper" v-show="showPanelName === 'hj-1'"> <div class="left-panel-wrapper" v-show="showPanelName === 'hj-1'">
<panel title="航景"> <panel title="航景">
<ys-hangjing /> <ys-hangjing />
</panel> </panel>
</div> </div>
</transition> </transition> -->
<transition name="slide"> <transition name="slide">
<div class="left-panel-wrapper" v-show="showPanelName === 'hj-2'"> <div class="left-panel-wrapper" v-show="showPanelName === 'hj-2'">
<panel title="值班航景"> <panel title="值班航景">

View File

@ -7,11 +7,9 @@ const treeData = ref([])
const daodanData = ref({}) const daodanData = ref({})
export function useDaodan() { export function useDaodan() {
onMounted(() => {
getDaodanTreeData()
})
return { return {
showDdConfigCom, showDdConfigCom,
getDaodanTreeData,
showOrHideDdConfig, showOrHideDdConfig,
isLoading, isLoading,
daodanData, daodanData,

View File

@ -2,11 +2,15 @@ import Tree from '@/components/Tree/index.vue'
import { useDaodan } from './ddHooks' import { useDaodan } from './ddHooks'
import { NButton } from 'naive-ui' import { NButton } from 'naive-ui'
import { useTestConfig } from './components/hooks/testHooks' import { useTestConfig } from './components/hooks/testHooks'
import { onMounted } from 'vue'
export default defineComponent({ export default defineComponent({
setup() { setup() {
const { treeData, isLoading, showOrHideDdConfig } = useDaodan() const { treeData, isLoading, showOrHideDdConfig, getDaodanTreeData } =
useDaodan()
onMounted(() => {
getDaodanTreeData()
})
const renderSuffix = ({ option }) => { const renderSuffix = ({ option }) => {
if (!option.data) { if (!option.data) {
return undefined return undefined

View File

@ -33,7 +33,7 @@ onMounted(async () => {
// tilingScheme: new Cesium.WebMercatorTilingScheme(), // tilingScheme: new Cesium.WebMercatorTilingScheme(),
// }) // })
// ) // )
viewer.scene.debugShowFramesPerSecond = true // viewer.scene.debugShowFramesPerSecond = true
viewer.camera.setView({ viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(117.48, 30.67, 18000000.0), destination: Cesium.Cartesian3.fromDegrees(117.48, 30.67, 18000000.0),
}) })
@ -109,6 +109,23 @@ onMounted(async () => {
// } // }
// }) // })
// }, 2000) // }, 2000)
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
// var tooltip = document.getElementById("toolTip");
handler.setInputAction(function (movement) {
// tooltip.style.display = "none";
// cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
const ray = viewer.camera.getPickRay(movement.position)
const promise = viewer.imageryLayers.pickImageryLayerFeatures(
ray,
viewer.scene
)
Promise.resolve(promise).then(function (features) {
console.log(features)
})
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}) })
</script> </script>

View File

@ -19,7 +19,7 @@ export default defineComponent({
const { showMainEvent, mainEventData } = useEvent() const { showMainEvent, mainEventData } = useEvent()
const close = () => { const close = () => {
showNewEvent.value = false showMainEvent.value = false
} }
watch( watch(
@ -52,7 +52,9 @@ export default defineComponent({
</NForm> </NForm>
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
<NButton onClick={close}>取消</NButton> <NButton onClick={close}>取消</NButton>
<NButton type="primary">确认</NButton> <NButton type="primary" onClick={close}>
确认
</NButton>
</div> </div>
</ModalCom> </ModalCom>
) )

View File

@ -73,7 +73,9 @@ export default defineComponent({
</NForm> </NForm>
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
<NButton onClick={close}>取消</NButton> <NButton onClick={close}>取消</NButton>
<NButton type="primary">确认</NButton> <NButton type="primary" onClick={close}>
确认
</NButton>
</div> </div>
</ModalCom> </ModalCom>
) )

View File

@ -25,12 +25,7 @@ export default defineComponent({
}, },
setup(props) { setup(props) {
const { showMainEvent, mainEventData, showNewEvent, eventData } = useEvent() const { showMainEvent, mainEventData, showNewEvent, eventData } = useEvent()
const dict = { const dict = window.settings.gantt
mainEvent: { label: '主事件', color: 'success' },
eventType: { label: '事件分类', color: 'info' },
subEvent: { label: '子事件', color: 'warning' },
}
const columns = [ const columns = [
{ {
title: '事件名称', title: '事件名称',

View File

@ -36,7 +36,7 @@ const useGantt = ({ router, route }: GanttParams) => {
const option = getOption() const option = getOption()
ganttInstance = new Gantt(dom, option) ganttInstance = new Gantt(dom, option)
window['ganttInstance'] = ganttInstance window['ganttInstance'] = ganttInstance
console.log(ganttInstance) // console.log(ganttInstance)
} }
function getOption(): TYPES.GanttConstructorOptions { function getOption(): TYPES.GanttConstructorOptions {
const option = { const option = {
@ -224,6 +224,28 @@ const useGantt = ({ router, route }: GanttParams) => {
// checkbox.addEventListener('click', event => { // checkbox.addEventListener('click', event => {
// console.log(event, 'event') // console.log(event, 'event')
// }) // })
// console.log(taskRecord, 'taskRecord')
const nameContainer = new Group({
fill: 'transparent',
display: 'flex',
// flexDirection: 'column',
// justifyContent: 'center',
alignItems: 'center',
})
container.add(nameContainer)
if ('trajData' in taskRecord && taskRecord.trajData) {
const taskRecordSymbol = new Image({
width: 20,
height: 20,
fill: '#ff0',
image:
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8s8 3.59 8 8s-3.59 8-8 8zm0-12.5c-2.49 0-4.5 2.01-4.5 4.5s2.01 4.5 4.5 4.5s4.5-2.01 4.5-4.5s-2.01-4.5-4.5-4.5zm0 5.5c-.55 0-1-.45-1-1s.45-1 1-1s1 .45 1 1s-.45 1-1 1z" fill="#ff0"></path></svg>',
boundsPadding: [-3, 10, 0, 0],
cursor: 'pointer',
})
nameContainer.add(taskRecordSymbol)
}
const name = new Text({ const name = new Text({
text: taskRecord.name, text: taskRecord.name,
fontSize: 16, fontSize: 16,
@ -234,7 +256,7 @@ const useGantt = ({ router, route }: GanttParams) => {
textAlign: 'center', textAlign: 'center',
// boundsPadding: [10, 0, 0, 0], // boundsPadding: [10, 0, 0, 0],
}) })
container.add(name) nameContainer.add(name)
const days = new Text({ const days = new Text({
text: `${startDate.toLocaleDateString()} ~ ${endDate.toLocaleDateString()}`, text: `${startDate.toLocaleDateString()} ~ ${endDate.toLocaleDateString()}`,

View File

@ -15,7 +15,12 @@ export default defineComponent({
return () => ( return () => (
<> <>
<div class="flex gap-2"> <div class="flex gap-2">
<NDatePicker v-model:value={range.value} type="daterange" clearable /> <NDatePicker
v-model:value={range.value}
type="daterange"
clearable
disabled
/>
<NRadioGroup v-model:value={value.value} name="radiobuttongroup"> <NRadioGroup v-model:value={value.value} name="radiobuttongroup">
<NRadioButton value="hour" label="日" /> <NRadioButton value="hour" label="日" />
<NRadioButton value="day" label="月" /> <NRadioButton value="day" label="月" />

View File

@ -1,7 +1,14 @@
const showNewTask = ref(false) const showNewTask = ref(false)
const curTaskData = ref({
name: '',
description: '',
checkedEvent: [],
})
const useTask = () => { const useTask = () => {
return { return {
showNewTask, showNewTask,
curTaskData,
} }
} }

View File

@ -10,14 +10,11 @@ export default defineComponent({
// }, // },
// }, // },
setup() { setup() {
const checkedRowKeys = ref([]) // const checkedRowKeys = ref([])
watch(checkedRowKeys, newval => { // watch(checkedRowKeys, newval => {
console.log(newval, '-----') // console.log(newval, '-----')
}) // })
const task = ref({
name: '',
description: '',
})
const columns = [ const columns = [
{ type: 'selection' }, { type: 'selection' },
{ {
@ -43,10 +40,10 @@ export default defineComponent({
title: '结束时间', title: '结束时间',
key: 'end', key: 'end',
}, },
{ // {
title: '类型', // title: '',
key: 'type', // key: 'type',
}, // },
{ {
title: '图片', title: '图片',
key: 'avatar', key: 'avatar',
@ -59,34 +56,50 @@ export default defineComponent({
}, },
}, },
] ]
const tableData = ref([]) const tableData = ref([])
onMounted(async () => { onMounted(async () => {
const res = await getMainGantt() const res = await getMainGantt()
tableData.value = res tableData.value = res
}) })
const { showNewTask } = useTask() const { showNewTask, curTaskData } = useTask()
const close = () => { const close = () => {
showNewTask.value = false showNewTask.value = false
console.log(curTaskData, '---')
} }
// watch(
// showNewTask,
// show => {
// if (show) {
// taskData.value = {
// name: '',
// description: '',
// checkedEvent: [],
// }
// }
// },
// { immediate: true }
// )
return () => ( return () => (
<ModalCom v-model:show={showNewTask.value} title="新增任务"> <ModalCom v-model:show={showNewTask.value} title="新增任务">
<NForm <NForm
class="w-[900px]" class="w-[900px]"
model={task} model={curTaskData}
label-placement="left" label-placement="left"
label-width="auto" label-width="auto"
> >
<NFormItem label="任务名称" path="name"> <NFormItem label="任务名称" path="name">
<NInput v-model:value={task.value.name} /> <NInput v-model:value={curTaskData.value.name} />
</NFormItem> </NFormItem>
<NFormItem label="任务描述" path="description"> <NFormItem label="任务描述" path="description">
<NInput v-model:value={task.value.description} /> <NInput v-model:value={curTaskData.value.description} />
</NFormItem> </NFormItem>
<NFormItem label="事件" path="event"> <NFormItem label="事件" path="event">
<NDataTable <NDataTable
v-model:checked-row-keys={checkedRowKeys.value} v-model:checked-row-keys={curTaskData.value.checkedEvent}
class="h-[400px]" class="h-[400px]"
flex-height flex-height
columns={columns} columns={columns}

View File

@ -8,19 +8,11 @@ import {
AddCircleOutline, AddCircleOutline,
EnterOutline, EnterOutline,
} from '@vicons/ionicons5' } from '@vicons/ionicons5'
import useTask from './components/NewTask/hooks'
export default defineComponent({ export default defineComponent({
setup() { setup() {
const dict = { const dict = window.settings.gantt
task: { label: '任务', color: 'error' },
dd: { label: '主体' },
mainEvent: { label: '主事件', color: 'success' },
eventType: { label: '事件分类', color: 'info' },
subEvent: { label: '子事件', color: 'warning' },
}
const columns = [ const columns = [
{ {
title: '任务名称/事件名称', title: '任务名称/事件名称',
@ -93,21 +85,23 @@ export default defineComponent({
type="primary" type="primary"
size="small" size="small"
quaternary quaternary
onClick={() => handleEdit(row)} onClick={() => editTask(row)}
> >
<NIcon> <NIcon>
<EnterOutline /> <EnterOutline />
</NIcon> </NIcon>
进入任务
</NButton> </NButton>
<NButton <NButton
type="primary" type="primary"
size="small" size="small"
quaternary quaternary
onClick={() => handleEdit(row)} onClick={() => editTask(row)}
> >
<NIcon> <NIcon>
<CreateOutline /> <CreateOutline />
</NIcon> </NIcon>
编辑
</NButton> </NButton>
</> </>
) : null} ) : null}
@ -126,7 +120,7 @@ export default defineComponent({
<></> <></>
)} */} )} */}
<NButton {/* <NButton
type="error" type="error"
size="small" size="small"
quaternary quaternary
@ -135,7 +129,7 @@ export default defineComponent({
<NIcon> <NIcon>
<TrashBinOutline /> <TrashBinOutline />
</NIcon> </NIcon>
</NButton> </NButton> */}
</div> </div>
) )
}, },
@ -154,6 +148,15 @@ export default defineComponent({
expandedRowKeys.value = getAllKeys(tableData.value, 'name') expandedRowKeys.value = getAllKeys(tableData.value, 'name')
} }
const { showNewTask, curTaskData } = useTask()
function editTask(row) {
showNewTask.value = true
curTaskData.value = {
...row,
checkedEvent: getAllKeys(row.children, 'name'),
}
}
return () => ( return () => (
<NDataTable <NDataTable
class="h-full" class="h-full"

View File

@ -16,9 +16,9 @@ const hangjingMap: Map<string, any> = new Map()
const { addHangjingPolygon, removeHangjingPolygon } = useHjPolygon(hangjingMap) const { addHangjingPolygon, removeHangjingPolygon } = useHjPolygon(hangjingMap)
export const useHangjing = () => { export const useHangjing = () => {
onMounted(() => { // onMounted(() => {
initWebSocket() // initWebSocket()
}) // })
const addHangjing = ids => { const addHangjing = ids => {
addHangjingPolygon(ids, hjTreeData) addHangjingPolygon(ids, hjTreeData)
} }
@ -28,6 +28,7 @@ export const useHangjing = () => {
} }
return { return {
initWebSocket,
addHangjing, addHangjing,
removeHangjing, removeHangjing,
hjTreeData, hjTreeData,

View File

@ -16,7 +16,7 @@ export const useHjPolygon = (polygonMap: Map<string | number, any>) => {
let subscriber: Subscriber | null = null let subscriber: Subscriber | null = null
const colors = new Map() const colors = new Map()
const centerPointMap = new Map()
function addHangjingPolygon(ids, data) { function addHangjingPolygon(ids, data) {
subscriber = new Subscriber(viewer, { subscriber = new Subscriber(viewer, {
pickResult: { pickResult: {
@ -38,10 +38,13 @@ export const useHjPolygon = (polygonMap: Map<string | number, any>) => {
nodes.forEach(({ data: hjData, dataId: id }) => { nodes.forEach(({ data: hjData, dataId: id }) => {
// const item = data.find(item => item.id === id) // const item = data.find(item => item.id === id)
if (hjData) { if (hjData) {
// console.log(hjData, 'hjData')
if (hjData.zoneList.length > 0) { if (hjData.zoneList.length > 0) {
hjData.zoneList.forEach(zone => { hjData.zoneList.forEach(zone => {
// console.log(zone, 'zone') // console.log(zone, 'zone')
addPolygon({ ...zone, styleJsonData: hjData.styleJsonData }, id) // addPolygon({ ...zone, styleJsonData: hjData.styleJsonData }, id)
addPolygon({ ...zone, styleJsonData: hjData.styleJsonData })
}) })
} else { } else {
addPolygon(hjData) addPolygon(hjData)
@ -60,6 +63,7 @@ export const useHjPolygon = (polygonMap: Map<string | number, any>) => {
} }
function addPolygon(item, parentId: number | null = null) { function addPolygon(item, parentId: number | null = null) {
// console.log(parentId, '----')
const { id, geom, title, styleJsonData } = item const { id, geom, title, styleJsonData } = item
const feature = parseWKT(geom) const feature = parseWKT(geom)
const position = feature.coordinates[0].map(pos => { const position = feature.coordinates[0].map(pos => {
@ -115,9 +119,10 @@ export const useHjPolygon = (polygonMap: Map<string | number, any>) => {
polygonMap.get(parentId).push(centerEntity) polygonMap.get(parentId).push(centerEntity)
} else { } else {
polygonMap.set(id, polygon) polygonMap.set(id, polygon)
centerPointMap.set(id, centerEntity)
} }
// console.log(polygonMap, 'polygonMap') // console.log(parentId, polygonMap, 'polygonMap')
} }
function addPolygonCenter(centerPoint: number[]) { function addPolygonCenter(centerPoint: number[]) {
@ -235,6 +240,11 @@ export const useHjPolygon = (polygonMap: Map<string | number, any>) => {
// viewer.entities.remove(hangjingMap.get(id)) // viewer.entities.remove(hangjingMap.get(id))
polygonMap.delete(id) polygonMap.delete(id)
} }
if (centerPointMap.has(id)) {
viewer.entities.remove(centerPointMap.get(id))
centerPointMap.delete(id)
}
} }
function addEventSub({ function addEventSub({

View File

@ -26,7 +26,7 @@ function initStyle(data) {
styleForm.value = { styleForm.value = {
fontFamily: '微软雅黑', fontFamily: '微软雅黑',
fontSize: 14, fontSize: 14,
textColor: 'rgba(255,255,0,1)', textColor: 'rgba(255,255,255,1)',
polygonColor: 'rgba(255,255,255,0.5)', polygonColor: 'rgba(255,255,255,0.5)',
lineColor: 'rgba(255,255,255,1)', lineColor: 'rgba(255,255,255,1)',
lineWidth: 1, lineWidth: 1,

View File

@ -96,9 +96,22 @@ const drawArea = () => {
const { showDetailsModal } = useHangjingDetail() const { showDetailsModal } = useHangjingDetail()
const renderSuffix = ({ option }: { option: TreeOption }) => { const renderLabel = ({ option }) => {
return option.data // if()
? h('div', { class: 'flex items-center gap-2 pr-2' }, [ if (option.data) {
const textColor = option.data.styleJsonData
? JSON.parse(option.data.styleJsonData).textColor
: 'rgba(255,255,255,1)'
return h('span', { style: `color:${textColor}` }, option.data.title)
} else {
return option.nodeName
}
}
const renderSuffix = ({ option }) => {
return (
option.data &&
h('div', { class: 'flex items-center gap-2 pr-2' }, [
h( h(
NButton, NButton,
{ {
@ -121,12 +134,13 @@ const renderSuffix = ({ option }: { option: TreeOption }) => {
// { default: () => '' } // { default: () => '' }
// ), // ),
]) ])
: null )
} }
// const checkedKeys = ref<Array<string | number>>([]) // const checkedKeys = ref<Array<string | number>>([])
const { const {
initWebSocket,
addHangjing, addHangjing,
hjTreeData, hjTreeData,
isLoading, isLoading,
@ -144,6 +158,7 @@ watch(checkedKeys, val => {
}) })
onMounted(() => { onMounted(() => {
initWebSocket()
getHangjingData() getHangjingData()
}) })
</script> </script>
@ -196,6 +211,7 @@ onMounted(() => {
v-model:checked="checkedKeys" v-model:checked="checkedKeys"
showSearch showSearch
:renderSuffix="renderSuffix" :renderSuffix="renderSuffix"
:renderLabel="renderLabel"
/> />
</div> </div>
</template> </template>

View File

@ -1,9 +1,9 @@
import { ref } from 'vue' import { ref, nextTick } from 'vue'
import { Subscriber } from 'cesium-extends' import { Subscriber } from 'cesium-extends'
import { parseWKT } from '@/utils/parseWKT' import { parseWKT } from '@/utils/parseWKT'
import { cesiumTime2Format } from '@/utils/date' import { cesiumTime2Format } from '@/utils/date'
import { difference } from 'lodash' import { difference } from 'lodash'
import { getMubiaoPos, sendCheckedTargetIds } from '@/api/Mubiao' import { getMubiao, getMubiaoPos, sendCheckedTargetIds } from '@/api/Mubiao'
import { useTree } from '@/utils/tree' import { useTree } from '@/utils/tree'
import { useMubiaoPopup } from './mubiaoPopup' import { useMubiaoPopup } from './mubiaoPopup'
import { useEntity } from '@/hooks/entity' import { useEntity } from '@/hooks/entity'
@ -23,15 +23,23 @@ interface IMubiao {
children?: IMubiao[] children?: IMubiao[]
} }
const checkedKeys = ref<Array<string | number>>([])
const data = ref<Record<string, any>[]>([]) const data = ref<Record<string, any>[]>([])
const { mubiaoMap, getMBEntityOpt } = useEntity() const {
mubiaoMap,
getMBEntityOpt,
createMBConicSensor,
mubiaoConicMap,
mbPayloadShowMap,
} = useEntity()
// const { mubiaoMap } = storeToRefs(entity) // const { mubiaoMap } = storeToRefs(entity)
// const mubiaoMap = ref<Map<string, any>>(new Map()) // const mubiaoMap = ref<Map<string, any>>(new Map())
let subscriber: Subscriber | null = null let subscriber: Subscriber | null = null
const { filterTreeNodeByField } = useTree() const { filterTreeNodeByField, getLeafNode } = useTree()
const { popupMap, createPopup } = useMubiaoPopup() const { popupMap, createPopup } = useMubiaoPopup()
export const useMubiao = () => { export const useMubiao = () => {
@ -72,6 +80,7 @@ export const useMubiao = () => {
position: pos, position: pos,
target_time, target_time,
targetType: data.targetType, targetType: data.targetType,
extendInfo: data.extendInfo,
}) })
// console.log(mbEntity, 'mbEntity') // console.log(mbEntity, 'mbEntity')
@ -98,19 +107,29 @@ export const useMubiao = () => {
position, position,
target_time, target_time,
targetType, targetType,
extendInfo,
}: Record<string, string | number | number[]>) => { }: Record<string, string | number | number[]>) => {
// 添加目标实体 // 添加目标实体
// console.log(window.settings, targetType, '-----') // console.log(window.settings, targetType, '-----')
const mbEntityOpt = getMBEntityOpt({ const mbEntityOpt = getMBEntityOpt({ id, targetType, extendInfo })
id,
targetType,
})
const mubiaoEntity = viewer.entities.add({ const mubiaoEntity = viewer.entities.add({
name: id, name: id,
position: Cesium.Cartesian3.fromDegrees(...(position as number[])), position: Cesium.Cartesian3.fromDegrees(
...(position as number[]),
targetType === '甲' ? 20000 : 0
),
...mbEntityOpt, ...mbEntityOpt,
}) })
if (extendInfo?.detectingPayload?.angle) {
const conic = createMBConicSensor({
entity: mubiaoEntity,
angle: extendInfo?.detectingPayload?.angle,
show: mbPayloadShowMap.get(id).detectingPayload.show,
})
mubiaoConicMap.set(id, conic)
}
return mubiaoEntity return mubiaoEntity
} }
@ -144,6 +163,10 @@ export const useMubiao = () => {
popupMap.get(id).windowClose() popupMap.get(id).windowClose()
popupMap.delete(id) popupMap.delete(id)
} }
if (mubiaoConicMap.has(id)) {
viewer.entities.remove(mubiaoConicMap.get(id))
mubiaoConicMap.delete(id)
}
} }
const updateMubiaoPos = async ( const updateMubiaoPos = async (
@ -197,6 +220,8 @@ export const useMubiao = () => {
return { return {
data, data,
checkedKeys,
getMubiaoData,
addMubiao, addMubiao,
updateMubiaoPos, updateMubiaoPos,
} }
@ -212,3 +237,34 @@ async function getMubiaoCurPos(ids: Array<string | number>) {
return [] return []
} }
} }
async function getMubiaoData() {
const checked = JSON.parse(JSON.stringify(checkedKeys.value))
// console.log(checked)
const { code, data: resData } = await getMubiao()
if (code === '200') {
data.value = [resData]
checkedKeys.value = []
getAllNodesToPayload()
nextTick(() => {
checkedKeys.value = checked
})
}
}
function getAllNodesToPayload() {
const mbList = getLeafNode(data.value[0])
mbList.forEach(node => {
const { dataId, data: nodeData } = node
const { extendInfo } = nodeData
const detectingShow =
mbPayloadShowMap.get(dataId)?.detectingPayload?.show || false
if (extendInfo) {
mbPayloadShowMap.set(dataId, {
data: toRaw(nodeData),
detectingPayload: { ...extendInfo, show: detectingShow },
})
}
})
console.log('mbPayloadShowMap', mbPayloadShowMap)
}

View File

@ -1,35 +1,65 @@
// import { h } from 'vue' // import { h } from 'vue'
import { NDataTable, NInputNumber, NSwitch } from 'naive-ui' import { NButton, NInputNumber, NSwitch } from 'naive-ui'
import { useModal } from '@/views/Content/hooks/modal' import { useModal } from '@/views/Content/hooks/modal'
import Detection from '@/views/Payload/Detection.jsx' import Detection from '@/views/Payload/Detection.jsx'
import Communication from '@/views/Payload/Communication.jsx' import Communication from '@/views/Payload/Communication.jsx'
import { updateMbPayload } from '@/api/Mubiao'
import { useEntity } from '@/hooks/entity'
import { useMubiao } from './mubiao'
const { openDetailsModal } = useModal() const { openDetailsModal } = useModal()
export const useMubiaoDetail = () => { export const useMubiaoDetail = () => {
return { showDetailsMubiao } const payloadData = ref([])
}
const data = ref([ function addCommunicationPayload(mbData) {
const { id, targetType, extendInfo } = mbData
const payLoadType = window.settings.mbDict[targetType].payload
if (payLoadType === 'radar') {
payloadData.value = [
{ {
id: 3, id,
radius: 5000, radius: null,
minimumClock: 20.0, minimumClock: null,
maximumClock: 110.0, maximumClock: 90,
minimumCone: 20.0, minimumCone: null,
maximumCone: 90.0, maximumCone: null,
height: 100, show: false,
status: true,
}, },
]) ]
} else if (payLoadType === 'conic') {
payloadData.value = [
{
id,
angle: null,
show: false,
},
]
}
}
const { mbPayloadShowMap } = useEntity()
function renderMubiaoDetailsContent(mbData) { function renderMubiaoDetailsContent(mbData) {
payloadData.value = []
const { id, targetType, extendInfo } = mbData
const payLoadType = window.settings.mbDict[targetType].payload
if (extendInfo) {
payloadData.value = [
{
id,
...extendInfo.detectingPayload,
show: mbPayloadShowMap.get(id).detectingPayload.show,
},
]
}
// return h( // return h(
// 'div', // 'div',
// {}, // {},
// Object.keys(mbData).map(key => h('div', {}, `${key}${mbData[key]}`)) // Object.keys(mbData).map(key => h('div', {}, `${key}${mbData[key]}`))
// ) // )
return () => ( return () => (
<div class="detail-container"> <div class="detail-container w-[45vw]">
<div class="detail-item-title">基本信息</div> <div class="detail-item-title">基本信息</div>
<div> <div>
{Object.keys(mbData).map(key => ( {Object.keys(mbData).map(key => (
@ -38,14 +68,65 @@ function renderMubiaoDetailsContent(mbData) {
</div> </div>
))} ))}
</div> </div>
{/* <div class="detail-item-title"></div>
*/}
<div class="flex justify-between">
<div class="detail-item-title">探测载荷</div> <div class="detail-item-title">探测载荷</div>
<Detection type="radar" data={data.value} /> {payloadData.value.length === 0 && (
<NButton
quaternary
type="primary"
onClick={() => addCommunicationPayload(mbData)}
>
添加
</NButton>
)}
</div>
{payloadData.value.length > 0 && (
<Detection target="mb" type={payLoadType} data={payloadData.value} />
)}
<div class="flex justify-end gap-2">
<NButton
type="primary"
onClick={() =>
updateMbLoad({
mbData,
detection: payloadData.value,
})
}
>
确定
</NButton>
{/* <NButton onClick={closeDetailsModal}>取消</NButton> */}
</div>
</div> </div>
) )
} }
function showDetailsMubiao(mbData) { function showDetailsMubiao(mbData) {
openDetailsModal({ openDetailsModal({
titleString: 'zb详情', titleString: 'zb详情',
contentSlot: renderMubiaoDetailsContent(mbData), contentSlot: renderMubiaoDetailsContent(mbData),
}) })
}
function updateMbLoad({ mbData, detection }) {
const { getMubiaoData } = useMubiao()
const { id, show, ...detectionData } = detection[0]
const payloadData = {
id: mbData.id,
extendInfo: {
detectingPayload: { ...detectionData },
},
}
// console.log(payloadData)
updateMbPayload(payloadData).then(res => {
if (res.code === '200') {
window.$message.success('保存成功')
getMubiaoData()
}
})
}
return { showDetailsMubiao }
} }

View File

@ -2,7 +2,6 @@
import { h } from 'vue' import { h } from 'vue'
import { NButton } from 'naive-ui' import { NButton } from 'naive-ui'
import type { TreeOption } from 'naive-ui' import type { TreeOption } from 'naive-ui'
import { getMubiao, getMubiaoPos } from '@/api/Mubiao'
// import type { DataTableColumns, DataTableRowKey } from 'naive-ui' // import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
import Tree from '@/components/Tree/index.vue' import Tree from '@/components/Tree/index.vue'
import HeatMap from './components/HeatMap/index.vue' import HeatMap from './components/HeatMap/index.vue'
@ -13,26 +12,19 @@ import { useMubiaoDetail } from './hooks/mubiaoDetail'
import { useMBTrajectory } from './components/HisTrajectory/hooks/mbTraj' import { useMBTrajectory } from './components/HisTrajectory/hooks/mbTraj'
import { useDaodan } from '../Daodan/ddHooks' import { useDaodan } from '../Daodan/ddHooks'
const { addMubiao, data } = useMubiao() const { getMubiaoData, data, addMubiao, checkedKeys } = useMubiao()
const useMbPosWS = useMuBiaoPositionWS() const useMbPosWS = useMuBiaoPositionWS()
const useMbDisappearWS = useMuBiaoDisappearWS() const useMbDisappearWS = useMuBiaoDisappearWS()
const getMubiaoData = async () => {
const { code, data: resData } = await getMubiao()
if (code === '200') {
data.value = [resData]
}
}
onMounted(() => { onMounted(() => {
getMubiaoData() getMubiaoData()
// useMuBiaoPositionWS()
}) })
const checkedKeys = ref<Array<string | number>>([]) // const checkedKeys = ref<Array<string | number>>([])
watch(checkedKeys, val => { watch(checkedKeys, val => {
console.log('watch', val)
addMubiao(val) addMubiao(val)
}) })

View File

@ -1,19 +1,50 @@
import { NDataTable, NButton, NSelect, NInputNumber, NSwitch } from 'naive-ui' import { defineExpose } from 'vue'
import {
NDataTable,
NButton,
NSelect,
NInputNumber,
NSwitch,
NTreeSelect,
} from 'naive-ui'
import { getMubiao } from '@/api/Mubiao'
export default defineComponent({ export default defineComponent({
name: 'DetectionPayload', name: 'CommunicationPayload',
props: {}, props: {
setup(props) { data: {
type: Array,
default: () => [],
},
},
setup(props, { expose }) {
const targetList = ref([])
onMounted(async () => {
const { code, data: resData } = await getMubiao()
if (code === '200') {
targetList.value = [resData]
}
})
const communicationPayloadColumns = [ const communicationPayloadColumns = [
{ {
title: '通信对象', title: '通信对象',
key: 'target', key: 'target',
render(row) { render(row) {
return ( return (
<NSelect // <NSelect
// v-model:value={row.target}
// options={[{ label: '3', value: '3' }]}
// ></NSelect>
<NTreeSelect
class="w-full"
multiple
checkable
check-strategy="child"
v-model:value={row.target} v-model:value={row.target}
options={[{ label: '3', value: '3' }]} options={targetList.value}
></NSelect> key-field="dataId"
label-field="nodeName"
></NTreeSelect>
) )
}, },
}, },
@ -26,18 +57,12 @@ export default defineComponent({
}, },
}, },
] ]
const communicationPayload = ref([
{
id: 3,
target: '3',
status: true,
},
])
return () => ( return () => (
<NDataTable <NDataTable
key={row => row.id} key={row => row.id}
columns={communicationPayloadColumns} columns={communicationPayloadColumns}
data={communicationPayload.value} data={props.data}
/> />
) )
}, },

View File

@ -1,8 +1,13 @@
import { NDataTable, NButton, NSelect, NInputNumber, NSwitch } from 'naive-ui' import { NDataTable, NButton, NSelect, NInputNumber, NSwitch } from 'naive-ui'
import { useEntity } from '@/hooks/entity'
export default defineComponent({ export default defineComponent({
name: 'DetectionPayload', name: 'DetectionPayload',
props: { props: {
target: {
type: String,
require: true,
},
type: { type: {
type: String, type: String,
default: 'radar', default: 'radar',
@ -13,12 +18,14 @@ export default defineComponent({
}, },
}, },
setup(props) { setup(props) {
const { mbPayloadShowMap, satellitePayloadShowMap } = useEntity()
const detectingPayloadColumns = { const detectingPayloadColumns = {
radar: [ radar: [
{ {
title: '垂直起始角', title: '垂直起始角',
key: 'minimumClock', key: 'minimumClock',
width: 180, // width: 140,
render(row) { render(row) {
return ( return (
<NInputNumber <NInputNumber
@ -44,7 +51,7 @@ export default defineComponent({
{ {
title: '水平起始角', title: '水平起始角',
key: 'minimumCone', key: 'minimumCone',
width: 180, // width: 140,
render(row) { render(row) {
return ( return (
<NInputNumber <NInputNumber
@ -57,7 +64,7 @@ export default defineComponent({
{ {
title: '水平终止角', title: '水平终止角',
key: 'maximumCone', key: 'maximumCone',
width: 180, // width: 140,
render(row) { render(row) {
return ( return (
<NInputNumber <NInputNumber
@ -82,14 +89,19 @@ export default defineComponent({
}, },
{ {
title: '是否开启', title: '是否开启',
key: 'status', key: 'show',
width: 120, width: 120,
render(row) { render(row) {
return <NSwitch v-model:value={row.status}></NSwitch> return (
<NSwitch
v-model:value={row.show}
onUpdate:value={() => changePayloadStatus(row)}
></NSwitch>
)
}, },
}, },
], ],
corner: [ conic: [
// { // {
// title: '', // title: '',
// key: 'type', // key: 'type',
@ -152,15 +164,30 @@ export default defineComponent({
// }, // },
{ {
title: '是否开启', title: '是否开启',
key: 'status', key: 'show',
width: 120, width: 120,
render(row) { render(row) {
return <NSwitch v-model:value={row.status}></NSwitch> return (
<NSwitch
v-model:value={row.show}
onUpdate:value={() => changePayloadStatus(row)}
></NSwitch>
)
}, },
}, },
], ],
} }
function changePayloadStatus(row) {
const { id, show } = row
const mapDict = {
mb: mbPayloadShowMap,
satellite: satellitePayloadShowMap,
}
const map = mapDict[props.target]
map.has(id) && (map.get(id).detectingPayload.show = show)
}
return () => ( return () => (
<NDataTable <NDataTable
key={row => row.id} key={row => row.id}

View File

@ -1,10 +1,13 @@
import { ref } from 'vue'
import maplibregl from 'maplibre-gl' import maplibregl from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css' import 'maplibre-gl/dist/maplibre-gl.css'
import { style } from '../style' import { style } from '../style'
const zoom = ref(0)
export function useMapbox() { export function useMapbox() {
return { return {
initMapbox, initMapbox,
zoom,
} }
} }
@ -16,7 +19,7 @@ function initMapbox() {
style, // style URL style, // style URL
center: [121, 19], // starting position [lng, lat] center: [121, 19], // starting position [lng, lat]
zoom: 5, zoom: zoom.value,
}) })
map.on('load', function () { map.on('load', function () {
@ -40,6 +43,10 @@ function initMapbox() {
// }) // })
}) })
map.on('zoom', () => {
zoom.value = map.getZoom()
})
map.on('click', e => { map.on('click', e => {
const features = map.queryRenderedFeatures(e.point) const features = map.queryRenderedFeatures(e.point)
console.log(features) console.log(features)

View File

@ -21,7 +21,7 @@ export default defineComponent({
const { model, showPlace, addPlaceName, initViewer, clickPoint } = const { model, showPlace, addPlaceName, initViewer, clickPoint } =
usePlaceName() usePlaceName()
const { initMapbox } = useMapbox() const { initMapbox, zoom } = useMapbox()
const { initOpenLayer } = useOpenLayer() const { initOpenLayer } = useOpenLayer()
onMounted(async () => { onMounted(async () => {
initMapbox() initMapbox()
@ -32,6 +32,7 @@ export default defineComponent({
return () => ( return () => (
<div class="h-full w-full"> <div class="h-full w-full">
<div id="place-earth" class="h-full w-full"></div> <div id="place-earth" class="h-full w-full"></div>
<div class="absolute right-2 top-2 text-black">zoom:{zoom.value}</div>
<div class="absolute left-0 top-0 p-2"> <div class="absolute left-0 top-0 p-2">
<NButton class="z-10" type="primary" onClick={() => addPlaceName()}> <NButton class="z-10" type="primary" onClick={() => addPlaceName()}>
添加地名 添加地名

View File

@ -101,7 +101,7 @@ export const style = {
openmaptiles: { openmaptiles: {
type: 'vector', type: 'vector',
scheme: 'tms', scheme: 'tms',
tiles: ['http://192.168.10.187:8080/tmp/pbfMulti/{z}/{x}/{y}.pbf'], tiles: ['http://192.168.10.143:2024/api/tmp/pbfMulti/{z}/{x}/{y}.pbf'],
}, },
}, },
// tiles: [ // tiles: [
@ -464,14 +464,14 @@ export const style = {
metadata: {}, metadata: {},
source: 'openmaptiles', source: 'openmaptiles',
'source-layer': 'admin', 'source-layer': 'admin',
minzoom: 5, // minzoom: 1,
filter: ['all', ['==', 'admin_level', 2]], filter: ['all', ['==', 'admin_level', 2]],
layout: { layout: {
visibility: 'visible', visibility: 'visible',
}, },
paint: { paint: {
'line-color': '#aaaaaa', 'line-color': '#aaaaaa',
'line-width': ['interpolate', ['linear'], ['zoom'], 4, 0.5, 7, 2], 'line-width': ['interpolate', ['linear'], ['zoom'], 4, 1, 7, 2],
}, },
}, },
{ {
@ -480,7 +480,7 @@ export const style = {
metadata: {}, metadata: {},
source: 'openmaptiles', source: 'openmaptiles',
'source-layer': 'admin', 'source-layer': 'admin',
minzoom: 6, minzoom: 3,
filter: ['all', ['==', 'admin_level', 4]], filter: ['all', ['==', 'admin_level', 4]],
layout: { layout: {
visibility: 'visible', visibility: 'visible',
@ -497,7 +497,7 @@ export const style = {
metadata: {}, metadata: {},
source: 'openmaptiles', source: 'openmaptiles',
'source-layer': 'admin', 'source-layer': 'admin',
minzoom: 9, minzoom: 6,
filter: ['all', ['==', 'admin_level', 5]], filter: ['all', ['==', 'admin_level', 5]],
layout: { layout: {
visibility: 'visible', visibility: 'visible',
@ -551,13 +551,55 @@ export const style = {
}, },
interactive: true, interactive: true,
}, },
{ {
id: 'province_point', id: 'province_point',
type: 'symbol', type: 'symbol',
metadata: {}, metadata: {},
source: 'openmaptiles', source: 'openmaptiles',
'source-layer': 'place', 'source-layer': 'place',
minzoom: 4,
filter: ['all', ['==', 'type', 'state']],
layout: {
'text-field': '{name}',
'text-font': ['Open Sans Regular'],
'text-padding': 5,
'text-rotation-alignment': 'map',
// 'symbol-placement': 'line-center',
// 'text-pitch-alignment': 'viewport',
// 'text-size': 18,
// 'text-max-width': 6.25,
'text-size': [
'interpolate',
['linear', 1],
['zoom'],
4.99,
13,
5,
14,
7,
15,
],
},
paint: {
'text-halo-color': 'rgb(200, 200, 200)',
'text-halo-width': 1,
'text-color': {
stops: [
[2, 'hsl(302, 16%, 36%)'],
[10, 'hsl(273, 33%, 22%)'],
],
},
'text-halo-blur': 0.5,
},
interactive: true,
},
{
id: 'county_point',
type: 'symbol',
metadata: {},
source: 'openmaptiles',
'source-layer': 'place',
minzoom: 7, minzoom: 7,
filter: ['all', ['==', 'type', 'county']], filter: ['all', ['==', 'type', 'county']],
layout: { layout: {

View File

@ -1,24 +1,53 @@
import { toRaw } from 'vue'
import { useModal } from '@/views/Content/hooks/modal' import { useModal } from '@/views/Content/hooks/modal'
import { NDataTable, NButton, NSelect, NInputNumber, NSwitch } from 'naive-ui' import { NButton } from 'naive-ui'
import Detection from '@/views/Payload/Detection.jsx' import Detection from '@/views/Payload/Detection.jsx'
import Communication from '@/views/Payload/Communication.jsx' import Communication from '@/views/Payload/Communication.jsx'
import { useEntity } from '@/hooks/entity'
import { updateSatellitePayload } from '@/api/Satellite'
import { useSatellite } from '../hooks/satellite'
const { openDetailsModal } = useModal() const { openDetailsModal } = useModal()
export function showDetailsSatellite(option) { export function showDetailsSatellite(option) {
const detectingPayload = ref([ const { extendInfo, id } = option
{
id: 3, const detectingPayload = ref([])
angle: 30, function addDetectingPayload() {
// xHalfAngle: 20, detectingPayload.value.push({
// yHalfAngle: 25, id,
// type: '', angle: null,
status: true, show: false,
}, })
]) }
const communicationPayload = ref([])
function addCommunicationPayload() {
communicationPayload.value.push({
id,
target: [],
show: false,
})
}
const { satellitePayloadShowMap } = useEntity()
if (extendInfo?.detectingPayload) {
detectingPayload.value.push({
id,
angle: extendInfo.detectingPayload.angle,
show: satellitePayloadShowMap.get(id).detectingPayload.show,
})
}
if (extendInfo?.communicationPayload) {
communicationPayload.value.push({
id,
target: extendInfo.communicationPayload,
show: satellitePayloadShowMap.get(id).communicationPayload.show,
})
}
openDetailsModal({ openDetailsModal({
titleString: '' + option.name + ' 详情', titleString: '' + option.name + ' 详情',
contentSlot: () => ( contentSlot: () => (
<div class="detail-container"> <div class="detail-container w-[45vw]">
<div class="detail-item-title">基本信息</div> <div class="detail-item-title">基本信息</div>
<div> <div>
<div>卫星编号{option.name}</div> <div>卫星编号{option.name}</div>
@ -31,19 +60,79 @@ export function showDetailsSatellite(option) {
</div> </div>
</div> </div>
</div> </div>
<div class="detail-item-title">探测载荷</div> {/* <div class="detail-item-title">探测载荷</div> */}
<Detection type="corner" data={detectingPayload.value} />
<div class="flex justify-between"> <div class="flex justify-between">
<div class="detail-item-title">通信载荷</div> <div class="detail-item-title">探测载荷</div>
<NButton quaternary type="primary"> {detectingPayload.value.length === 0 && (
<NButton quaternary type="primary" onClick={addDetectingPayload}>
添加 添加
</NButton> </NButton>
)}
</div>
{detectingPayload.value.length > 0 && (
<Detection
target="satellite"
type="conic"
data={detectingPayload.value}
/>
)}
<div class="flex justify-between">
<div class="detail-item-title">通信载荷</div>
{communicationPayload.value.length === 0 && (
<NButton
quaternary
type="primary"
onClick={addCommunicationPayload}
>
添加
</NButton>
)}
</div>
{communicationPayload.value.length > 0 && (
<Communication data={communicationPayload.value} />
)}
<div class="flex justify-end gap-2">
<NButton
type="primary"
onClick={() =>
updateSatelliteLoad({
sat: option,
detection: detectingPayload.value,
communication: communicationPayload.value,
})
}
>
确定
</NButton>
{/* <NButton onClick={closeDetailsModal}>取消</NButton> */}
</div> </div>
<Communication />
</div> </div>
), ),
}) })
} }
function updateSatelliteLoad({ sat: sateData, detection, communication }) {
// console.log(sateData, payload, communicationRef.value.communicationPayload)
if (!detection[0] && !communication[0]) {
return
}
const { getSatelliteList } = useSatellite()
const payloadData = {
id: sateData.id,
extendInfo: {
detectingPayload: detection[0] ? { angle: detection[0].angle } : null,
communicationPayload: communication[0]
? toRaw(communication[0].target)
: null,
},
}
// console.log(payloadData)
updateSatellitePayload(payloadData).then(res => {
if (res.code === '200') {
window.$message.success('保存成功')
getSatelliteList()
}
})
}
// export default defineComponent({ // export default defineComponent({
// name: 'SatDetail', // name: 'SatDetail',

View File

@ -1,6 +1,9 @@
import SatelliteEntity from '@/js/SatelliteEntity' import SatelliteEntity from '@/js/SatelliteEntity'
import { difference } from 'lodash' import { difference } from 'lodash'
import { useEntity } from '@/hooks/entity' import { useEntity } from '@/hooks/entity'
import { useTree } from '@/utils/tree'
import { getSatellite } from '@/api/Satellite'
// import CreateFrustum from '@/js/Sensor' // import CreateFrustum from '@/js/Sensor'
interface ISatellite { interface ISatellite {
@ -14,9 +17,11 @@ interface IBaseFilterParam {
params: Array<string | number> params: Array<string | number>
paramName: string paramName: string
} }
const { filterTreeNodeByField } = useTree()
const satelliteList = ref<ISatellite[]>([]) const satelliteList = ref<ISatellite[]>([])
const checkedKeys = ref<Array<string | number>>([])
const { satelliteMap, showOrHideLoad } = useEntity() const { satelliteMap, showOrHideLoad, satellitePayloadShowMap } = useEntity()
const showPoint = ref(true) const showPoint = ref(true)
function showPointUnderSat(id?: string) { function showPointUnderSat(id?: string) {
@ -54,14 +59,19 @@ export function useSatellite() {
}) })
} }
// 创建satellite entity 实例 // 创建satellite entity 实例
function addSatellite({ tle }: ISatellite) { function addSatellite({ id, tle }: ISatellite) {
const satellite = new SatelliteEntity(tle) const satellite = new SatelliteEntity(tle)
const cesiumSateEntity = satellite.createSatelliteEntity() const cesiumSateEntity = satellite.createSatelliteEntity()
// const result = viewer.entities.add(cesiumSateEntity) // const result = viewer.entities.add(cesiumSateEntity)
setTimeout(() => { setTimeout(() => {
// satellite.sensorType = Math.random() > 0.5 ? 'conic' : 'rectangle' // satellite.sensorType = Math.random() > 0.5 ? 'conic' : 'rectangle'
satellite.sensor = showOrHideLoad.value const satPayload = satellitePayloadShowMap.get(id)
if (satPayload && satPayload.detectingPayload) {
satPayload.detectingPayload.angle &&
(satellite.sensorAngle = satPayload.detectingPayload.angle)
satPayload.detectingPayload.show && (satellite.sensor = true)
}
}, 1000) }, 1000)
// viewer.clock.multiplier = 100 // viewer.clock.multiplier = 100
@ -99,27 +109,76 @@ export function useSatellite() {
} }
} }
return { satelliteList, addSatellites, showPoint, showPointUnderSat } return {
satelliteList,
checkedKeys,
getSatelliteList,
addSatellites,
showPoint,
showPointUnderSat,
}
} }
function filterTreeNodeByField({ // function filterTreeNodeByField({
treeData, // treeData,
params, // params,
paramName, // paramName,
}: IBaseFilterParam): Array<ISatellite> { // }: IBaseFilterParam): Array<ISatellite> {
return treeData.reduce((acc, node) => { // return treeData.reduce((acc, node) => {
if (params.includes(node[paramName]) && !node.children) { // if (params.includes(node[paramName]) && !node.children) {
acc.push(node) // acc.push(node)
} // }
if (node.children) { // if (node.children) {
acc = acc.concat( // acc = acc.concat(
filterTreeNodeByField({ // filterTreeNodeByField({
treeData: node.children, // treeData: node.children,
params, // params,
paramName, // paramName,
// })
// )
// }
// return acc
// }, [])
// }
async function getSatelliteList() {
const checked = JSON.parse(JSON.stringify(checkedKeys.value))
const sateRes = await getSatellite()
const { data, code } = sateRes
if (code === '200') {
checkedKeys.value = []
satelliteList.value = data
getAllNodesToPayload()
nextTick(() => {
checkedKeys.value = checked
}) })
)
} }
return acc // console.log('data,code', data, code)
}, []) }
function getAllNodesToPayload() {
// const mbList = getLeafNodeIds(satelliteList.value, 'dataId')
satelliteList.value.forEach(satellite => {
if (satellite.extendInfo) {
const { detectingPayload, communicationPayload } = satellite.extendInfo
const detectingShow =
satellitePayloadShowMap.get(satellite.id)?.detectingPayload?.show ||
false
const communicationShow =
satellitePayloadShowMap.get(satellite.id)?.communicationPayload?.show ||
false
satellitePayloadShowMap.set
satellitePayloadShowMap.set(satellite.id, {
detectingPayload: detectingPayload
? { ...detectingPayload, show: detectingShow }
: null,
communicationPayload: communicationPayload
? { ...communicationPayload, show: communicationShow }
: null,
})
}
})
console.log('satellitePayloadShowMap', satellitePayloadShowMap)
} }

View File

@ -2,27 +2,16 @@
import type { TreeOption } from 'naive-ui' import type { TreeOption } from 'naive-ui'
import { NButton } from 'naive-ui' import { NButton } from 'naive-ui'
import Tree from '@/components/Tree/index.vue' import Tree from '@/components/Tree/index.vue'
import { getSatellite } from '@/api/Satellite'
import { useSatellite } from './hooks/satellite' import { useSatellite } from './hooks/satellite'
import { showDetailsSatellite } from './components/SatDetail' import { showDetailsSatellite } from './components/SatDetail'
const { satelliteList, addSatellites } = useSatellite() const { satelliteList, checkedKeys, getSatelliteList, addSatellites } =
useSatellite()
onMounted(async () => { onMounted(async () => {
getSatelliteList() getSatelliteList()
}) })
async function getSatelliteList() {
const sateRes = await getSatellite()
const { data, code } = sateRes
if (code === '200') {
satelliteList.value = data
}
// console.log('data,code', data, code)
}
const checkedKeys = ref<Array<string | number>>([])
watch(checkedKeys, val => { watch(checkedKeys, val => {
addSatellites(val) addSatellites(val)
}) })