import { lodLayer, viewer } from '@/components/dt-scene/index.vue' // 新增空间态势统计 // 台风列表 import SceneInfo from '@/mixin/scene-info' import LeftSlide from '@/components/LeftSlide.vue' import { mapGetters } from 'vuex' 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, getTaskListData, getUavCurrentHeight, getUavEnabledListData, reRunTask, } from '@/api/task' import LineTarget from './lineTarget' import axios from 'axios' let theViewerTools = null let pickHandler = null let startPoint = null let endPoint = null let linePlot = null let airlineCollection = {} let previewEntities = [] let taskListResource = [] 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: '拍照任务', uavCompletion: 30, isFinish: false, taskProgressName: '30%', executeClass: '2', taskTime: '2024-12-28 14:00: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, 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' }], 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.2': { width: 777.1751307, // y 方向幅宽 length: 0.1, // x 方向幅宽 theta: 70.91580209, // 下视角 reserved: 100, //预留距离 (m) direction: 1, //侧视方向 polarization: '0', //极化方式 }, '0.3': { width: 2025.600568, // y 方向幅宽 length: 0.1, // x 方向幅宽 theta: 80.12850849, // 下视角 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', //极化方式 } }, 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.2': { minDistance: 105, maxDistance: 3461, defaultAngle: 80.12850849, }, '0.3': { minDistance: 105, maxDistance: 5000, defaultAngle: 83.14499366, }, '1': { minDistance: 105, maxDistance: 5000, defaultAngle: 83.14499366, }, '3': { minDistance: 105, maxDistance: 5000, defaultAngle: 83.14499366, } }, { minSpeed: 10, maxSpeed: 15, '0.1': { minDistance: 105, maxDistance: 1192, defaultAngle: 62.52119039, }, '0.2': { minDistance: 105, maxDistance: 2325, defaultAngle: 75.41290323, }, '0.3': { minDistance: 105, maxDistance: 4591, defaultAngle: 82.53841873, }, '1': { minDistance: 105, maxDistance: 5000, defaultAngle: 83.14499366, }, '3': { minDistance: 105, maxDistance: 5000, defaultAngle: 83.14499366, } }, { minSpeed: 15, maxSpeed: 20, '0.1': { minDistance: 105, maxDistance: 910, defaultAngle: 55.07020714, }, '0.2': { minDistance: 105, maxDistance: 1760, defaultAngle: 70.91580209, }, '0.3': { minDistance: 105, maxDistance: 3461, defaultAngle: 80.12850849, }, '1': { minDistance: 105, maxDistance: 5000, defaultAngle: 83.14499366, }, '3': { minDistance: 105, maxDistance: 5000, defaultAngle: 83.14499366, } } ], 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, focusOptions: [ { label: '否', value: 0 }, { label: '是', value: 1 } ], motoOptions: [ { label: '否', value: 0 }, { label: '是', value: 1 } ], emptyImg: require('@/assets/img/common/empty.svg') } }, computed: { ...mapGetters([ 'currentTime', 'sarResolution', 'sarResolutionOptions', 'jobMode', 'jobModeOptions', 'jobStatus', 'polarization', 'polarizationOptions', ]), 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() } startPoint = null endPoint = null if (linePlot) { linePlot.destroy() linePlot = null } }, methods: { 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) { this.form.uav = this.uavOptions[0].id this.uavReady = true } } else { this.$message.error(res.data.message) } }) }, onLoaderTypeChange(type) { this.loaderOptions = [] if (type) { this.getLoaderData(type) } }, 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) { this.form.loader = this.loaderOptions[0].id 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) { console.log('请求高度', res.data.data) this.form.startAltitude = res.data.data.altitude this.currentUavInfo = { longitude: res.data.data.longitude, latitude: res.data.data.latitude, height: res.data.data.altitude, } 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) { console.log('任务列表', res.data.data) 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, }) }) taskListResource = data this.taskList.data = list } else { this.$message.error(res.data.message) } }) }, 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) if (info.status + '' !== '2') return let mode = info.mode + '' this.taskForm.visible = false this.form = { id: info.id, startAltitude: info.startAltitude, imageLight: info.imageLight, imageBit: info.imageBit, headingDiff: info.headingDiff, autoFocus: info.autoFocus, moto: info.moto, targetChoose: mode === '1' ? '点' : '多边形', loaderType: 'SAR', name: info.name, polarization: info.polarization, heightMode: 1, mode: mode, flyHeight: info.uavList[0]?.height, initSpeed: info.uavList[0]?.speed, targetList: [], ratio: info.uavList[0]?.payloadList[0]?.resolution, loader: info.uavList[0]?.payloadList[0]?.payloadId, uav: info.uavList[0]?.uavId, routepoints: [], startPoint: { lon: info.uavList[0]?.startLon, lat: info.uavList[0]?.startLat, }, endPoint: { lon: info.uavList[0]?.endLon, lat: info.uavList[0]?.endLat, } } this.taskForm.visible = true theViewerTools = new AreaPlotManager(viewer) theViewerTools.initPlot(this.theCallback) if (typeof this.form.startPoint.lon === 'number' && typeof this.form.startPoint.lat === 'number') { let newPosition = DT.Cesium.Cartesian3.fromDegrees(this.form.startPoint.lon, this.form.startPoint.lat) 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, } }) } if (typeof this.form.endPoint.lon === 'number' && typeof this.form.endPoint.lat === 'number') { let newPosition = DT.Cesium.Cartesian3.fromDegrees(this.form.endPoint.lon, this.form.endPoint.lat) 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, } }) } if (mode === '1') { if (info.pointList.length > 0) { let toPush = { groupTargetId: getUnionId(), targetName: '点1', targetType: 1, areaType: 2, boundary: [[info.pointList[0].longitude, info.pointList[0].latitude],] } theViewerTools.restoreEntity(toPush) this.form.targetList.push(toPush) } } else { if (info.pointList.length > 0) { let boundary = [] info.pointList.forEach(item => { boundary.push([item.longitude, item.latitude]) }) let toPush = { groupTargetId: getUnionId(), targetName: '多边形1', targetType: 4, areaType: 2, boundary: boundary } theViewerTools.restoreEntity(toPush) this.form.targetList.push(toPush) } } }, openAddForm() { this.form = { id: '', startAltitude: undefined, imageLight: undefined, imageBit: 0, headingDiff: 0, autoFocus: 0, moto: 0, targetChoose: undefined, loaderType: undefined, direction: 1, polarization: '0', name: '', airlineList: [], ratio: 0.1, 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() this.getLoaderData() // TODO 临时 // this.onLoaderTypeChange('SAR') this.taskForm.visible = true theViewerTools = new AreaPlotManager(viewer) theViewerTools.initPlot(this.theCallback) console.log('船舰了吗', theViewerTools) }, /*************************任务编辑相关*************************/ /** * 飞行模式改变 * @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 } }, 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) }, // 航线创建 /** * 开始绘制 */ 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 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 }) console.log('绘制边界线', result) console.log('绘制边界线targetType', targetType) console.log('绘制边界线areaType', areaType) console.log('绘制边界线targetName', targetName) console.log('绘制边界线targetName', targetName) this.endDraw() }, 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 }, 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 } console.log(1111, findIndex, find) console.log('求变化', this.lastLimitUpdate.index === findIndex && this.lastLimitUpdate.ratio === this.form.ratio) if (findIndex !== -1) { let find = this.calculateMap[findIndex] if (this.lastLimitUpdate.index === findIndex && this.lastLimitUpdate.ratio === this.form.ratio) { // return } let info = find[this.form.ratio] 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 console.log('最小距离', this.minDistance) console.log('最大距离', this.maxDistance) this.calculateWidth() } } }, calculateHeightLimit() { let find = this.calculateMap[this.lastLimitUpdate.index] let info = find[this.form.ratio] 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 console.log('最大最小下视角', this.maxAngle, this.minAngle) if (this.form.theta > this.maxAngle || this.form.theta < this.minAngle) { this.form.theta = Math.round((this.maxAngle + this.minAngle) * 100 / 2) / 100 } console.log('飞行高度', this.form.flyHeight) console.log('下视角', this.form.theta) 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 console.log('计算前波束角', this.form.waveAngle) console.log('最小最大波束角', this.maxWaveAngle, this.minWaveAngle) if (this.form.waveAngle > this.maxWaveAngle || this.form.waveAngle < this.minWaveAngle) { this.form.waveAngle = this.maxWaveAngle } console.log('计算后波束角', this.form.waveAngle) 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 = this.ratioMap[value] 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) { console.log('测试方向', typeof value, this.form.theta * 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 resetForm() { 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, moto: 0, targetChoose: undefined, loaderType: undefined, airlineList: [], direction: 1, polarization: '0', name: '', ratio: 0.1, 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(() => { this.taskForm.visible = true this.taskForm.show = true theViewerTools = new AreaPlotManager(viewer) theViewerTools.initPlot(this.theCallback) }) }, submit() { 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) } }) console.log('提交航线', params.airlineList) /*if (params.mode === '1' || params.mode === '2') { params.targetList.forEach(item => { item.boundary.forEach(child => { pointList.push({ longitude: child[0], latitude: child[1], }) }) }) } if (params.mode === '3') { params.routepoints.forEach(route => { pointList.push({ longitude: route.longitude, latitude: route.latitude, }) }) }*/ 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), 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.ratioMap[params.ratio].length, theta: params.theta, reserved: this.ratioMap[params.ratio].reserved, direction: params.direction, polarization: params.polarization, autoFocus: params.autoFocus, moto: params.moto, imageLight: parseFloat(params.imageLight), imageBit: parseFloat(params.imageBit), headingDiff: parseFloat(params.headingDiff), }], airlineList: params.airlineList } ] } // if (params.airlineList.length > 0) { // info.airlineList = params.airlineList // } console.log('任务创建提交', info) if (info.id) { addTaskFast(info).then(res => { if (res.data.code === 200) { console.log('新增任务任务成功') 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) { console.log('新增任务任务成功') this.$message.success('新增任务任务成功') // this.taskForm.visible = false this.resetForm() this.getList() } else { this.$message.error(res.data.message) } }) } } }) }, previewLine() { this.$refs.form.validate((valid) => { if (valid) { this.removePreviewLine() 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.ratioMap[params.ratio].length, theta: params.theta, direction: params.direction, reserved_distance: this.ratioMap[params.ratio].reserved, valid_DIRECTIONS: ['left', 'right'], }, } ] } console.log('任务预览提交', info) this.previewLoading = true axios.post(window.config.arithmeticPath, info).then(res => { console.log('预览返回', res) if (res.status === 200) { let data = res.data.data for (let key in data) { this.addPreviewLine(data[key], key) } } else { this.$message.error(res.data.message) } this.previewLoading = false }).catch( this.previewLoading = false ) // previewTaskFast(info).then(res => { // console.log('预览返回', res) // if (res.data.code === 200) { // console.log('预览返回', res.data.data) // this.addPreviewLine(res.data.data) // } else { // this.$message.error(res.data.message) // } // }) } }) }, addPreviewLine(data, parentId) { data.forEach((item, index) => { let startPosition = DT.Cesium.Cartesian3.fromDegrees(...item.flight_start) let endPosition = DT.Cesium.Cartesian3.fromDegrees(...item.flight_end) 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 = [] }, //#region 航线详情 openTaskLineDetail(info) { this.taskLineDetail.visible = false let find = taskListResource.find(item => item.id === info.id) console.log('信息', find) 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 } }