航点航线

main
徐景良 3 months ago
parent 9f28e09454
commit c125b18a30

@ -1,14 +1,26 @@
import { defHttp } from '@/utils/http/axios';
enum Api{
enum Api{
// 任务
GetTaskPageList = '/api/Manage/GetTaskPageList',
AddTask = '/api/Manage/AddTask',
EditTask = '/api/Manage/EditTask',
DeleteTask = '/api/Manage/DeleteTask',
// 无人机
GetUavPageList = '/api/Manage/GetUavPageList',
GetAirLineList = '/api/Manage/GetAirLineList'
// 航线
GetAirLineList = '/api/Manage/GetAirLineList',
AddAirLine = '/api/Manage/AddAirLine',
EditAirLine = '/api/Manage/EditAirLine',
DeleteAirLine = '/api/Manage/DeleteAirLine',
UploadXmlFile = '/api/Manage/UploadXmlFile/upload'
}
// 任务
export function getTaskPageList(params) {
return defHttp.get({ url: Api.GetTaskPageList, params });
}
@ -25,12 +37,30 @@ export function deleteTask(params){
return defHttp.post({ url: Api.DeleteTask+"?id="+params.id, params });
}
// 无人机
export function getUavPageList(params) {
return defHttp.get({ url: Api.GetUavPageList, params });
}
// 航线
export function getAirLineList(params) {
return defHttp.get({ url: Api.GetAirLineList, params });
}
export function addAirLine(params){
return defHttp.post({ url: Api.AddAirLine, params });
}
export function editAirLine(params){
return defHttp.post({ url: Api.EditAirLine, params });
}
export function uploadXmlFile(params){
return defHttp.post({ url: Api.UploadXmlFile, params,headers: {'Content-Type': 'multipart/form-data' }});
}
export function deleteAirLine(params){
return defHttp.post({ url: Api.DeleteAirLine+"?id="+params.id, params });
}

@ -38,18 +38,19 @@
<div class="filter-button">
<svg t="1749104685102" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6766" width="24" height="24"><path d="M712.313523 0.469118v51.176544c-208.544417 0-446.600641 148.795802-446.600641 279.040107 0 41.197118 9.552955 70.367748 31.68681 107.342801l7.25001 11.600017 17.314731 27.422098 3.497064 5.714714c31.729457 53.820666 34.075049 100.007497-2.004415 164.959061-51.38978 92.458956-145.682562 173.914956-282.281288 244.965057l-18.039731 9.211778L0.234559 856.098288c137.920786-68.960393 230.507684-146.919329 278.485694-233.237099 26.867686-48.404481 25.502978-75.314814 2.644122-114.123694l-21.579443-34.20299-6.22648-10.107367c-26.611803-44.438299-39.022115-81.882471-39.022114-133.741369 0-162.059056 255.669485-324.629878 485.878638-330.088709L712.313523 0.469118z m49.470659 185.514973l22.901504 45.717712-18.892674 9.638249-16.845613 9.083837c-68.661863 38.126525-82.053059 63.288326-72.329516 121.757528 3.539711 21.110324 17.442672 42.775061 44.566241 71.092749l8.316188 8.529424 9.595602 9.425014 31.089751 29.852984c59.876557 57.744201 90.3266 98.514847 104.058973 153.231102 20.129441 80.645704 21.408854 148.326684 2.857357 203.000292l-3.966182 10.747074-47.508892-19.020616c18.039732-45.120653 18.039732-105.850152-1.066178-182.316438-10.022073-40.088293-33.307401-72.926575-80.219233-119.411936l-42.34859-40.813294-12.282371-12.154429a601.06851 601.06851 0 0 1-5.458831-5.62942c-33.648578-35.141227-52.498605-64.525093-58.128025-98.131023-14.926492-89.644246 14.07355-130.628129 114.592812-183.809088l21.067677-10.832368zM574.904502 797.970264v50.579484h-29.852984v-50.622131h29.852984z m0-136.513432v85.29424h-29.852984v-85.29424h29.852984z m-25.161801-139.882554c14.627962 30.492691 23.072092 58.767731 24.863271 87.511891l-29.852984 1.833826c-1.450002-24.479447-8.827954-49.172129-21.92062-76.466286z m-68.278039-119.028112l7.505893 14.286786 35.269168 58.213318-25.588272 15.352964-31.302986-51.517721a446.856524 446.856524 0 0 1-12.538253-22.858857l26.65445-13.47649zM458.264629 268.719504l25.75886 15.09708a192.082629 192.082629 0 0 0-15.99267 34.927991c-4.264712 12.836783-5.117654 24.820624-2.985298 37.955937l-29.426513 4.861772a106.191329 106.191329 0 0 1 4.136771-52.370663c4.776477-14.07355 11.002957-27.55004 18.50885-40.472117z m104.186914-99.282496l15.011786 25.844155a284.712174 284.712174 0 0 0-64.013327 49.641248l-21.707384-20.513265a314.351922 314.351922 0 0 1 70.708925-54.972138z m131.011953-51.261838l7.25001 29.000041a533.515472 533.515472 0 0 0-78.811878 26.014744l-11.642663-27.507393c25.588272-10.875016 53.436841-20.044146 83.161884-27.507392z" fill="#ffffff" p-id="6767"></path></svg>
</div>
<div class="filter-button">
<svg t="1749104905772" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8872" width="24" height="24"><path d="M618.282667 150.570667a33.578667 33.578667 0 1 0-22.357334-63.317334L193.066667 229.461333A33.578667 33.578667 0 0 0 170.666667 261.12v189.568c0 18.56 15.018667 33.578667 33.578666 33.578667h369.322667v75.050666h-78.336v-50.346666a22.4 22.4 0 0 0-44.8 0v50.346666h-246.186667a33.578667 33.578667 0 0 0-33.578666 33.578667v165.888c0 13.610667 8.192 25.856 20.778666 31.061333L594.346667 955.733333a33.493333 33.493333 0 0 0 46.336-31.061333 33.578667 33.578667 0 0 0-20.821334-31.061333l-382.037333-157.312v-109.824h369.28a33.578667 33.578667 0 0 0 33.578667-33.578667v-142.208a33.578667 33.578667 0 0 0-33.578667-33.578667h-111.872V329.941333a22.4 22.4 0 1 0-44.8 0v87.168H237.866667v-132.266666L618.24 150.613333z m235.093333 113.92v-89.6a22.4 22.4 0 1 0-44.8 0v89.6a22.4 22.4 0 1 0 44.8 0z m-103.850667-100.821334l-86.058666 24.576a22.4 22.4 0 1 0 12.288 43.050667l86.101333-24.618667a22.4 22.4 0 0 0-12.330667-43.008z m-172.16 49.194667l-86.058666 24.576a22.4 22.4 0 0 0 12.288 43.050667l86.058666-24.618667a22.4 22.4 0 1 0-12.288-43.008zM853.333333 443.52V353.962667a22.4 22.4 0 1 0-44.757333 0v89.557333a22.4 22.4 0 1 0 44.8 0z m0 179.072v-89.557333a22.4 22.4 0 1 0-44.757333 0v89.514666a22.357333 22.357333 0 1 0 44.8 0z m-386.645333 176.512l2.986667 0.853333a22.4 22.4 0 0 0 25.685333-32.426666l-0.128-0.213334v-79.274666a22.4 22.4 0 1 0-44.8 0v89.557333c0 9.984 6.656 18.773333 16.256 21.504z m386.645333 2.56v-89.6a22.4 22.4 0 1 0-44.757333 0v89.6a22.357333 22.357333 0 1 0 44.8 0z m-297.6 22.912l86.101334 24.576a22.4 22.4 0 0 0 12.288-43.050667l-86.101334-24.576a22.4 22.4 0 1 0-12.288 43.050667z m172.16 49.152l86.101334 24.618667a22.4 22.4 0 1 0 12.288-43.050667l-86.058667-24.576a22.4 22.4 0 0 0-12.330667 43.050667z" p-id="8873" fill="#ffffff"></path></svg>
<div class="filter-button" @click="showSearchInput = !showSearchInput">
<svg t="1750122415214" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4744" width="24" height="24"><path d="M670.528 760.96a384 384 0 1 1 90.496-90.496l180.224 180.288a64 64 0 0 1-90.496 90.496l-180.224-180.224zM448 704a256 256 0 1 0 0-512 256 256 0 0 0 0 512z" fill="#ffffff" p-id="4745"></path></svg>
</div>
</div>
</div>
<div class="search-container">
<div class="search-container" v-show="showSearchInput">
<a-input-search
v-model:value="pageQuery.key"
placeholder="输入路线名称"
/>
</div>
<div class="routers-container">
<div class="file-container">
<div class="tip">
@ -69,22 +70,34 @@
</div>
<div class="routers-list">
<div class="tip">
<div class="info">航线</div>
<div class="info">航线{{ariLineCount}}</div>
<div>
<ImportOutlined />
<ImportOutlined @click="importAirLine" />
&nbsp;
<PlusOutlined @click="createAirLine" />
</div>
</div>
<div class="ari-line" v-for="(item,index) in ariLineList" :key="index" @click="checkAriLine(item)">
<div class="ari-line" v-for="(item,index) in ariLineList" :key="index" >
<div class="title">
<div style="flex:1;">
{{item.airLineName}}
</div>
<div style="">
<EditOutlined />
<!-- <EditOutlined @click="editLine" /> -->
&nbsp;
<MoreOutlined />
<a-dropdown>
<MoreOutlined />
<template #overlay>
<a-menu>
<a-menu-item>
<a href="javascript:;">编辑</a>
</a-menu-item>
<a-menu-item @click="deletePlan(item.id)">
<a href="javascript:;">删除</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
</div>
<div class="type" >
@ -95,16 +108,89 @@
</div>
</div>
</div>
<!-- 导入航线弹窗 -->
<div class="import-airline" v-if="importAirLineShow">
<div class="import-airline-title">
导入航线
</div>
<div class="import-airline-box">
<a-upload-dragger
v-model:fileList="fileList"
name="xmlFile"
:multiple="false"
:before-upload="beforeUpload"
@change="handleDragUploadChange"
>
<p class="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
<p class="ant-upload-hint">
单次上传1个文件仅支持.kmz格式文件
</p>
</a-upload-dragger>
</div>
<div class="import-airline-footer">
<div>
<a-button type="default" @click="importAirLineShow = false">取消</a-button>
</div>
<div>
<a-button type="primary" @click="handleManualUpload"></a-button>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { PlusOutlined,FileAddOutlined,LeftOutlined,ImportOutlined,MoreOutlined,EditOutlined } from '@ant-design/icons-vue';
import {ref,defineEmits} from 'vue'
import { ExclamationCircleOutlined,PlusOutlined,FileAddOutlined,LeftOutlined,ImportOutlined,MoreOutlined,EditOutlined,InboxOutlined } from '@ant-design/icons-vue';
import {ref,defineEmits,createVNode} from 'vue'
import { getAirLineList } from '@/api/sys/workplan';
import { getAirLineList,uploadXmlFile,deleteAirLine } from '@/api/sys/workplan';
import { Modal, message } from 'ant-design-vue';
const emit = defineEmits(["checkAriLine","createAirLine"])
//
const importAirLineShow = ref(false);
const fileList = ref([]);
const headers = ref({
'x-token':'ed973c9d'
})
const beforeUpload = ()=>{
return false;
}
const handleDragUploadChange =(info)=> {
const status = info.file.status;
if (status === 'removed') {
fileList.value = [];
}
}
const handleManualUpload = async () => {
if (fileList.value.length<1) return;
const formData = new FormData();
formData.append('xmlFile', fileList.value[0]?.originFileObj);
let res = await uploadXmlFile(formData);
if(res){
fileList.value = [];
importAirLineShow.value = false;
message.success("操作成功!");
}else{
message.error("操作失败!");
}
}
const showSearchInput = ref(false);
const createAirLine = () => {
emit("createAirLine");
}
@ -112,6 +198,10 @@
emit("checkAriLine",item);
}
const importAirLine = () => {
importAirLineShow.value = true;
}
const expandedKeys = ref<string[]>(['0-0', '0-1']);
const selectedKeys = ref<string[]>([]);
const treeData = ref(
@ -136,6 +226,7 @@
)
const ariLineList = ref([])
const ariLineCount = ref(0);
const pageQuery = ref({
page:1,
@ -147,12 +238,36 @@
let res = await getAirLineList(pageQuery.value);
ariLineCount.value = res.total;
ariLineList.value = res.items;
}
getAirList();
const editLine = ()=>{
}
const deletePlan = async (id) => {
Modal.confirm({
title: '是否确认删除?',
icon: createVNode(ExclamationCircleOutlined),
onCancel() {},
async onOk() {
let res = await deleteAirLine({id:id});
if(res){
message.success("操作成功!");
getAirList();
}else{
message.error("操作失败!");
}
},
});
}
</script>
<style scoped>
.container{
@ -167,6 +282,7 @@
padding:0px 15px;
display:flex;
gap:8px;
margin-bottom:12px;
}
.search-container{
width: calc( 100% - 30px);
@ -267,7 +383,37 @@
color:#ccc;
}
.import-airline{
width:100%;
height:100%;
background:#1c1c1c;
position:absolute;
top:0px;
left:0px;
z-index:999;
text-align: center;
color:#fff;
}
.import-airline-title{
padding:20px;
background: #282828;
}
.import-airline-box{
padding:20px;
color:#fff;
}
.import-airline-footer{
width:100%;
position: absolute;
bottom:0px;
left:0px;
padding:20px;
display: flex;
justify-content: flex-end;
gap:15px;
background: #282828;
}
::v-deep .ant-select-selector{
border:none!important;
color:#fff!important;
@ -330,4 +476,20 @@
height:30px !important;
background:#29305477!important;
}
::v-deep .ant-upload-text{
color:#fff!important;
}
::v-deep .ant-upload-hint{
color:#fff!important;
}
::v-deep .ant-upload-wrapper .ant-upload-list{
color:#fff;
}
::v-deep .ant-upload-list-item-actions .anticon{
color:#fff;
}
</style>

@ -5,16 +5,111 @@
<div>航点航线</div>
<SaveOutlined/>
<a-dropdown :trigger="['click']">
<a-button type="primary" @click.prevent>
航线设置
<DownOutlined />
</a-button>
<template #overlay>
<div class="area-options">
<div class="item">
<div class="label">参考起飞点</div>
<div class="content">
<a-button type="link" style="color:#408eff" @click="setFlyPoint()">
<img src="./start-fly.png" style="width:24px;height:24px;position:relative;left:-2px;top:-2px;" alt="">
设置起飞点
</a-button>
</div>
</div>
<div class="item flex-column">
<div class="label">选择镜头</div>
<div class="content">
<a-radio-group button-style="solid" v-model:value="props.polygonAirForm.lensMode">
<a-radio-button :value="1">红外</a-radio-button>
<a-radio-button :value="2">可见光</a-radio-button>
</a-radio-group>
</div>
</div>
<div class="item flex-column">
<div class="label">采集方式</div>
<div class="content">
<a-radio-group button-style="solid" v-model:value="props.polygonAirForm.gatherMode">
<a-radio-button :value="1">正射采集</a-radio-button>
<a-radio-button :value="2">倾斜采集</a-radio-button>
</a-radio-group>
</div>
</div>
<div class="item">
<div class="label">智能摆动拍摄</div>
</div>
<div class="item flex-column">
<div class="label">航线高度模式</div>
<div class="content">
<a-radio-group button-style="solid" v-model:value="props.polygonAirForm.heightMode">
<a-radio-button :value="1">海拔高度</a-radio-button>
<a-radio-button :value="2">相对起点高度</a-radio-button>
<a-radio-button :value="3">相对地形高度</a-radio-button>
</a-radio-group>
<div style="margin-top:12px;">
<a-input-number v-model:value="props.polygonAirForm.height" :min="1" :max="100000" />
</div>
</div>
</div>
<div class="item">
<div class="label">全局航线速度</div>
<div class="content">
<a-input-number style="width:160px" v-model:value="props.polygonAirForm.speed" :min="1" :max="20" />
</div>
</div>
<div class="item">
<div class="label"> 主航线角度</div>
<div class="content">
<a-input-number width="160px" v-model:value="props.polygonAirForm.angle" :min="0" :max="180" />
</div>
</div>
<div class="item">
<div class="label"> 高程优化</div>
</div>
<div class="item">
<div class="label"> 完成动作</div>
<div class="content">
<a-select
ref="select"
style="width:160px;"
v-model:value="props.polygonAirForm.complete"
>
<a-select-option :value="1">自动返航</a-select-option>
<a-select-option :value="2">返回航线起始点悬停</a-select-option>
<a-select-option :value="3">退出航线模式</a-select-option>
<a-select-option :value="4">原地降落</a-select-option>
</a-select>
</div>
</div>
</div>
</template>
</a-dropdown>
<div style="flex:1;">
<a-input size="middle" placeholder="航线名称" />
</div>
</div>
<div class="area-info">
<div class="item">
<div>航点数量</div>
<div>1</div>
<div>{{ props.airPoints.length }}</div>
</div>
<div class="bar"></div>
<div class="item">
<div>航线长度</div>
<div>{{props.airInfo.length}} km</div>
@ -48,7 +143,7 @@
<div class="air-point-item" v-for="(item,index) in props.airPoints" :key="index">
<!-- <div class="cel">{{item.lng}}</div>
<div class="cel">{{item.lat}}</div> -->
<div class="cel">
<div class="cel" @click="checkPoint(item)">
<img src="/map/air-point.png" width="18" alt="">
{{index+1}}
</div>
@ -60,95 +155,13 @@
</div>
</div>
<div class="area-options" v-if="false">
<div class="item">
<div class="label">参考起飞点</div>
<div class="content">
<a-button type="link" style="color:#408eff" @click="setFlyPoint()">
<img src="./start-fly.png" style="width:24px;height:24px;position:relative;left:-2px;top:-2px;" alt="">
设置起飞点
</a-button>
</div>
</div>
<div class="item flex-column">
<div class="label">选择镜头</div>
<div class="content">
<a-radio-group button-style="solid" v-model:value="props.polygonAirForm.lensMode">
<a-radio-button :value="1">红外</a-radio-button>
<a-radio-button :value="2">可见光</a-radio-button>
</a-radio-group>
</div>
</div>
<div class="item flex-column">
<div class="label">采集方式</div>
<div class="content">
<a-radio-group button-style="solid" v-model:value="props.polygonAirForm.gatherMode">
<a-radio-button :value="1">正射采集</a-radio-button>
<a-radio-button :value="2">倾斜采集</a-radio-button>
</a-radio-group>
</div>
</div>
<div class="item">
<div class="label">智能摆动拍摄</div>
</div>
<div class="item flex-column">
<div class="label">航线高度模式</div>
<div class="content">
<a-radio-group button-style="solid" v-model:value="props.polygonAirForm.heightMode">
<a-radio-button :value="1">海拔高度</a-radio-button>
<a-radio-button :value="2">相对起点高度</a-radio-button>
<a-radio-button :value="3">相对地形高度</a-radio-button>
</a-radio-group>
<div style="margin-top:12px;">
<a-input-number v-model:value="props.polygonAirForm.height" :min="1" :max="100000" />
</div>
</div>
</div>
<div class="item">
<div class="label">全局航线速度</div>
<div class="content">
<a-input-number style="width:160px" v-model:value="props.polygonAirForm.speed" :min="1" :max="20" />
</div>
</div>
<div class="item">
<div class="label"> 主航线角度</div>
<div class="content">
<a-input-number width="160px" v-model:value="props.polygonAirForm.angle" :min="0" :max="180" />
</div>
</div>
<div class="item">
<div class="label"> 高程优化</div>
</div>
<div class="item">
<div class="label"> 完成动作</div>
<div class="content">
<a-select
ref="select"
style="width:160px;"
v-model:value="props.polygonAirForm.complete"
>
<a-select-option :value="1">自动返航</a-select-option>
<a-select-option :value="2">返回航线起始点悬停</a-select-option>
<a-select-option :value="3">退出航线模式</a-select-option>
<a-select-option :value="4">原地降落</a-select-option>
</a-select>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import {ref,defineEmits,defineProps} from 'vue'
import { SaveOutlined,LeftOutlined } from '@ant-design/icons-vue';
const emits = defineEmits(["setFlyPoint"])
import { SaveOutlined,LeftOutlined,AppstoreOutlined,DownOutlined} from '@ant-design/icons-vue';
const emits = defineEmits(["setFlyPoint","checkPoint"])
const props = defineProps(["airPoints","airInfo","polygonAirForm"])
@ -163,6 +176,10 @@ const setFlyPoint = ()=>{
emits("setFlyPoint");
}
const checkPoint = (e)=>{
emits("checkPoint",e);
}
</script>
<style scoped>
.container{
@ -197,11 +214,14 @@ const setFlyPoint = ()=>{
}
.area-options{
width:100%;
height: calc( 100vh - 260px);
width:400px;
height: calc( 100vh - 160px);
padding:10px;
position: absolute;
left:-160px;
overflow-y:auto;
line-height:32px;
background:#232323;
}
.area-options .item{

@ -6,10 +6,10 @@
</div>
<div class="item-content">
<a-input-number
v-model:value="config.lng"
v-model:value="props.currentAirPoint.lng"
:min="-180"
:max="180"
:step="0.00000001"
:step="0.0001"
string-mode
/>
</div>
@ -21,10 +21,10 @@
</div>
<div class="item-content">
<a-input-number
v-model:value="config.lat"
v-model:value="props.currentAirPoint.lat"
:min="-90"
:max="90"
:step="0.00000001"
:step="0.0001"
string-mode
/>
</div>
@ -36,9 +36,9 @@
</div>
<div class="item-content">
<a-input-number
v-model:value="config.alt"
v-model:value="props.currentAirPoint.alt"
:min="0"
:step="0.01"
:step="1"
string-mode
/>
</div>
@ -50,11 +50,11 @@
飞行器偏航角
</div>
<div>
{{ config.aircraftHorizontalAngle }} °
{{ props.currentAirPoint.aircraftHorizontalAngle }} °
</div>
</div>
<div class="item-content">
<a-slider v-model:value="config.aircraftHorizontalAngle" :min="-180" :max="180" :step="0.01" />
<a-slider v-model:value="props.currentAirPoint.aircraftHorizontalAngle" :min="-180" :max="180" :step="0.01" />
</div>
</div>
@ -64,11 +64,11 @@
云台偏航角
</div>
<div>
{{ config.cameraHorizontalAngle }} °
{{ props.currentAirPoint.cameraHorizontalAngle }} °
</div>
</div>
<div class="item-content">
<a-slider v-model:value="config.cameraHorizontalAngle" :min="-180" :max="180" :step="0.01" />
<a-slider v-model:value="props.currentAirPoint.cameraHorizontalAngle" :min="-180" :max="180" :step="0.01" />
</div>
</div>
@ -78,12 +78,12 @@
云台俯仰角
</div>
<div class="">
{{ config.cameraVerticalAngle }} °
{{ props.currentAirPoint.cameraVerticalAngle }} °
</div>
</div>
<div class="item-content">
<a-slider v-model:value="config.cameraVerticalAngle" :min="-180" :max="180" :step="0.01" />
<a-slider v-model:value="props.currentAirPoint.cameraVerticalAngle" :min="-180" :max="180" :step="0.01" />
</div>
</div>
@ -93,11 +93,11 @@
相机焦距
</div>
<div class="">
× {{ config.cameraFocalLength }}
× {{ props.currentAirPoint.cameraFocalLength }}
</div>
</div>
<div class="item-content">
<a-slider v-model:value="config.cameraFocalLength" :min="1" :max="56" />
<a-slider v-model:value="props.currentAirPoint.cameraFocalLength" :min="1" :max="56" />
</div>
</div>
@ -106,8 +106,17 @@
<script lang="ts" setup>
import {ref} from 'vue';
import {ref,defineProps,watch} from 'vue';
const props = defineProps(['currentAirPoint'])
watch(
()=>props.currentAirPoint,
(newVal,oldVal)=>{
console.log("newVal",newVal);
}
)
const config = ref({
id:"1",
name:"航点",

@ -3,7 +3,7 @@
<!-- 航点航线 -->
<div v-if="props.airRoute.airLineType == '航点航线'" class="air-container">
<airPoint :airPoints="airPoints" @setFlyPoint="setFlyPoint" :airInfo="airInfo" :polygonAirForm="polygonAirForm"></airPoint>
<airPoint :airPoints="airPoints" @setFlyPoint="setFlyPoint" :airInfo="lineInfo" :polygonAirForm="polygonAirForm" @checkPoint="checkPoint"></airPoint>
</div>
<!-- 航面航线 -->
@ -12,8 +12,8 @@
</div>
<!-- 航点航线配置 -->
<div class="airpoint-config-container">
<airPointConfig></airPointConfig>
<div class="airpoint-config-container" v-if="airPointConfigShow">
<airPointConfig :currentAirPoint="currentAirPoint"></airPointConfig>
</div>
</div>
@ -42,7 +42,25 @@ watch(
)
const airPoints = ref([])
const currentAirPoint = ref({});
const airPointConfigShow = ref(false);
//
watch(
currentAirPoint,
(newVal,oldVal)=>{
updateAirPoint(newVal);
},
{ deep: true }
)
const checkPoint = (e)=>{
currentAirPoint.value = e;
airPointConfigShow.value = true;
}
let map: mars3d.Map; //
let graphicLayer:mars3d.layer.GraphicLayer;
@ -54,6 +72,14 @@ let polygonLineGraphicLayer:mars3d.layer.GeoJsonLayer;
let graphic = null;
// 线
const lineInfo = ref({
count:0,
length:0,
time:0,
picture:'- -'
})
// 线
const airInfo = ref({
area:0,
length:0,
@ -310,6 +336,17 @@ const initMap = ()=>{
graphicLayer = new mars3d.layer.GraphicLayer({
isAutoEditing: false //
})
graphicLayer.bindContextMenu([
{
text: "删除航点",
icon: "fa fa-camera-retro", // font-class
callback: (e) => {
deleteAirPoint(e);
}
}
])
map.addLayer(graphicLayer);
//
@ -328,6 +365,11 @@ const handlerBindMapMenus = ()=>{
text: "添加航点",
icon: "fa fa-camera-retro", // font-class
callback: (e) => {
if(!startPosition.value){
message.warning("请先设置起飞点");
return null;
}
handlerDrawPoint(e);
}
},{
@ -355,15 +397,14 @@ const handlerDrawPoint = (e) => {
let position = mars3d.LngLatPoint.fromCartesian(e.position);
position._alt = position._alt + 100;
let uuid = buildUUID();
//
const graphic = new mars3d.graphic.BillboardEntity({
id:uuid,
name: "航点",
position: [position._lng,position._lat,position._alt+180],
position: [position._lng,position._lat,position._alt],
style: {
image: "/map/node.png",
scale: 1,
@ -379,16 +420,18 @@ const handlerDrawPoint = (e) => {
}
},
})
uavPoints.value.push(graphic);
uavPoints.value.push(graphic);
//
const rectSensor = new mars3d.graphic.RectSensor({
id: "-rectSensor",
position: [position._lng,position._lat,position._alt+180],
id: "camera"+uuid,
position: [position._lng,position._lat,position._alt],
show:true,
style: {
angle1: 30, // 1
angle2: 30, // 2
length: 100, //
length: 50, //
rayEllipsoid: true,
color: "rgba(0,255,255,0.3)",
outline: true,
@ -398,7 +441,7 @@ const handlerDrawPoint = (e) => {
cameraHpr: true,
heading: 0,
pitch: 180,
roll: 30, //
roll: 0, //
clippingPlanes: [{
distance: 0, // 0
normal: new Cesium.Cartesian3(0, 0, -1) //
@ -417,11 +460,13 @@ const handlerDrawPoint = (e) => {
aircraftHorizontalAngle:0,
cameraHorizontalAngle:0,
cameraVerticalAngle:0,
focalLength:2,
focalLength:0,
}
airPoints.value?.push(airPointInfo);
currentAirPoint.value = airPoints.value[airPoints.value?.length-1]
graphicLayer.addGraphic(graphic)
handlerDrawLine();
@ -430,27 +475,48 @@ const handlerDrawPoint = (e) => {
// 线
const handlerDrawLine = () => {
console.log("uavPoints",uavPoints.value);
let positions = [];
uavPoints.value?.forEach((item,index)=>{
positions.push(item._position);
})
console.log("positions",positions);
airPoints.value?.forEach((item,index)=>{
positions.push([item.lng,item.lat,item.alt]);
})
if(positions.length>1){
const graphic = new mars3d.graphic.PolylineEntity({
positions: positions,
style: {
width: 2,
color: "#3388ff",
},
})
graphicLayer.addGraphic(graphic)
positions.unshift([startPosition.value[0],startPosition.value[1],airPoints.value[0].alt])
positions.unshift([startPosition.value[0],startPosition.value[1],startPosition.value[2]]);
//
if(positions.length>0){
let lineGraphic = graphicLayer.getGraphicById("pointsLine");
if(lineGraphic){
lineGraphic.setOptions({
id:"pointsLine",
positions: positions,
style: {
width: 2,
color: "#3388ff",
},
})
}else{
const graphic = new mars3d.graphic.PolylineEntity({
id:"pointsLine",
positions: positions,
style: {
width: 2,
color: "#3388ff",
},
})
graphicLayer.addGraphic(graphic)
}
}
// 线
let lineString = turf.lineString(positions);
lineInfo.value.length = turf.length(lineString).toFixed(2);
}
const startPosition = ref(null);
@ -477,6 +543,7 @@ const setFlyPoint = async ()=>{
startPosition.value = graphic.toJSON().position
polygonAirForm.value.startingPoint = graphic.toJSON().position;
}
@ -733,10 +800,94 @@ const CalculateAreaInfo = (polygon,lines)=>{
//
}
//
const updateAirPoint = (e)=>{
// idgraphic
let graphic = graphicLayer.getGraphicById(e.id);
if(graphic){
graphic.setOptions({
id:e.id,
name: "航点",
position: [e.lng,e.lat,e.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
}
},
})
}
let cameraGraphic = graphicLayer.getGraphicById('camera'+e.id);
if(cameraGraphic){
cameraGraphic.setOptions({
position: [e.lng,e.lat,e.alt],
// style: {
// angle1: 30, // 1
// angle2: 30, // 2
// length: 50, //
// rayEllipsoid: true,
// color: "rgba(0,255,255,0.3)",
// outline: true,
// topShow: true,
// topSteps: 2,
// flat: true,
// cameraHpr: true,
// heading: 0,
// pitch: 180,
// roll: 0, //
// clippingPlanes: [{
// distance: 0, // 0
// normal: new Cesium.Cartesian3(0, 0, -1) //
// }]
// }
})
}
// 线
handlerDrawLine()
}
//
const deleteAirPoint = (e)=>{
let id = e.graphic.id;
//
let point = graphicLayer.getGraphicById(id);
if(point){
graphicLayer.removeGraphic(point);
}
//
let camera = graphicLayer.getGraphicById('camera'+id);
if(camera){
graphicLayer.removeGraphic(camera);
}
//
airPoints.value?.forEach((item,index)=>{
if(item.id == id){
airPoints.value?.splice(index,1);
}
})
// 线
handlerDrawLine()
}
</script>
<style scoped>

@ -45,17 +45,16 @@
<a-dropdown>
<MoreOutlined />
<template #overlay>
<a-menu>
<a-menu>
<a-menu-item>
<a href="javascript:;">编辑</a>
<a href="javascript:;">编辑</a>
</a-menu-item>
<a-menu-item @click="deletePlan(item.id)">
<a href="javascript:;">删除</a>
<a href="javascript:;">删除</a>
</a-menu-item>
</a-menu>
</a-menu>
</template>
</a-dropdown>
</a-dropdown>
</div>
</div>
<div class="type" >

@ -29,8 +29,6 @@
<createAirLine @createAirLine="handlerCreateAirRoute" @cancle="cancleCreateAirLine"></createAirLine>
</div>
</div>
</template>
<script lang="ts" setup>
@ -89,6 +87,7 @@ const cancleCreateAirLine = ()=>{
}
const handlerCreateAirRoute = (info)=>{
console.log("info",info);
workPlanFormShow.value = false;
ariLineShow.value = false;
aircraftShow.value = false;

Loading…
Cancel
Save