skyeyesystem/frontend/Skyeye-sys-ui/src/views/home/components/task-manage/index.js

2157 lines
65 KiB
JavaScript
Raw Normal View History

2026-01-25 16:02:00 +08:00
import { lodLayer, viewer } from '@/components/dt-scene/index.vue'
// 新增空间态势统计
// 台风列表
import SceneInfo from '@/mixin/scene-info'
import LeftSlide from '@/components/LeftSlide.vue'
import { mapGetters, mapMutations } from 'vuex'
2026-01-25 16:02:00 +08:00
import * as DT from 'dt-sdk'
import { ICON_MODE } from '@/enum'
import { getUnionId } from '@/utils'
import { AreaPlotManager } from '@/utils/area-plot-manager'
import {
addTaskFast,
deleteTaskItem, editTaskName, getLoaderEnabledList, getTaskEditItemDetail,
getTaskListData, getUavCurrentHeight, getUavEnabledListData, previewTaskFast,
reRunTask, flyTaskUavCommand, stopTaskFly
2026-01-25 16:02:00 +08:00
} from '@/api/task'
2026-01-28 21:08:52 +08:00
import { getLastStatus } from '@/api/device'
2026-01-25 16:02:00 +08:00
import LineTarget from './lineTarget'
import UavTarget from '../twin-situation/uavTarget'
2026-01-25 16:02:00 +08:00
let theViewerTools = null
let pickHandler = null
let startPoint = null
let endPoint = null
let linePlot = null
let airlineCollection = {}
let previewEntities = []
let taskListResource = []
let taskUavCollection = {}
let taskPlanAreaCollection = {}
let sceneEntity = {}
2026-01-25 16:02:00 +08:00
export default {
name: 'TaskManage',
props: {
visible: Boolean,
sceneComplete: Boolean,
readOnly: {
type: Boolean,
default: false
},
},
components: {
LeftSlide
},
mixins: [SceneInfo],
data() {
return {
IconDelete: require('@/assets/img/platform/delete.png'),
rightArrow: require('@/assets/img/platform/right-arrow.png'),
startDrawIcon: require('@/assets/img/platform/start-draw.png'),
endDrawIcon: require('@/assets/img/platform/end-draw.png'),
visibleLocale: false,
taskList: {
visible: true,
data: [
// {
// id: 1,
// executeIcon: 'ri-dv-line',
// executeName: '无人机1',
// typeIcon: 'el-icon-camera',
// name: '拍照任务',
// check: false,
// status: 0,
// uavCompletion: 30,
// isFinish: false,
// taskProgressName: '30%',
// executeClass: '2',
// taskTime: '2024-12-28 14:00:00'
// },
2026-01-25 16:02:00 +08:00
]
},
taskForm: {
show: false,
visible: false,
form: {},
title: '新增任务'
},
form: {
id: '',
targetChoose: undefined,
loaderType: undefined,
direction: 1,
startAltitude: undefined,
imageLight: undefined,
imageBit: 0,
headingDiff: 0,
polarization: '0',
name: '',
ratio: '',
airlineList: [],
heightMode: 1,
mode: undefined,
width: undefined,
theta: undefined,
flyHeight: 300,
initSpeed: 10,
targetList: [],
loader: undefined,
uav: undefined,
routepoints: [],
waveAngle: 20,
waveRotation: 20,
autoFocus: 0,
imageMode: '0',
2026-01-25 16:02:00 +08:00
moto: 0,
// startPoint: {
// lon: undefined,
// lat: undefined,
// },
// endPoint: {
// lon: undefined,
// lat: undefined,
// }
},
rules: {
name: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
startAltitude: [{ required: true, message: '请输入起飞点高度', trigger: 'blur' }],
imageLight: [{ required: true, message: '请输入图片亮度', trigger: 'blur' }],
mode: [{ required: true, message: '请选择飞行模式', trigger: 'change' }],
imageMode: [{ required: true, message: '请选择成像模式', trigger: 'change' }],
2026-01-25 16:02:00 +08:00
targetList: [{ required: true, message: '请选择区域', trigger: 'change' }],
uav: [{ required: true, message: '请选择无人机', trigger: 'change' }],
loader: [{ required: true, message: '请选择载荷', trigger: 'change' }],
loaderType: [{ required: true, message: '请选择载荷类型', trigger: 'change' }],
ratio: [{ required: true, message: '请选择分辨率', trigger: 'change' }],
},
settingExpand: false,
duringDraw: false,
duringPick: false,
flyModeOptions: [
{
label: '点目标模式',
value: 1
},
{
label: '区域目标模式',
value: 2
},
{
label: '航线创建',
value: 3
}
],
drawOptions: [
{
label: '点',
value: '点'
},
{
label: '区域',
value: '多边形'
}
],
loaderTypeOptions: [
{
label: '可见光',
value: 1
},
{
label: '红外',
value: 2
},
{
label: '多光谱',
value: 3
},
{
label: '激光雷达',
value: 4
},
{
label: 'SAR',
value: 'SAR'
}
],
loaderOptions: [],
ratioOptions: [
{
label: '0.1m',
value: 0.1
},
{
label: '0.3m',
value: 0.3
},
{
label: '1m',
value: 1
},
{
label: '3m',
value: 3
},
],
directionOptions: [
{
label: '左侧视',
value: 1
},
{
label: '右侧视',
value: -1
}
],
ratioMap: {
'0.1': {
width: 317.5523063, // y 方向幅宽
length: 0.1, // x 方向幅宽
theta: 55.07020714, // 下视角
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
},
'0.15': {
width: 2597.873969, // y 方向幅宽
length: 0.1, // x 方向幅宽
theta: 83.1449936, // 下视角
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
},
2026-01-25 16:02:00 +08:00
'0.2': {
width: 2597.87396, // y 方向幅宽
2026-01-25 16:02:00 +08:00
length: 0.1, // x 方向幅宽
theta: 83.1449936, // 下视角
2026-01-25 16:02:00 +08:00
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
},
'0.3': {
width: 4200.426476, // y 方向幅宽
2026-01-25 16:02:00 +08:00
length: 0.1, // x 方向幅宽
theta: 85.0964241, // 下视角
2026-01-25 16:02:00 +08:00
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
},
'0.5': {
width: 5009.03516, // y 方向幅宽
length: 0.1, // x 方向幅宽
theta: 84.99811885, // 下视角
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
},
'1': {
width: 3329.435, // y 方向幅宽
length: 0.1, // x 方向幅宽
theta: 83.14499, // 下视角
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
},
'3': {
width: 3329.435, // y 方向幅宽
length: 0.1, // x 方向幅宽
theta: 83.14499, // 下视角
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
},
'10': {
width: 6808.414439, // y 方向幅宽
length: 0.1, // x 方向幅宽
theta: 86.56482716, // 下视角
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
},
'gmti': {
width: 6808.414439, // y 方向幅宽
length: 0.1, // x 方向幅宽
theta: 86.56482716, // 下视角
reserved: 100, //预留距离 (m)
direction: 1, //侧视方向
polarization: '0', //极化方式
2026-01-25 16:02:00 +08:00
}
},
heightModeOptions: [
{
label: '海拔高度',
value: 1
},
{
label: '相对起飞点高度',
value: 2
},
{
label: '相对地形高度',
value: 3
},
],
uavOptions: [],
duringAirlinePick: false,
calculateMap: [
{
minSpeed: 5,
maxSpeed: 10,
'0.1': {
minDistance: 105,
maxDistance: 1760,
defaultAngle: 70.91580209,
},
'0.15': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 70.91580209,
},
2026-01-25 16:02:00 +08:00
'0.2': {
minDistance: 105,
maxDistance: 5000,
2026-01-25 16:02:00 +08:00
defaultAngle: 80.12850849,
},
'0.3': {
minDistance: 105,
maxDistance: 7000,
2026-01-25 16:02:00 +08:00
defaultAngle: 83.14499366,
},
'1': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 83.14499366,
},
'3': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 83.14499366,
},
'10': {
minDistance: 105,
maxDistance: 10000,
defaultAngle: 82.14499366,
},
'gmti': {
minDistance: 105,
maxDistance: 10000,
defaultAngle: 82.14499366,
2026-01-25 16:02:00 +08:00
}
},
{
minSpeed: 10,
maxSpeed: 15,
'0.1': {
minDistance: 105,
maxDistance: 1192,
defaultAngle: 62.52119039,
},
'0.15': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 62.52119039,
},
2026-01-25 16:02:00 +08:00
'0.2': {
minDistance: 105,
maxDistance: 5000,
2026-01-25 16:02:00 +08:00
defaultAngle: 75.41290323,
},
'0.3': {
minDistance: 105,
maxDistance: 7000,
2026-01-25 16:02:00 +08:00
defaultAngle: 82.53841873,
},
'1': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 83.14499366,
},
'3': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 83.14499366,
},
'10': {
minDistance: 105,
maxDistance: 10000,
defaultAngle: 82.14499366,
},
'gmti': {
minDistance: 105,
maxDistance: 10000,
defaultAngle: 82.14499366,
2026-01-25 16:02:00 +08:00
}
},
{
minSpeed: 15,
maxSpeed: 20,
'0.1': {
minDistance: 105,
maxDistance: 910,
defaultAngle: 55.07020714,
},
'0.15': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 55.07020714,
},
2026-01-25 16:02:00 +08:00
'0.2': {
minDistance: 105,
maxDistance: 5000,
2026-01-25 16:02:00 +08:00
defaultAngle: 70.91580209,
},
'0.3': {
minDistance: 105,
maxDistance: 7000,
2026-01-25 16:02:00 +08:00
defaultAngle: 80.12850849,
},
'1': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 83.14499366,
},
'3': {
minDistance: 105,
maxDistance: 5000,
defaultAngle: 83.14499366,
},
'10': {
minDistance: 105,
maxDistance: 10000,
defaultAngle: 82.14499366,
},
'gmti': {
minDistance: 105,
maxDistance: 10000,
defaultAngle: 82.14499366,
2026-01-25 16:02:00 +08:00
}
}
],
minDistance: 105,
maxDistance: 1760,
maxAngle: 80,
minAngle: 10,
minWaveAngle: 1,
maxWaveAngle: 10,
airlineCreateInfo: {
during: false,
id: undefined
},
lastLimitUpdate: {
index: -1,
ratio: undefined
},
editName: {
visible: false,
name: '',
id: '',
loading: false
},
nameRules: {
name: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
},
uavReady: false,
loaderReady: false,
taskLineDetail: {
visible: false,
title: '航线详情',
data: []
},
currentUavInfo: {
lon: undefined,
lat: undefined,
height: undefined
},
previewLoading: false,
imageModeOptions: [
{
label: '条带',
value: 0
},
{
label: 'GMTI',
value: 4
}
],
2026-01-25 16:02:00 +08:00
focusOptions: [
{
label: '否',
value: 0
},
{
label: '是',
value: 1
}
],
motoOptions: [
{
label: '否',
value: 0
},
{
label: '是',
value: 1
}
],
emptyImg: require('@/assets/img/common/empty.svg'),
2026-01-25 16:02:00 +08:00
}
},
computed: {
...mapGetters([
'currentTime',
'sarResolution',
'sarResolutionOptions',
'jobMode',
'jobModeOptions',
'jobStatus',
'polarization',
'polarizationOptions',
'sarImageModeOptions',
2026-01-25 16:02:00 +08:00
]),
isIconModeLarge() {
return this.iconMode === ICON_MODE.LARGE
},
readyUavLocation() {
return this.uavReady && this.loaderReady
}
},
watch: {
visible: {
handler: function (nv) {
if (nv) {
this.visibleLocale = nv
}
},
immediate: true,
},
visibleLocale(nv) {
if (!nv) {
if (lodLayer) {
lodLayer.removeAll()
viewer.entities.removeAll()
}
this.$emit('update:visible', false)
}
},
sceneComplete: {
handler: function (nv) {
if (nv && this.visibleLocale) {
}
},
immediate: true,
},
'taskForm.visible'(nv) {
if (nv) {
this.taskList.visible = false
} else {
if (this.visibleLocale) {
this.taskList.visible = true
}
if (startPoint) {
viewer.entities.remove(startPoint)
startPoint = null
}
if (endPoint) {
viewer.entities.remove(endPoint)
endPoint = null
}
console.log('走这一步了吗')
if (theViewerTools) {
theViewerTools.destroy()
}
theViewerTools = null
// this.$nextTick(() => {
// this.form = {
// id: '',
// targetChoose: undefined,
// loaderType: undefined,
// direction: 1,
// name: '',
// ratio: '',
// heightMode: 1,
// mode: undefined,
// flyHeight: 300,
// initSpeed: 10,
// targetList: [],
// loader: undefined,
// uav: undefined,
// routepoints: [],
// }
// })
}
},
'form.targetList': {
handler: function (newValue, oldValue) {
if (newValue.length && this.taskForm.visible && this.$refs.form) {
this.$refs.form.validateField('targetList')
}
},
deep: true
},
readyUavLocation(nv) {
if (nv) {
// this.refreshUavHeight()
}
}
},
created() {
this.getLoaderData()
this.getList()
this.getUavList()
// TODO 临时
// this.onLoaderTypeChange('SAR')
},
mounted() {
// this.openAddForm()
},
beforeDestroy() {
taskListResource = []
this.removeAllAirline()
this.removePreviewLine()
this.taskForm.visible = false
if (theViewerTools) {
theViewerTools.destroy()
}
theViewerTools = null
pickHandler = null
if (lodLayer) {
// lodLayer.removeAll()
// viewer.entities.removeAll()
}
viewer.entities.removeAll()
2026-01-25 16:02:00 +08:00
startPoint = null
endPoint = null
if (linePlot) {
linePlot.destroy()
linePlot = null
}
for (let key in taskPlanAreaCollection) {
if (taskPlanAreaCollection[key]) {
taskPlanAreaCollection[key].forEach(item => {
viewer.entities.remove(item)
})
}
}
for (let key in taskUavCollection) {
if (taskUavCollection[key]) {
taskUavCollection[key].forEach(item => {
item.destroy()
})
}
}
for (let key in sceneEntity) {
if (sceneEntity[key]) {
viewer.entities.remove(sceneEntity[key])
}
}
sceneEntity = {}
taskPlanAreaCollection = {}
taskUavCollection = {}
2026-01-25 16:02:00 +08:00
},
methods: {
...mapMutations('app', ['SET_MENUS_CHOSE']),
// #region 任务启动部分代码迁移
reRunTask(info) {
if (info.status !== 2) return
this.$confirm('确定重新执行吗', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(res => {
reRunTask({ id: info.id }).then(res => {
if (res.data.code === 200) {
console.log('重新运行结果', res)
this.$message.success('任务重新执行成功')
this.getList()
this.SET_MENUS_CHOSE('1')
// let data = res.data.data
// data.check = data.status === 1
// data.statusName = this.jobStatus[data.status + '']
// data.uavList.forEach(child => {
// if (!child.trailList) {
// child.trailList = []
// }
// child.jobName = data.name
// })
// this.taskList.data.unshift({
// id: data.id,
// beginTime: data.beginTime,
// check: data.check,
// endTime: data.endTime,
// mode: data.mode,
// name: data.name,
// status: data.status,
// statusName: data.statusName,
// })
// taskListResource.unshift(data)
// this.addUavToScene(data)
// this.addTaskPlanArea(data.pointList, data.id, data.name)
} else {
this.$message.error(res.data.message)
}
})
})
},
stopTask(info, index) {
this.$confirm('确定结束任务吗', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(res => {
stopTaskFly({ id: info.id }).then(res => {
if (res.data.code === 200) {
// info.status = 2
this.getList()
// info.statusName = this.jobStatus[info.status + '']
this.$message.success('任务已结束!')
} else {
this.$message.error(res.data.message)
}
})
})
},
makeTaskUavFly(info, index) {
this.$confirm('确定执行吗', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(res => {
flyTaskUavCommand({ id: info.id }).then(res => {
if (res.data.code === 200) {
// info.status = 1
// info.check = false
// info.statusName = this.jobStatus[info.status + '']
// this.toggleTaskSceneShow(info, index)
// this.taskList.data.forEach((child, childIndex) => {
// if (child.check && child.status === 2) {
// this.toggleTaskSceneShow(child, childIndex)
// }
// })
this.$message.success('起飞成功')
this.SET_MENUS_CHOSE('1')
} else {
this.$message.error(res.data.message)
}
})
})
},
toggleTaskSceneShow(info, index) {
console.log(5555555555);
if (info.check) {
info.check = false;
taskListResource[index].check = false
this.removeTaskTarget(info.id);
} else {
this.addUavToScene(taskListResource[index])
this.addTaskPlanArea(taskListResource[index].pointList, info.id, info.name)
info.check = true
}
},
addTaskPlanArea(data, taskId, taskName) {
taskPlanAreaCollection[taskId] = []
let allPositions = []
let centerLon = 0
let centerLat = 0
data.forEach((item, index) => {
if (item.length > 1) {
let positions = []
item.forEach(child => {
positions.push(DT.Cesium.Cartesian3.fromDegrees(child.longitude, child.latitude))
})
positions.push(DT.Cesium.Cartesian3.fromDegrees(item[0].longitude, item[0].latitude))
allPositions = allPositions.concat(positions)
let entity = viewer.entities.add({
position: positions[0],
label: {
text: `${taskName}任务-规划区域${index + 1}`,
disableDepthTestDistance: 10000,
font: '14px sans-serif',
fillColor: DT.Cesium.Color.RED,
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
verticalOrigin: DT.Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new DT.Cesium.Cartesian2(0, -10),
scaleByDistance: new DT.Cesium.NearFarScalar(0, 1, 1, 0.8),
distanceDisplayCondition: new DT.Cesium.DistanceDisplayCondition(0, 10000),
showBackground: true,
backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(255,255,255,0.6)')
},
polyline: {
positions: positions,
width: 2,
arcType: DT.Cesium.ArcType.NONE,
material: DT.Cesium.Color.RED,
depthFailMaterial: DT.Cesium.Color.RED,
disableDepthTestDistance: 10000,
zIndex: -1
}
})
taskPlanAreaCollection[taskId].push(entity)
} else if (item.length === 1) {
let position = DT.Cesium.Cartesian3.fromDegrees(item[0].longitude, item[0].latitude)
allPositions.push(position)
let entity = viewer.entities.add({
position,
label: {
text: `${taskName}任务-规划区域${index + 1}`,
disableDepthTestDistance: 10000,
font: '14px sans-serif',
fillColor: DT.Cesium.Color.RED,
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
pixelOffset: new DT.Cesium.Cartesian2(10, 0),
showBackground: true,
backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(255,255,255,0.6)')
},
point: {
pixelSize: 4,
color: DT.Cesium.Color.RED,
disableDepthTestDistance: 10000
}
})
taskPlanAreaCollection[taskId].push(entity)
}
})
if (allPositions.length > 0) {
let cat = DT.Cesium.Cartographic.fromCartesian(allPositions[0])
allPositions.push(DT.Cesium.Cartesian3.fromRadians(cat.longitude, cat.latitude, 2000))
viewer.cesiumViewer.camera.flyToBoundingSphere(DT.Cesium.BoundingSphere.fromPoints(allPositions), {
duration: 0.1,
offset: new DT.Cesium.HeadingPitchRange(0, -Math.PI / 2, 0),
})
}
},
addUavToScene(info) {
let arr = []
info.uavList.forEach(item => {
console.log(viewer, item, 8888);
let uav = new UavTarget(viewer, item)
arr.push(uav)
})
taskUavCollection[info.id] = arr
},
removeTaskTarget(taskId) {
if (taskPlanAreaCollection[taskId]) {
taskPlanAreaCollection[taskId].forEach(item => {
viewer.entities.remove(item)
})
taskPlanAreaCollection[taskId] = null
}
if (taskUavCollection[taskId]) {
taskUavCollection[taskId].forEach(item => {
item.destroy()
})
taskUavCollection[taskId] = null
}
},
toggleHistoryPicture(data) {
if (taskUavCollection[data.jobId]) {
let find = taskUavCollection[data.jobId].find(item => item.uavId + '' === data.uavId + '')
if (find) {
find.toggleLoaderPictureVisible(data.payloadId, data.fileId)
}
}
},
// #endregion
handleCommand(command, item) {
switch (command) {
case 'edit':
this.editTaskName(item)
break;
case 'copy':
this.copyTask(item)
break;
case 'remove':
this.deleteTask(item)
break;
}
},
2026-01-25 16:02:00 +08:00
dealStatusColor(name) {
if (name === '执行中') {
return '#6ae965'
} else if (name === '已完成') {
return '#336dff'
}
},
getUavList() {
this.uavReady = false
getUavEnabledListData().then(res => {
if (res.data.code === 200) {
console.log('无人机列表', res.data.data)
this.uavOptions = res.data.data
// TODO 临时
if (this.uavOptions.length > 0) {
2026-01-28 21:08:52 +08:00
// this.form.uav = this.uavOptions[0].id
2026-01-25 16:02:00 +08:00
this.uavReady = true
}
} else {
this.$message.error(res.data.message)
}
})
},
onLoaderTypeChange(type) {
this.loaderOptions = []
if (type) {
this.getLoaderData(type)
}
},
2026-01-28 21:08:52 +08:00
loaderChange() {
getLastStatus({ payloadId: this.form.loader }).then(res => {
const data = res.data.data
console.log(data, '载荷状态信息');
let position = DT.Cesium.Cartesian3.fromDegrees(data.longitude, data.latitude, 2000)
viewer.cesiumViewer.scene.camera.flyTo({
destination: position,
duration: 1
})
})
},
2026-01-25 16:02:00 +08:00
getLoaderData(type) {
// getLoaderList
this.loaderReady = false
getLoaderEnabledList().then(res => {
if (res.data.code === 200) {
console.log('载荷数据-------------', res.data.data)
this.loaderOptions = res.data.data
// TODO 临时
if (this.loaderOptions.length > 0) {
2026-01-28 21:08:52 +08:00
// this.form.loader = this.loaderOptions[0].id
// getLastStatus({ payloadId: this.loaderOptions[0].id }).then(res => {
// console.log(res.data.data, 777777777777777);
// const data = res.data.data
// let position = DT.Cesium.Cartesian3.fromDegrees(data.longitude, data.latitude, 1000)
// viewer.cesiumViewer.scene.camera.flyTo({
// destination: position,
// duration: 1
// })
// })
2026-01-25 16:02:00 +08:00
this.loaderReady = true
}
} else {
this.$message.error(res.data.message)
}
})
},
refreshUavHeight() {
if (this.form.uav) {
if (this.form.loader) {
getUavCurrentHeight({ payloadId: this.form.loader }).then(res => {
if (res.data.code === 200) {
this.form.startAltitude = res.data.data.altitude
this.currentUavInfo = {
longitude: res.data.data.longitude,
latitude: res.data.data.latitude,
height: res.data.data.altitude,
}
2026-01-28 21:08:52 +08:00
console.log(this.currentUavInfo, 889999999);
let position = DT.Cesium.Cartesian3.fromDegrees(res.data.data.longitude, res.data.data.latitude, 3000)
viewer.cesiumViewer.scene.camera.flyTo({
destination: position,
duration: 1
})
2026-01-25 16:02:00 +08:00
this.$message.success('获取当前高度成功!')
} else {
this.$message.error(res.data.message)
}
})
} else {
this.$message.warning('请选择雷达!')
}
} else {
this.$message.warning('请选择无人机!')
}
},
getList() {
getTaskListData({ type: 2, orders: [{ column: 'begin_time', asc: false }] }).then(res => {
if (res.data.code === 200) {
let data = res.data.data
let list = []
data.forEach(item => {
item.statusName = this.jobStatus[item.status + '']
list.push({
id: item.id,
beginTime: item.beginTime,
check: item.check,
endTime: item.endTime,
mode: item.mode,
name: item.name,
status: item.status,
statusName: item.statusName,
})
this.removeTaskTarget(item.id)
2026-01-25 16:02:00 +08:00
})
taskListResource = data
this.taskList.data = list
} else {
this.$message.error(res.data.message)
}
})
},
copyTask(info) {
getTaskEditItemDetail({ jobId: info.id }).then(res => {
if (res.data.code === 200) {
console.log('编辑详情', res.data.data)
this.editTask(JSON.parse(res.data.data))
} else {
this.$message.error(res.data.message)
}
})
},
2026-01-25 16:02:00 +08:00
editTaskName(info) {
this.editName.visible = false
this.editName.loading = false
this.editName.name = info.name
this.editName.id = info.id
this.editName.visible = true
},
submitName() {
this.$refs.form.validate(valid => {
if (valid) {
let params = {
id: this.editName.id,
name: this.editName.name,
}
editTaskName(params).then(res => {
this.editName.loading = false
if (res.data.code === 200) {
this.$message.success('修改成功!')
this.editName.visible = false
this.getList()
} else {
this.$message.error(res.data.message)
}
}).catch(err => {
this.editName.loading = false
})
}
})
},
// 删除任务
deleteTask(info) {
this.$confirm('确定删除吗', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(res => {
deleteTaskItem([info.id]).then(res => {
if (res.data.code === 200) {
this.$message.success('删除成功')
this.getList()
} else {
this.$message.error(res.data.message)
}
})
})
},
/**
* 重新执行
* @param info
*/
reRunTask(info) {
this.$confirm('确定重新执行吗', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(res => {
reRunTask({ id: info.id }).then(res => {
if (res.data.code === 200) {
this.$message.success('任务重新执行成功')
this.getList()
} else {
this.$message.error(res.data.message)
}
})
})
},
/**
* 编辑任务
* @param info
*/
editTask(info) {
console.log('复制信息', info)
// 移除所有线
this.removeAllAirline()
// 移除预览
this.removePreviewLine()
2026-01-25 16:02:00 +08:00
this.taskForm.visible = false
this.form = info
this.form.name = info.name + '-copy'
this.form.id = undefined
this.calculateLimit()
this.getUavList()
this.getLoaderData()
// TODO 临时
// this.onLoaderTypeChange('SAR')
viewer.cesiumViewer.scene.globe.depthTestAgainstTerrain = this.form.mode === '3'
2026-01-25 16:02:00 +08:00
this.taskForm.visible = true
if (theViewerTools) {
theViewerTools.destroy()
theViewerTools = null
}
2026-01-25 16:02:00 +08:00
theViewerTools = new AreaPlotManager(viewer)
theViewerTools.initPlot(this.theCallback)
this.$nextTick(() => {
if (this.$refs.form && this.form.mode === '1') {
this.$refs.form.validateField('targetList')
2026-01-25 16:02:00 +08:00
}
})
2026-01-25 16:02:00 +08:00
switch (this.form.mode) {
case '1':
// 快速模式
this.form.targetList.forEach(item => {
theViewerTools.restoreEntity(item)
2026-01-25 16:02:00 +08:00
})
break
case '2':
break
case '3':
// 航线创建
this.form.airlineList.forEach(item => {
let arr = new LineTarget({
viewer: viewer,
id: item.id,
endCallback: this.airlineEndCallback,
baseHeight: this.form.flyHeight,
angle: this.form.waveAngle,
// rotation: this.form.theta * this.form.direction,
rotation: this.form.theta,
name: item.name,
})
airlineCollection[item.id] = arr
arr.restoreTarget(item)
})
break
2026-01-25 16:02:00 +08:00
}
},
openAddForm() {
this.form = {
id: '',
startAltitude: undefined,
imageLight: undefined,
imageBit: 0,
headingDiff: 0,
autoFocus: 0,
imageMode: '0',
2026-01-25 16:02:00 +08:00
moto: 0,
targetChoose: undefined,
loaderType: undefined,
direction: 1,
polarization: '0',
name: '',
airlineList: [],
// ratio: this.sarResolutionOptions[0].value,
ratio: 0.2,
2026-01-25 16:02:00 +08:00
heightMode: 1,
mode: '1',
width: undefined,
theta: 70.91580209,
flyHeight: 300,
initSpeed: 10,
targetList: [],
2026-01-28 21:08:52 +08:00
loader: this.loaderOptions[0].id,
uav: this.uavOptions[0].id,
2026-01-25 16:02:00 +08:00
routepoints: [],
waveAngle: 20,
waveRotation: 20,
}
this.calculateLimit()
this.getUavList()
this.getLoaderData()
// TODO 临时
// this.onLoaderTypeChange('SAR')
this.taskForm.visible = true
if (theViewerTools) {
theViewerTools.destroy()
theViewerTools = null
}
2026-01-28 14:32:29 +08:00
this.taskList.data.forEach(el => {
if (el.check) {
this.removeTaskTarget(el.id)
el.check = false
}
})
2026-01-25 16:02:00 +08:00
theViewerTools = new AreaPlotManager(viewer)
theViewerTools.initPlot(this.theCallback)
console.log('船舰了吗', theViewerTools)
},
resetForm() {
2026-01-28 14:32:29 +08:00
// this.taskForm.show = false
// this.taskForm.visible = false
this.removeAllAirline()
this.removePreviewLine()
this.form = {
id: '',
startAltitude: undefined,
imageLight: undefined,
imageBit: 0,
headingDiff: 0,
autoFocus: 0,
imageMode: '0',
moto: 0,
targetChoose: undefined,
loaderType: undefined,
airlineList: [],
direction: 1,
polarization: '0',
name: '',
ratio: this.sarResolutionOptions[0].value,
heightMode: 1,
mode: '1',
width: undefined,
theta: 70.91580209,
flyHeight: 300,
initSpeed: 10,
targetList: [],
loader: undefined,
uav: undefined,
routepoints: [],
waveAngle: 20,
waveRotation: 20,
}
this.calculateLimit()
this.getUavList()
// TODO 临时
this.onLoaderTypeChange('SAR')
this.$nextTick(() => {
2026-01-28 14:32:29 +08:00
// this.taskForm.visible = true
// this.taskForm.show = true
if (theViewerTools) {
theViewerTools.destroy()
theViewerTools = null
}
theViewerTools = new AreaPlotManager(viewer)
theViewerTools.initPlot(this.theCallback)
})
},
submit() {
2026-01-28 21:08:52 +08:00
console.log(this.form, 88888888);
this.$refs.form.validate((valid) => {
if (valid) {
let params = JSON.parse(JSON.stringify(this.form))
let pointList = []
params.targetList.forEach(item => {
let arr = []
item.boundary.forEach(child => {
arr.push({
longitude: child[0],
latitude: child[1],
})
})
pointList.push(arr)
})
params.airlineList.forEach((item, index) => {
if (item.boundaryLonLat) {
pointList.push(item.boundaryLonLat)
}
})
let info = {
info1: JSON.stringify(this.form),
id: params.id,
name: params.name,
mode: params.mode,
pointList: pointList,
startAltitude: params.startAltitude,
imageLight: parseFloat(params.imageLight),
headingDiff: parseFloat(params.headingDiff),
imageBit: parseFloat(params.imageBit),
targetType: params.targetChoose === '点' ? '1' : '2',
imageMode: params.imageMode,
uavList: [
{
uavId: params.uav,
// startLon: params.startPoint.lon,
// startLat: params.startPoint.lat,
// endLon: params.endPoint.lon,
// endLat: params.endPoint.lat,
speed: params.initSpeed,
height: params.flyHeight,
resolution: params.ratio,
startAltitude: params.startAltitude,
payloadList: [{
payloadId: params.loader,
resolution: params.ratio,
width: params.width,
length: this.form.imageMode === '4' ? this.ratioMap.gmti.length : this.ratioMap[params.ratio].length,
theta: params.theta,
reserved: this.form.imageMode === '4' ? this.ratioMap.gmti.reserved : this.ratioMap[params.ratio].reserved,
direction: params.direction,
polarization: params.polarization,
autoFocus: params.autoFocus,
imageMode: params.imageMode,
moto: params.moto,
imageLight: parseFloat(params.imageLight),
imageBit: parseFloat(params.imageBit),
headingDiff: parseFloat(params.headingDiff),
}],
airlineList: params.airlineList
}
]
}
if (info.id) {
addTaskFast(info).then(res => {
if (res.data.code === 200) {
this.$message.success('新增任务任务成功')
this.taskForm.visible = false
this.getList()
} else {
this.$message.error(res.data.message)
}
})
} else {
addTaskFast(info).then(res => {
if (res.data.code === 200) {
this.$message.success('新增任务任务成功')
this.taskForm.visible = false
this.resetForm()
this.getList()
} else {
this.$message.error(res.data.message)
}
})
}
}
})
},
2026-01-25 16:02:00 +08:00
/*************************任务编辑相关*************************/
/**
* 飞行模式改变
* @param value
*/
onModeChange(value) {
console.log('飞行模式', value)
// if (linePlot) {
// linePlot.destroy()
// linePlot = null
// }
this.form.targetList.forEach(item => {
this.tagClose(item)
})
this.endDraw()
this.removeAllAirline()
this.removePreviewLine()
viewer.cesiumViewer.scene.globe.depthTestAgainstTerrain = value === '3'
this.lastLimitUpdate = {
index: -1,
ratio: undefined
}
// this.form.routepoints = []
switch (value) {
case '1':
this.settingExpand = false
// this.form.targetChoose = '点'
break
case '2':
this.settingExpand = false
// this.form.targetChoose = '多边形'
break
case '3':
this.calculateLimit()
this.settingExpand = true
// this.form.targetChoose = '点'
// linePlot = new LinePlot({
// viewer: viewer,
// lodLayer: lodLayer,
// Cesium: DT.Cesium,
// callback: this.pickCallback,
// changeCallback: this.onChangeCallback,
// endCallback: this.endCallback,
// readOnly: this.readOnly,
// loop: false
// })
// console.log('创建了吗', linePlot)
break
}
},
getDrawTargetDisabled(info) {
if (this.form.imageMode === '1') {
return info.value === '多边形'
} else {
return false
}
},
2026-01-25 16:02:00 +08:00
createLine() {
},
/**
* 目标类型改变事件
* @author wangxueshen
* @date 2022-11-03
* @param {any} val
* @returns {any}
*/
targetTypeChange(val) {
this.endDraw()
switch (val) {
case '区域选择':
break
case '形状选择':
// this.form.targetList = []
// theViewerTools.removebyName('区域1')
// const data = {
// id: 1,
// targetName: '区域1',
// targetType: 2,
// areaType: 3,
// data: [
// [119.65860240889127, 26.341999829244322],
// [117.25916413364445, 23.61439484133452],
// [120.67063487635603, 21.896506978647942],
// [121.88328392808693, 25.240668250328035],
// [119.65860240889127, 26.341999829244322]
// ]
// }
// this.form.targetList.push(data)
// theViewerTools.addProvinceMap(data.targetName, data.data)
break
case 'ROI区域':
// this.form.targetList = []
// theViewerTools.removebyName('区域1')
// this.form.targetList.push({
// id: 2,
// targetName: '船舶AIS编号413118000',
// targetType: 3,
// })
break
default:
break
}
},
/**
* tag 删除时间删除已选择的区域或绘制的图形
* @author wangxueshen
* @date 2022-04-28
* @param {any} target
* @returns {any}
*/
tagClose(target) {
// 删除 form.targetList 中的项
let tagIndex = this.form.targetList.findIndex(
item => target.groupTargetId === item.groupTargetId
)
this.form.targetList.splice(tagIndex, 1)
// 删除 form.provinceValue 中的项
this.$set(this.form, 'provinceValue', [])
this.removePreviewLine()
// 清楚当前目标
if (this.form.reqType !== 3) {
theViewerTools.removeByName(target.targetName)
}
},
//#region 绘制代码区域
endDraw(type) {
if (theViewerTools) {
theViewerTools.endDraw()
}
},
destroyDraw() {
if (theViewerTools) {
theViewerTools.destroy()
}
theViewerTools = null
},
startDraw(type) {
theViewerTools.startDraw(
type,
this.theCallback,
'rgba(0, 255, 0, 1)',
'rgba(0, 255, 0, 1)'
)
},
drawFromButton() {
this.duringDraw = true
this.startDraw(this.form.targetChoose)
},
theCallback(targetName, targetType, areaType, data) {
this.duringDraw = false
let result = data
if (targetType === 3) {
let minLon = Math.min(data[0][0], data[1][0])
let minLat = Math.min(data[0][1], data[1][1])
let maxLon = Math.max(data[0][0], data[1][0])
let maxLat = Math.max(data[0][1], data[1][1])
result = [
[minLon, minLat],
[maxLon, minLat],
[maxLon, maxLat],
[minLon, maxLat],
[minLon, minLat]
]
}
this.form.targetList.push({
groupTargetId: getUnionId(),
targetName,
targetType,
areaType,
boundary: result
})
this.endDraw()
},
2026-01-25 16:02:00 +08:00
// 航线创建
/**
* 开始绘制
*/
startAirlineDraw() {
if (this.readOnly) return
if (this.duringAirlinePick) {
this.$message.info('已经处于绘制模式!')
return
}
if (this.form.routepoints.length > 0) {
this.$confirm('绘制会清除历史数据,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.form.routepoints = []
this.duringAirlinePick = true
linePlot.startPick()
})
} else {
linePlot.startPick()
this.duringAirlinePick = true
}
},
/**
* 结束绘制
*/
endAirlineDraw() {
if (this.readOnly) return
if (this.duringAirlinePick) {
linePlot.abortPick()
}
},
pickCallback(position) {
let cat = DT.Cesium.Cartographic.fromCartesian(position)
let lon = Math.round(DT.Cesium.Math.toDegrees(cat.longitude) * 10000000000000) / 10000000000000
let lat = Math.round(DT.Cesium.Math.toDegrees(cat.latitude) * 10000000000000) / 10000000000000
let length = this.form.routepoints.length
this.form.routepoints.push({
longitude: lon,
latitude: lat,
routePointIndex: length
})
// this.calculateDistance()
},
// pickCallback(positions) {
// this.duringAirlinePick = false
// let list = []
// positions.forEach((item, index) => {
// let cat = DT.Cesium.Cartographic.fromCartesian(item)
// let lon = Math.round(DT.Cesium.Math.toDegrees(cat.longitude) * 10000000000000) / 10000000000000
// let lat = Math.round(DT.Cesium.Math.toDegrees(cat.latitude) * 10000000000000) / 10000000000000
// list.push({
// templateType: 1,
// longitude: lon,
// latitude: lat,
// gimbalPitchAngle: -90
// })
// })
// this.form.list = list
// this.calculateDistance()
// },
onChangeCallback(info) {
let cat = DT.Cesium.Cartographic.fromCartesian(info.position)
let lon = Math.round(DT.Cesium.Math.toDegrees(cat.longitude) * 10000000000000) / 10000000000000
let lat = Math.round(DT.Cesium.Math.toDegrees(cat.latitude) * 10000000000000) / 10000000000000
this.form.routepoints[info.index].longitude = lon
this.form.routepoints[info.index].latitude = lat
// this.calculateDistance()
},
endCallback() {
this.duringAirlinePick = false
},
onTableCommand(info, index) {
if (this.readOnly || this.duringAirlinePick) return
if (this.form.routepoints.length < 3) {
this.$message.warning('至少需要保留两个点!')
return
}
let position = DT.Cesium.Cartesian3.fromDegrees(info.longitude, info.latitude)
linePlot.deleteItem({ position: position, index: index })
this.form.routepoints.splice(index, 1)
},
onTableInputChange(info, index) {
let position = DT.Cesium.Cartesian3.fromDegrees(info.longitude, info.latitude)
linePlot.editItem({ position: position, index: index })
},
//#endregion
theCallback2(targetName, targetType, areaType, data) {
let result = JSON.parse(JSON.stringify(data))
switch (this.addRegion.currentSelfDrawType) {
case 'rectangle':
this.addRegion.recTopLeft = {
lon: result[0][0].toFixed(4),
lat: result[0][1].toFixed(4)
}
this.addRegion.recBottomRight = {
lon: result[1][0].toFixed(4),
lat: result[1][1].toFixed(4)
}
this.endDraw()
this.updateRectangle()
break
case 'circle':
this.addRegion.circleCenter = {
lon: result[0][0].toFixed(4),
lat: result[0][1].toFixed(4)
}
this.addRegion.circleRadius =
this.getDistance(
{ lon: result[0][0], lat: result[0][1] },
{ lon: result[1][0], lat: result[1][1] }
) * 1852
this.endDraw()
this.updateCircle()
break
case 'polygon':
let lineData = []
let length = result.length
result.forEach((item, index) => {
if (index < length - 1) {
lineData.push({
name: '点' + (index + 1),
lon: item[0].toFixed(4),
lat: item[1].toFixed(4)
})
}
})
this.addRegion.polylinePoints = lineData
this.addRegion.polylineCount = lineData.length + 1
this.endDraw()
this.updatePolygon()
break
}
},
pickPoint(type) {
this.duringPick = true
if (!pickHandler) {
pickHandler = new DT.Cesium.ScreenSpaceEventHandler(
viewer.cesiumViewer.scene.canvas
)
}
pickHandler.setInputAction(evt => {
let cartesian = this.getCartesian3FromPX(evt.position)
if (cartesian) {
let cat = DT.Cesium.Cartographic.fromCartesian(cartesian)
let lon = DT.Cesium.Math.toDegrees(cat.longitude)
let lat = DT.Cesium.Math.toDegrees(cat.latitude)
let newPosition = DT.Cesium.Cartesian3.fromDegrees(lon, lat, 50)
newPosition = cartesian
if (type === 'startPoint') {
if (startPoint) {
// viewer.entities.remove(startPoint)
startPoint.position = newPosition
} else {
startPoint = viewer.entities.add({
position: newPosition,
label: {
text: '航线起点',
font: '12px sans-serif',
disableDepthTestDistance: 10000,
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
verticalOrigin: DT.Cesium.VerticalOrigin.CENTER,
pixelOffset: new DT.Cesium.Cartesian2(10, 0),
showBackground: true,
backgroundColor: DT.Cesium.Color.BLACK.withAlpha(0.7),
backgroundPadding: new DT.Cesium.Cartesian2(5, 3),
},
point: {
pixelSize: 8,
color: DT.Cesium.Color.WHITE,
disableDepthTestDistance: 10000,
}
})
}
} else {
if (endPoint) {
// viewer.entities.remove(startPoint)
endPoint.position = newPosition
} else {
endPoint = viewer.entities.add({
position: newPosition,
label: {
text: '航线终点',
font: '12px sans-serif',
disableDepthTestDistance: 10000,
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
verticalOrigin: DT.Cesium.VerticalOrigin.CENTER,
pixelOffset: new DT.Cesium.Cartesian2(10, 0),
showBackground: true,
backgroundColor: DT.Cesium.Color.BLACK.withAlpha(0.7),
backgroundPadding: new DT.Cesium.Cartesian2(5, 3),
},
point: {
pixelSize: 8,
color: DT.Cesium.Color.WHITE,
disableDepthTestDistance: 10000,
}
})
}
}
this.form[type].lon = Math.round(lon * 1000000000) / 1000000000
this.form[type].lat = Math.round(lat * 1000000000) / 1000000000
pickHandler.removeInputAction(DT.Cesium.ScreenSpaceEventType.LEFT_CLICK)
this.duringPick = false
}
}, DT.Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
getCartesian3FromPX(px) {
let cartesian
let ray = viewer.cesiumViewer.camera.getPickRay(px)
if (!ray) return null
cartesian = viewer.cesiumViewer.scene.globe.pick(ray, viewer.cesiumViewer.scene)
if (!cartesian) {
cartesian = viewer.cesiumViewer.camera.pickEllipsoid(px, viewer.cesiumViewer.scene.globe.ellipsoid)
}
return cartesian
},
onImageModeChange(value) {
switch (this.form.imageMode) {
case '0':
// 条带
if (this.form.ratio === '10') {
this.form.ratio = this.sarResolutionOptions[0].value
}
break;
case '1':
// 聚束模式
if (this.form.ratio === '10') {
this.form.ratio = this.sarResolutionOptions[0].value
}
if (this.form.mode === '1') {
if (this.form.targetChoose === '多边形') {
this.onModeChange('1')
this.form.targetChoose = '点'
}
} else {
this.form.mode = '1'
this.onModeChange('1')
}
break;
case '4':
// gmti
this.form.ratio = '10'
break;
}
this.calculateLimit()
},
getRatioDisabled(value) {
if (this.form.imageMode !== '4') {
return value.value === '10'
} else {
return value.value !== '10'
}
},
2026-01-25 16:02:00 +08:00
calculateLimit() {
if (this.form.ratio && this.form.initSpeed) {
let findIndex = this.calculateMap.findIndex(item => this.form.initSpeed > item.minSpeed && this.form.initSpeed <= item.maxSpeed)
if (this.form.initSpeed === 5) {
findIndex = 0
}
if (findIndex !== -1) {
let find = this.calculateMap[findIndex]
if (this.lastLimitUpdate.index === findIndex && this.lastLimitUpdate.ratio === this.form.ratio) {
// return
}
let info = this.form.imageMode === '4' ? find.gmt : find[this.form.ratio]
2026-01-25 16:02:00 +08:00
this.form.theta = info.defaultAngle
this.lastLimitUpdate.index = findIndex
this.lastLimitUpdate.ratio = this.form.ratio
this.minDistance = Math.max(info.minDistance, this.form.flyHeight / Math.cos(Math.PI / 18))
this.maxDistance = info.maxDistance
this.calculateWidth()
}
}
},
calculateHeightLimit() {
let find = this.calculateMap[this.lastLimitUpdate.index]
let info = this.form.imageMode === '4' ? find.gmti : find[this.form.ratio]
2026-01-25 16:02:00 +08:00
this.minDistance = Math.max(info.minDistance, this.form.flyHeight / Math.cos(Math.PI / 18))
this.maxDistance = info.maxDistance
this.calculateWidth()
},
calculateWidth() {
// 算角度范围
let angleMin = 10
if (this.form.flyHeight < this.minDistance) {
angleMin = Math.max(180 * Math.acos(this.form.flyHeight / this.minDistance) / Math.PI, 10)
}
let angleMax = 180 * Math.acos(this.form.flyHeight / this.maxDistance) / Math.PI
this.maxAngle = Math.round((angleMax - 1.2) * 10) / 10
this.minAngle = Math.round((angleMin + 1.2) * 10) / 10
if (this.form.theta > this.maxAngle || this.form.theta < this.minAngle) {
this.form.theta = Math.round((this.maxAngle + this.minAngle) * 100 / 2) / 100
}
let maxWaveAngle = Math.min(this.maxAngle - this.form.theta, this.form.theta - this.minAngle)
maxWaveAngle = Math.min(maxWaveAngle + 1.2, 13)
maxWaveAngle = Math.ceil(maxWaveAngle * 100) / 100
this.maxWaveAngle = maxWaveAngle
if (this.form.waveAngle > this.maxWaveAngle || this.form.waveAngle < this.minWaveAngle) {
this.form.waveAngle = this.maxWaveAngle
}
let width = 2 * (this.form.flyHeight * Math.tan(this.form.theta * Math.PI / 180) - this.form.flyHeight * Math.tan((this.form.theta - this.form.waveAngle) * Math.PI / 180))
width = Math.round(width * 1000000) / 1000000
this.form.width = width
this.updateSceneAirline()
},
updateWaveAngle() {
let width = 2 * (this.form.flyHeight * Math.tan(this.form.theta * Math.PI / 180) - this.form.flyHeight * Math.tan((this.form.theta - this.form.waveAngle) * Math.PI / 180))
width = Math.round(width * 1000000) / 1000000
this.form.width = width
this.updateSceneAirline()
},
handleRatioChange(value) {
let info
if (this.form.imageMode === '4') {
info = this.ratioMap.gmti
} else {
info = this.ratioMap[value]
}
2026-01-25 16:02:00 +08:00
this.form.width = info.width
this.form.theta = info.theta
},
//#region 航线创建
createAirline() {
if (this.airlineCreateInfo.during) {
return
}
this.$message({
type: 'success',
message: '在场景中点击鼠标左键创建航线',
duration: 4000,
})
this.airlineCreateInfo.during = true
let id = new Date().getTime() + ''
this.airlineCreateInfo.id = id
let length = this.form.airlineList.length
let name = `航线${length + 1}`
let arr = new LineTarget({
viewer: viewer,
id: id,
endCallback: this.airlineEndCallback,
baseHeight: this.form.flyHeight,
angle: this.form.waveAngle,
// rotation: this.form.theta * this.form.direction,
rotation: this.form.theta,
name: name,
})
airlineCollection[id] = arr
arr.startPick()
},
updateSceneAirline() {
let params = {
baseHeight: this.form.flyHeight,
angle: this.form.waveAngle,
rotation: this.form.theta * this.form.direction,
}
// this.form.airlineList.forEach(item => {
// item.height = this.form.flyHeight
// })
for (let key in airlineCollection) {
if (airlineCollection[key]) {
let find = this.form.airlineList.find(target => target.id == key)
if (find) {
params.rotation = this.form.theta * find.direction
airlineCollection[key].updateHeightAndAngle(params)
}
}
}
},
airlineEndCallback(data) {
this.airlineCreateInfo.during = false
let findIndex = this.form.airlineList.findIndex(item => item.id === data.id)
if (findIndex > -1) {
let obj = Object.assign({}, this.form.airlineList[findIndex], data)
this.form.airlineList.splice(findIndex, 1, obj)
} else {
let length = this.form.airlineList.length
data.name = `航线${length + 1}`
this.form.airlineList.push(data)
}
},
deleteAirlineItem(info, index) {
this.form.airlineList.splice(index, 1)
if (airlineCollection[info.id]) {
airlineCollection[info.id].destroy()
airlineCollection[info.id] = null
}
},
removeAllAirline() {
for (let key in airlineCollection) {
if (airlineCollection[key]) {
airlineCollection[key].destroy()
}
}
this.form.airlineList = []
airlineCollection = {}
},
handleDirectionChange(value) {
for (let key in airlineCollection) {
if (airlineCollection[key]) {
let rotation = this.form.theta * value
airlineCollection[key].changeWaveRotation(rotation)
}
}
},
handleSelfDirectionChange(value, info, index) {
if (airlineCollection[info.id]) {
let rotation = this.form.theta * value
airlineCollection[info.id].changeWaveRotation(rotation)
}
},
//#endregion
//#region 预览
previewLine() {
2026-01-25 16:02:00 +08:00
this.$refs.form.validate((valid) => {
if (valid) {
this.removePreviewLine()
2026-01-25 16:02:00 +08:00
let params = JSON.parse(JSON.stringify(this.form))
let pointList = []
params.targetList.forEach(item => {
let arr = []
item.boundary.forEach(child => {
arr.push({
longitude: child[0],
latitude: child[1],
})
})
pointList.push(arr)
})
params.airlineList.forEach((item, index) => {
if (item.boundaryLonLat) {
pointList.push(item.boundaryLonLat)
}
})
console.log('提交航线', params.airlineList)
2026-01-25 16:02:00 +08:00
let info = {
id: params.id,
name: params.name,
mode: params.mode,
pointList: pointList,
startAltitude: params.startAltitude,
imageLight: parseFloat(params.imageLight),
headingDiff: parseFloat(params.headingDiff),
imageBit: parseFloat(params.imageBit),
targetType: params.targetChoose === '点' ? '1' : '2',
imageMode: params.imageMode,
2026-01-25 16:02:00 +08:00
uavList: [
{
uavId: params.uav,
// startLon: params.startPoint.lon,
// startLat: params.startPoint.lat,
// endLon: params.endPoint.lon,
// endLat: params.endPoint.lat,
speed: params.initSpeed,
height: params.flyHeight,
resolution: params.ratio,
startAltitude: params.startAltitude,
payloadList: [{
payloadId: params.loader,
resolution: params.ratio,
width: params.width,
length: this.form.imageMode === '4' ? this.ratioMap.gmti.length : this.ratioMap[params.ratio].length,
2026-01-25 16:02:00 +08:00
theta: params.theta,
reserved: this.form.imageMode === '4' ? this.ratioMap.gmti.reserved : this.ratioMap[params.ratio].reserved,
2026-01-25 16:02:00 +08:00
direction: params.direction,
polarization: params.polarization,
autoFocus: params.autoFocus,
imageMode: params.imageMode,
2026-01-25 16:02:00 +08:00
moto: params.moto,
imageLight: parseFloat(params.imageLight),
imageBit: parseFloat(params.imageBit),
headingDiff: parseFloat(params.headingDiff),
}],
airlineList: params.airlineList
}
]
}
this.previewLoading = true
previewTaskFast(info).then(res => {
this.previewLoading = false
if (res.data.code === 200) {
2026-01-25 16:02:00 +08:00
let data = res.data.data
for (let key in data) {
this.addPreviewLine(data[key], key)
}
this.$message.success('获取航线成功!')
2026-01-25 16:02:00 +08:00
} else {
this.$message.error(res.data.message)
}
}).catch(err => {
2026-01-25 16:02:00 +08:00
this.previewLoading = false
})
// let params = JSON.parse(JSON.stringify(this.form))
// let pointList = []
// params.targetList.forEach((item, index) => {
// let arr = []
// item.boundary.forEach(child => {
// arr.push([child[0], child[1]])
// })
// pointList.push({
// type: params.targetChoose === '点' ? 'point' : 'region',
// coords: arr,
// valid_TYPES: [
// 'region',
// 'line',
// 'point'
// ],
// id: index
// })
// })
// console.log('提交航线', params.airlineList)
// let info = {
// optimize: false,
// targets: pointList,
// uavs: [
// {
// id: params.uav,
// constraint: {
// endurance: 1000000.0,
// height: params.flyHeight
// },
// start_coord: [this.currentUavInfo.longitude, this.currentUavInfo.latitude],
// end_coord: [this.currentUavInfo.longitude, this.currentUavInfo.latitude],
// payload: {
// type: 'SAR',
// width: params.width,
// length: this.form.imageMode === 0 ? this.ratioMap[params.ratio].length : this.ratioMap.gmti.length,
// theta: params.theta,
// direction: params.direction,
// reserved_distance: this.form.imageMode === 0 ? this.ratioMap[params.ratio].reserved : this.ratioMap.gmti.reserved,
// valid_DIRECTIONS: [ 'left', 'right'],
// },
//
// }
// ]
// }
// console.log('任务预览提交', info)
// this.previewLoading = true
// axios.post(window.config.arithmeticPath, info).then(res => {
2026-01-25 16:02:00 +08:00
// console.log('预览返回', res)
//
// if (res.status === 200) {
// let data = res.data.data
// for (let key in data) {
// this.addPreviewLine(data[key], key)
// }
2026-01-25 16:02:00 +08:00
// } else {
// this.$message.error(res.data.message)
// }
// this.previewLoading = false
// }).catch(
// this.previewLoading = false
// )
2026-01-25 16:02:00 +08:00
}
})
},
addPreviewLine(data, parentId) {
data.forEach((item, index) => {
let startPosition = DT.Cesium.Cartesian3.fromDegrees(item.startLon, item.startLat, item.startHeight)
let endPosition = DT.Cesium.Cartesian3.fromDegrees(item.endLon, item.endLat, item.endHeight)
2026-01-25 16:02:00 +08:00
let entity = viewer.entities.add({
position: startPosition,
label: {
text: `航线${index + 1}起点`,
font: '24px',
showBackground: true,
backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'),
fillColor: DT.Cesium.Color.WHITE,
horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT,
pixelOffset: this.labelPixelOffset,
disableDepthTestDistance: 20000
},
polyline: {
//使用cesium的peoperty
positions: [startPosition, endPosition],
show: true,
material: DT.Cesium.Color.LIMEGREEN,
width: 4,
}
})
previewEntities.push(entity)
})
},
removePreviewLine() {
previewEntities.forEach((item, index) => {
viewer.entities.remove(item)
})
previewEntities = []
},
//#endregion
2026-01-25 16:02:00 +08:00
//#region 航线详情
openTaskLineDetail(info) {
this.taskLineDetail.visible = false
let find = taskListResource.find(item => item.id === info.id)
if (find && find.uavList) {
let line = []
find.uavList.forEach(item => {
if (item.airlineList) {
item.airlineList.forEach(airline => {
line.push({
startLon: airline.startLon,
startLat: airline.startLat,
startHeight: airline.startHeight,
startAlt: airline.startHeight + item.startAltitude,
endLon: airline.endLon,
endLat: airline.endLat,
endHeight: airline.endHeight,
endAlt: airline.endHeight + item.startAltitude,
})
})
}
})
this.taskLineDetail.title = find.name + '-航线详情'
this.taskLineDetail.data = line
this.taskLineDetail.visible = true
}
}
//#endregion
}
}