zhufu 2 months ago
commit 0a97af9747

@ -94,6 +94,9 @@
<a-menu-item @click="checkAriLine(item)" >
<a href="javascript:;">选择</a>
</a-menu-item>
<a-menu-item @click="airLineDetail(item)" >
<a href="javascript:;">预览</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:;">编辑</a>
</a-menu-item>
@ -185,9 +188,14 @@
import { getAirLineList,uploadXmlFile,deleteAirLine,addAirLine} from '@/api/sys/workplan';
import { Modal, message } from 'ant-design-vue';
const emit = defineEmits(["checkAriLine","createAirLine"])
const emit = defineEmits(["checkAriLine","createAirLine","previewAirLine"])
import {templateTypeOptions} from '../waylineConfig/index';
import JSZip from 'jszip';
import axios from 'axios';
import {templateTypeOptions} from '../waylineConfig/index'
import { XMLParser, XMLBuilder } from 'fast-xml-parser';
//
const importAirLineShow = ref(false);
@ -213,7 +221,7 @@
const submitForm = ref({
"id": "",
"airLineName": "测试航线01", // 线
"airLineName": "", // 线
"airLineType": "waypoint", // 线 templateType waypointmapping2dmappingStrip
"uavId": "",
"flyToFirstPointMode": "", // :flyToWaylineMode safelypointToPoint
@ -267,6 +275,48 @@
emit("checkAriLine",item);
}
// 线
const currentPreviewWayLine = ref(null);
const airLineDetail =async (item) => {
currentPreviewWayLine.value = item;
console.log("item",item.wpml);
try{
let response = await axios.get(item.wpml,{responseType: 'arraybuffer'});
// kmz
let xmlStr =await extractKmz(response.data);
let xmlData = xmlStr.replace(/wpml:/g,"");
const parser = new XMLParser();
const jsonObj = parser.parse(xmlData);
emit("previewAirLine",jsonObj.kml.Document,currentPreviewWayLine)
}catch(e){
console.error(e);
}
}
// 线
const extractKmz = async (kmzBlob)=>{
const zip = new JSZip();
const contents = await zip.loadAsync(kmzBlob);
// .wmpl
for (const [filename, file] of Object.entries(contents.files)) {
if (filename.toLowerCase().endsWith('.wpml')) {
return await file.async('text');
}
}
throw new Error('KMZ文件中未找到WMPL文件');
}
const importAirLine = () => {
importAirLineShow.value = true;
}

@ -175,7 +175,7 @@
const form = {
"id": "",
"airLineName": "测试航线01", // 线
"airLineName": "", // 线
"airLineType": "waypoint", // 线 templateType waypointmapping2dmappingStrip
"uavId": "1",
"flyToFirstPointMode": "safely", // :flyToWaylineMode safelypointToPoint

@ -29,15 +29,15 @@
</a-form-item>
<a-form-item ref="name" label="选择航线" name="name">
<a-button type="primary" style="width:100%;" @click="selectAriLine" v-show="!submitForm.taskAirLine">
<a-button type="primary" style="width:100%;" @click="selectAriLine" v-show="!submitForm.airLineId">
<PlusOutlined />
选择航线
</a-button>
<div class="select-item" v-show="submitForm.taskAirLine">
<div class="item-name">{{props.checkedAriLine.airLineName}}</div>
<div class="select-item" v-show="submitForm.airLineId">
<div class="item-name">{{submitForm.taskAirLineName}}</div>
<div class="item-operate">
<DeleteOutlined @click="submitForm.taskAirLine = null"/>
<MoreOutlined @click="selectAriLine"/>
</div>
</div>
</a-form-item>
@ -49,9 +49,9 @@
</a-button>
<div class="select-item" v-show="submitForm.taskDronePort">
<div class="item-name">{{props.checkedDronePort.name}}</div>
<div class="item-name">{{submitForm.taskDronePortName}}</div>
<div class="item-operate">
<DeleteOutlined @click="submitForm.taskDronePort = null" />
<MoreOutlined @click="selectAircraft" />
</div>
</div>
@ -122,7 +122,7 @@
</a-form-item>
<a-form-item ref="outOfContact" label="完成动作" name="outOfContact" v-if="submitForm.lossOfControlAction == 'executeLostAction'">
<a-form-item ref="outOfContact" label="完成动作" name="outOfContact" v-if="submitForm.lossOfControlAction == 1">
<div class="radio-box">
<div v-for="(item,index) in continuationModeOptions" :key="index"
:class=" submitForm.continuationMode == item.value ? 'radio-item-active':'radio-item'"
@ -148,7 +148,7 @@
</template>
<script lang="ts" setup>
import { ref, defineEmits, defineProps, watch } from "vue";
import { PlusOutlined,LeftOutlined,DeleteOutlined } from '@ant-design/icons-vue';
import { PlusOutlined,LeftOutlined,DeleteOutlined,MoreOutlined } from '@ant-design/icons-vue';
import { addTask,editTask } from "@/api/sys/workplan";
import { Modal, message } from 'ant-design-vue';
const formRef = ref();
@ -158,31 +158,63 @@ const props = defineProps(["checkedAriLine","checkedDronePort","formData"]);
// const submitForm = ref({
// taskName:null, //
// taskType:0, //
// taskDronePort:null, // s
// taskAirLine:null, // 线id
// returnAltitude:0, //
// lossOfControlAction:"executeLostAction", //
// continuationMode:"goBack", //
// aiInspection:null, // AI
// periodicFormula:0, //
// airLineId:1, // 线id
// waylinePrecisionType:0, //
// taskAirLineName : null,
// taskDronePortName : null,
// })
const submitForm = ref({
taskName:null, //
taskType:0, //
taskDronePort:null, // s
taskAirLine:null, // 线id
returnAltitude:0, //
lossOfControlAction:"executeLostAction", //
continuationMode:"goBack", //
aiInspection:null, // AI
periodicFormula:0, //
airLineId:1, // 线id
waylinePrecisionType:0, //
"id": null,
"taskName": null,
"taskType": 0,
"taskAirLineName": null,
"taskDronePortName": null,
"taskDronePort": null,
"taskAirLine": null,
"returnAltitude": 0,
"lossOfControlAction": 0,
"continuationMode": null,
"aiInspection": null,
"status": 0,
"periodicFormula": null,
"airLineId": null,
"createId": 0,
"createTime": "",
"waylinePrecisionType": 0,
"scheduledStartTime": "",
"scheduledEndTime": "",
"executeTime": "",
"completedTime": "",
"planExecuteDuration": 0,
"actualExecuteDuration": 0,
"workspaceId": null,
"expectedFileCount": 0,
"uploadedFileCount": 0,
"flightId": null,
"reason": null
})
if(props.formData){
submitForm.value = props.formData
console.log("formData",props.formData);
}
watch(
()=>props.checkedAriLine,
(newVal,oldVal)=>{
submitForm.value.taskAirLine = newVal.airLineName;
submitForm.value.taskAirLineName = newVal.airLineName;
submitForm.value.airLineId = newVal.id;
}
)
@ -190,6 +222,8 @@ watch(
watch(
()=>props.checkedDronePort,
(newVal,oldVal)=>{
console.log("newVal",newVal);
submitForm.value.taskDronePortName = newVal.name;
submitForm.value.taskDronePort = newVal.id;
}
)
@ -235,10 +269,10 @@ const waylinePrecisionTypeOptions = ref([
//
const lossOfControlActionOptions = ref([
{
value:'goContinue',
value:0,
label:"继续执行航线"
},{
value:'executeLostAction',
value:1,
label:"执行失控动作"
}
])
@ -246,14 +280,14 @@ const lossOfControlActionOptions = ref([
//
const continuationModeOptions = ref([
{
value:"goBack",
value:0,
label:"返航"
},{
value:"landing",
label:"降落"
},{
value:"hover",
value:1,
label:"悬停"
},{
value:2,
label:"降落"
}
])
@ -282,7 +316,10 @@ const onSubmit =async () => {
if(props.formData){
//
let res = await editTask(submitForm.value);
let data = {...submitForm.value}
let res = await editTask(data);
if(res){
message.success("操作成功!");
emit("successCreatePlan");

@ -3,7 +3,7 @@
<!-- 航点航线 -->
<div v-if="props.airRoute.airLineType == '航点航线'" class="air-container">
<airPoint :airPoints="airPoints" @setFlyPoint="setFlyPoint" @exitDraw="exitDraw" :airInfo="lineInfo" :polygonAirForm="polygonAirForm" @checkPoint="checkPoint"></airPoint>
<airPoint :wayline="props.wayline" :airPoints="airPoints" @setFlyPoint="setFlyPoint" @exitDraw="exitDraw" :airInfo="lineInfo" :polygonAirForm="polygonAirForm" @checkPoint="checkPoint"></airPoint>
</div>
<!-- 航面航线 -->
@ -33,7 +33,7 @@ import * as turf from '@turf/turf'
import airPolygon from './airPolygon.vue'
import airPointConfig from './airPointConfig.vue'
const props = defineProps(["airRoute","flyToTherePosition"]);
const props = defineProps(["airRoute","flyToTherePosition","wayline","waylineInfo"]);
watch(
()=> props.airRoute,
@ -42,6 +42,70 @@ watch(
}
)
watch(
()=>props.wayline,
(newVal,oldVal)=>{
generatePreviewPoint(newVal?.Folder?.Placemark);
}
)
// 线
const generatePreviewPoint = (placemark)=>{
//
startPosition.value = [118.296626,35.134563,69.7];
//
clearAllLayer();
placemark?.forEach((item,index)=>{
let coordinate = item.Point.coordinates.split(",")
let airPointInfo = {
id:item.index,
name:"航点",
lng:coordinate[0],
lat:coordinate[1],
alt:item.executeHeight,
aircraftHorizontalAngle:0,
cameraHorizontalAngle:0,
cameraVerticalAngle:0,
focalLength:0,
}
airPoints.value?.push(airPointInfo);
})
if(props.waylineInfo.value?.airLineType == 'waypoint'){ // 线
airPoints.value?.forEach((item,index)=>{
let drawPoint = {
_lng:item.lng,
_lat:item.lat,
_alt:item.alt
}
preViewPointWayLine(drawPoint);
})
}else if(props.waylineInfo.value?.airLineType == 'mapping2d'){
let coordinates = [];
airPoints.value?.forEach((item,index)=>{
coordinates.push([item.lng,item.lat]);
})
console.log("coordinates",coordinates);
let line = turf.lineString(coordinates);
preViewPolygonWayLine(line);
}
}
const emits = defineEmits(["exitDraw","flyToThere"])
@ -682,8 +746,8 @@ const handlerDrawLine = () => {
}
// 线
let lineString = turf.lineString(positions);
lineInfo.value.length = turf.length(lineString).toFixed(2);
// let lineString = turf.lineString(positions);
// lineInfo.value.length = turf.length(lineString).toFixed(2);
}
const startPosition = ref(null);
@ -760,6 +824,8 @@ const handlerDrawPolygon = async () => {
CalculateAreaInfo(polygon,lines);
console.log("lines",lines);
// 线
handlerDrawPolygonLine(lines);
}
@ -767,7 +833,6 @@ const handlerDrawPolygon = async () => {
// 线
const handlerDrawPolygonLine = (lines) => {
const graphic = new mars3d.graphic.BillboardEntity({
id:"节点",
name: "航点",
@ -796,8 +861,6 @@ const handlerDrawPolygonLine = (lines) => {
lines.geometry.coordinates.unshift(polygonAirForm.value.startingPoint);
if(polygonLineGraphicLayer){
polygonLineGraphicLayer.clear();
@ -1352,6 +1415,110 @@ const uavGraphicMove = (e) => {
})
}
}
// 线
const preViewPointWayLine = (position) => {
if(moveTool){
moveTool.destroy();
moveTool = null;
}
let uuid = buildUUID();
//
let startGraphic = new mars3d.graphic.BillboardEntity({
id:"start-graphic",
position: startPosition.value,
style: {
image: "/map/start.png",
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
label: {
text: "参考起飞点",
font_size: 14,
color: "#ffffff",
outline: true,
outlineColor: "#000000",
pixelOffsetY: -35
}
}
})
graphicLayer.addGraphic(startGraphic);
//
let graphic = new mars3d.graphic.BillboardEntity({
id:uuid,
name: "航点",
position: [position._lng,position._lat,position._alt],
style: {
image: "/map/node.png",
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
label: {
text: "航点",
font_size: 14,
color: "#ffffff",
outline: true,
outlineColor: "#000000",
pixelOffsetY: -35
}
},
})
graphicLayer.addGraphic(graphic)
//
let stickGraphic = new mars3d.graphic.PointEntity({
id:"stick"+uuid,
position: [position._lng,position._lat],
style: {
color: "#f5f5f5",
pixelSize: 8,
outline: true,
outlineColor: "#f5f5f5",
outlineWidth: 1,
clampToGround:true,
}
})
stickGroundPointLayer.addGraphic(stickGraphic);
// 线
let lineGraphic = new mars3d.graphic.PolylineEntity({
id:"line"+uuid,
positions: [[position._lng,position._lat,position._alt], [position._lng,position._lat,0]],
style: {
color: '#f5f5f5',
width: 1,
},
});
lineGroundPointLayer.addGraphic(lineGraphic);
graphicLayer.flyTo();
// 线
handlerDrawLine();
}
// 线
const preViewPolygonWayLine = (lines) => {
handlerDrawLine();
}
//
const clearAllLayer = ()=>{
graphicLayer ? graphicLayer.clear() : null;
stickGroundPointLayer ? stickGroundPointLayer.clear() : null;
lineGroundPointLayer ? lineGroundPointLayer.clear() : null;
polygonGraphicLayer ? polygonGraphicLayer.clear() : null;
polygonLineGraphicLayer ? polygonLineGraphicLayer.clear() : null;
airPoints.value = [];
}
</script>
<style scoped>

@ -77,17 +77,26 @@
<script lang="ts" setup>
import { UserOutlined,PlusOutlined,FileAddOutlined,LeftOutlined,ImportOutlined,MoreOutlined,EditOutlined } from '@ant-design/icons-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import {ref,defineEmits,createVNode} from 'vue'
import {ref,defineEmits,defineProps,createVNode,watch} from 'vue'
import { Modal, message } from 'ant-design-vue';
import { getTaskPageList, deleteTask,executeFlyTask,pendingFlyTask } from '@/api/sys/workplan';
const emit = defineEmits(["checkAriLine","createWorkPlan"])
const emit = defineEmits(["planDetail","createWorkPlan"])
const createWorkPlan = (data) => {
emit("createWorkPlan",data);
}
const props = defineProps(["planListShow"])
watch(
()=>props.planListShow,
(newVal,oldVal)=>{
getTaskList();
}
)
const ariLineList = ref([]);
const lineListTotal = ref(0);
const pageQuery = ref({
@ -118,6 +127,7 @@
}else{
message.error("操作失败!");
}
getTaskList();
},
});
@ -138,11 +148,16 @@
}else{
message.error("操作失败!");
}
getTaskList();
},
});
}
const detail = (item) => {
}
const pendingPlan = async (id) => {
Modal.confirm({
@ -163,7 +178,7 @@
}
const checkAriLine = (item)=> {
emit("checkAriLine",item);
emit("planDetail",item);
}
const expandedKeys = ref<string[]>(['0-0', '0-1']);

@ -1,12 +1,12 @@
<template>
<div>
<div style="width:100%;height: calc( 100vh - 80px);" >
<Map :airRoute="airRoute" @exitDraw="exitDraw" @flyToThere="flyToThere"></Map>
<Map :airRoute="airRoute" @exitDraw="exitDraw" @flyToThere="flyToThere" :wayline="wayline" :waylineInfo="waylineInfo"></Map>
</div>
<!-- 工作计划列表 -->
<div v-show="planListShow" style="width:360px;background:#0d0e15c1 ;position:absolute;top:0px;left:0px;z-index:1;height: calc( 100vh - 104px);overflow-y:hidden;">
<planList @createWorkPlan="toCreateWorkPlan" ></planList>
<planList :planListShow="planListShow" @planDetail="planDetail" @createWorkPlan="toCreateWorkPlan" ></planList>
</div>
<!-- 创建计划弹窗 -->
@ -16,7 +16,7 @@
<!-- 航线库 -->
<div v-if="ariLineShow" style="width:566px;background:#0d0e15c1 ;position:absolute;top:30px;left:440px;z-index:1;height: calc( 100vh - 164px);overflow-y:hidden;">
<airLineList @checkAriLine="checkAriLine" @createAirLine="handlerCreateAirLine"></airLineList>
<airLineList @checkAriLine="checkAriLine" @previewAirLine="previewAirLine" @createAirLine="handlerCreateAirLine"></airLineList>
</div>
<!-- 飞行器 -->
@ -135,4 +135,20 @@ const exitDraw = ()=>{
workPlanFormShow.value = true;
ariLineShow.value = true;
}
// 线
const planDetail = (item) => {
formData.value = item;
workPlanFormShow.value = true;
}
// 线
const wayline = ref({});
const waylineInfo = ref(null)
const previewAirLine = (line,type) => {
wayline.value = line;
waylineInfo.value = type;
}
</script>

Loading…
Cancel
Save