<template>
|
<div class="setting">
|
<a-popover placement="bottom" trigger="click" :getPopupContainer="(triggerNode: any) => triggerNode.parentNode">
|
<template #content>
|
<div class="setting-content">
|
<div class="start-point common">
|
<div class="title">起飞点</div>
|
<div class="value">{{ missionConfigSetting.takeOffRefPoint ? '已设置' : '未设置' }}</div>
|
</div>
|
<div class="photo-setting common">
|
<div class="title">拍照设置</div>
|
<ul class="select-box">
|
<li
|
class="select-item"
|
:style="{
|
'--settingColor': folderSetting.payloadParam.imageFormat.includes(item.value) ? '#409eff' : '#3c3c3c',
|
}"
|
v-for="item in photoSetting"
|
:key="item.value"
|
@click="selectPhotoSetting(item.value)">
|
{{ item.title }}照片
|
</li>
|
</ul>
|
<!-- <div class="auto-low-light">
|
<div class="title">自动低光</div>
|
<a-tooltip
|
placement="right"
|
:title="tipDescriptionEnums.rowLightModeTip">
|
<a-switch
|
v-model:checked="setting.orientedPhotoMode"
|
checkedValue="lowLightSmartShooting"
|
unCheckedValue="normalPhoto" />
|
</a-tooltip>
|
</div> -->
|
</div>
|
<!-- 爬升 -->
|
<div class="climb-mode common">
|
<a-tooltip placement="right" :title="tipDescriptionEnums.climbModeTip">
|
<div class="mode-box">
|
<a-radio-group v-model:value="missionConfigSetting.flyToWaylineMode" button-style="solid">
|
<a-radio-button value="safely">垂直爬升</a-radio-button>
|
<a-radio-button value="pointToPoint">倾斜爬升</a-radio-button>
|
</a-radio-group>
|
</div>
|
<div class="parameter-tool">
|
<div class="example-img">
|
<img :src="climbImage" alt="climb-img" />
|
</div>
|
<ul class="parameter-btn">
|
<li @click="numberControls(true, 100, 'takeOffSecurityHeight')">+100</li>
|
<li @click="numberControls(true, 10, 'takeOffSecurityHeight')">+10</li>
|
<li>
|
<span>{{ missionConfigSetting.takeOffSecurityHeight }}</span
|
>m
|
</li>
|
<li @click="numberControls(false, 100, 'takeOffSecurityHeight')">-100</li>
|
<li @click="numberControls(false, 10, 'takeOffSecurityHeight')">-10</li>
|
</ul>
|
</div>
|
</a-tooltip>
|
</div>
|
<!-- 高度模式 -->
|
<div class="height-mode common">
|
<a-tooltip
|
placement="right"
|
:title="tipDescriptionEnums[folderSetting.waylineCoordinateSysParam.heightMode]">
|
<div class="title">航线高度模式</div>
|
<div class="mode-box">
|
<a-radio-group v-model:value="folderSetting.waylineCoordinateSysParam.heightMode" button-style="solid">
|
<a-radio-button v-for="item in heightModeSetting" :key="item.value" :value="item.value">{{
|
item.title
|
}}</a-radio-button>
|
</a-radio-group>
|
</div>
|
<div class="parameter-tool">
|
<div class="example-img">
|
<img
|
:src="
|
folderSetting.waylineCoordinateSysParam.heightMode === heightModeSetting[0].value
|
? heightModeSetting[0].img
|
: heightModeSetting[1].img
|
"
|
alt="height-img" />
|
</div>
|
<div class="parameter-btn">
|
<li @click="numberControls(true, 100, 'globalHeight')">+100</li>
|
<li @click="numberControls(true, 10, 'globalHeight')">+10</li>
|
<li>
|
<span>{{ Math.round(folderSetting.globalHeight) }}</span> m
|
</li>
|
<li @click="numberControls(false, 100, 'globalHeight')">-100</li>
|
<li @click="numberControls(false, 10, 'globalHeight')">-10</li>
|
</div>
|
</div>
|
</a-tooltip>
|
</div>
|
<!-- 航线速度 -->
|
<div class="speed-setting common">
|
<div class="title">全局航线速度</div>
|
<div class="speed-box">
|
<div class="subtract" @click="numberControls(false, 1, 'autoFlightSpeed')">-</div>
|
<div class="text">
|
<a-input-number
|
:min="1"
|
:max="15"
|
class="value"
|
v-model:value="folderSetting.autoFlightSpeed"></a-input-number>
|
m / s
|
</div>
|
<div class="add" @click="numberControls(true, 1, 'autoFlightSpeed')">+</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
<slot name="show"></slot>
|
</a-popover>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { reactive, defineProps } from 'vue'
|
import { tipDescriptionEnums } from './enums'
|
import useKmzTsa, { kmlStr } from '/@/utils/cesium/use-kmz-tsa'
|
import useMapDraw from '/@/utils/cesium/use-map-draw'
|
import { getKmlParams } from '/@/utils/cesium/kmz'
|
import { cesiumOperation } from '/@/hooks/use-cesium-tsa'
|
import { message } from 'ant-design-vue'
|
import type { missionConfig, payloadParam as payloadParamConfig, Folder } from '/@/utils/cesium/types/kml'
|
const { appContext }: any = getCurrentInstance()
|
const global = appContext.config.globalProperties
|
|
const mapDraw = useMapDraw('', '', '', global)
|
const { removeAllDataSource, removeAllPoint } = cesiumOperation()
|
|
const kmzUtils = useKmzTsa()
|
|
const props = defineProps({
|
loadCompleted: Boolean,
|
})
|
|
const getResource = (name: string) => {
|
return new URL(`/src/assets/icons/${name}`, import.meta.url).href
|
}
|
const getSvgResource = (name: string) => {
|
return new URL(`/src/assets/svg/${name}`, import.meta.url).href
|
}
|
|
const climbImage = getSvgResource('climb.svg')
|
const imgs = []
|
|
const missionConfigSetting = reactive<missionConfig | any>({
|
flyToWaylineMode: 'safely',
|
// 航线结束动作
|
finishAction: 'goHome',
|
// 失控是否继续执行航线
|
exitOnRCLost: 'goContinue',
|
// 失控动作
|
executeRCLostAction: 'goBack',
|
// 安全起飞高度
|
takeOffSecurityHeight: 20,
|
// 全局航线速度
|
globalTransitionalSpeed: 10,
|
// 参考起飞点
|
takeOffRefPoint: '',
|
// 参考起飞点海拔高度
|
takeOffRefPointAGLHeight: 0,
|
// 全局返航高度
|
globalRTHHeight: 100,
|
droneInfo: {
|
droneEnumValue: 67,
|
droneSubEnumValue: 0,
|
},
|
payloadInfo: {
|
payloadEnumValue: 52,
|
payloadSubEnumValue: 1,
|
payloadPositionIndex: 0,
|
},
|
})
|
|
// 拍照设置
|
const photoSetting = reactive([
|
{ title: '广角', value: 'wide' },
|
{ title: '变焦', value: 'zoom' },
|
{ title: '红外', value: 'ir' },
|
])
|
|
// 高度模式
|
const heightModeSetting = reactive([
|
{
|
title: '绝对高度',
|
value: 'EGM96',
|
img: getSvgResource('jdgd.svg'),
|
},
|
{
|
title: '相对起飞高度',
|
value: 'relativeToStartPoint',
|
img: getSvgResource('xdqfd.svg'),
|
},
|
])
|
|
// folder设置
|
const folderSetting = reactive<Folder | any>({
|
templateType: 'waypoint',
|
templateId: 0,
|
waylineCoordinateSysParam: {
|
coordinateMode: 'WGS84',
|
heightMode: 'EGM96',
|
},
|
autoFlightSpeed: 10,
|
globalHeight: 100,
|
payloadParam: {
|
payloadPositionIndex: 0,
|
imageFormat: '',
|
},
|
caliFlightEnable: 0,
|
gimbalPitchMode: 'manual',
|
})
|
|
// 计算
|
const numberControls = (isAdd: boolean, computeVal: number, key: string) => {
|
if (isAdd) {
|
if (missionConfigSetting[key]) {
|
missionConfigSetting[key] += computeVal
|
} else {
|
folderSetting[key] += computeVal
|
}
|
} else {
|
if (missionConfigSetting[key]) {
|
missionConfigSetting[key] -= computeVal
|
} else {
|
if (folderSetting[key] - computeVal <= 0) {
|
return message.warn('飞行高度较低!!!!')
|
}
|
folderSetting[key] -= computeVal
|
}
|
}
|
|
if (key === 'globalHeight') {
|
const entities = mapDraw.kmlEntities.value
|
removeAllDataSource()
|
removeAllPoint()
|
mapDraw.drawWayline(entities, kmlStr.value)
|
}
|
}
|
|
// 获取机场默认值
|
watch(
|
() => props.loadCompleted,
|
(val) => {
|
if (val) {
|
getDefaultValue(missionConfigSetting)
|
getDefaultValue(folderSetting)
|
}
|
},
|
)
|
const getDefaultValue = (setting: any) => {
|
Object.keys(setting).forEach((key: string) => {
|
const param: RegExpMatchArray | any = getKmlParams(kmlStr.value, true, {
|
name: key,
|
findRegx: '([\\s\\S]*?)',
|
})
|
if (Object.prototype.toString.call(setting[key]) === '[object Object]') {
|
const value: RegExpMatchArray | any = getKmlParams(param[0], true, {
|
name: key,
|
findRegx: '([\\s\\S]*?)',
|
})
|
Object.keys(setting[key]).forEach((v) => {
|
const keyValue: RegExpMatchArray | any = getKmlParams(value[1], true, {
|
name: v,
|
findRegx: '([\\s\\S]*?)',
|
})
|
if (!Number(keyValue[1])) {
|
setting[key][v] = keyValue[1]
|
} else {
|
setting[key][v] = Number(keyValue[1])
|
}
|
})
|
} else {
|
if (!Number(param[1])) {
|
setting[key] = param[1]
|
} else {
|
setting[key] = Number(param[1])
|
}
|
}
|
})
|
return setting
|
}
|
|
// 全局设置写入kmz文件
|
watch(
|
() => missionConfigSetting,
|
(settingVal) => {
|
if (!props.loadCompleted) return
|
kmzUtils.edit(settingVal, 'missionConfig', true)
|
},
|
{
|
deep: true,
|
},
|
)
|
|
// folder设置写入kmz文件
|
watch(
|
() => folderSetting,
|
(newVal) => {
|
if (!props.loadCompleted) return
|
kmzUtils.edit(newVal, 'Folder', true)
|
},
|
{
|
deep: true,
|
},
|
)
|
|
// 拍照设置
|
const selectPhotoSetting = (value: string) => {
|
const arr: string[] = folderSetting.payloadParam.imageFormat.split(',')
|
const index: number = arr.findIndex((item) => item === value)
|
if (index !== -1) {
|
arr.splice(index, 1)
|
} else {
|
arr.push(value)
|
}
|
folderSetting.payloadParam.imageFormat = arr.join(',')
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.setting {
|
.setting-content {
|
width: 390px;
|
max-height: 80vh;
|
overflow-y: auto;
|
color: #fff;
|
|
.common {
|
background-color: #232323;
|
border-radius: 10px;
|
padding: 15px;
|
margin-bottom: 16px;
|
|
.title {
|
font-weight: bold;
|
}
|
|
&:last-child {
|
margin: 0;
|
}
|
}
|
|
.start-point {
|
display: flex;
|
justify-content: flex-start;
|
.value {
|
margin-left: auto;
|
color: #409eff;
|
}
|
}
|
|
.photo-setting {
|
.select-box {
|
padding: 0;
|
display: flex;
|
margin-top: 10px;
|
|
li {
|
list-style-type: none;
|
padding: 3px 15px;
|
margin-left: 10px;
|
background-color: var(--settingColor);
|
border-radius: 9999px;
|
font-weight: bold;
|
cursor: pointer;
|
|
&:first-child {
|
margin: 0;
|
}
|
}
|
}
|
|
.auto-low-light {
|
display: flex;
|
|
.title {
|
font-weight: bold;
|
margin-right: auto;
|
}
|
}
|
}
|
|
.height-mode,
|
.climb-mode {
|
.mode-box {
|
margin-top: 10px;
|
|
:deep() {
|
.ant-radio-group {
|
display: flex;
|
|
.ant-radio-button-wrapper {
|
flex: 1;
|
text-align: center;
|
background-color: #3c3c3c;
|
border: 1px solid #101010;
|
color: #fff;
|
font-weight: bold;
|
border: 0;
|
|
&::before {
|
background-color: #101010;
|
}
|
|
&-checked {
|
background-color: #409eff !important;
|
}
|
}
|
}
|
}
|
}
|
|
.parameter-tool {
|
margin-top: 15px;
|
display: flex;
|
|
.example-img {
|
flex: 3;
|
flex-shrink: 0;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
|
img {
|
width: 100%;
|
}
|
}
|
|
.parameter-btn {
|
flex: 1;
|
padding: 0;
|
margin: 0;
|
flex-shrink: 0;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
|
li {
|
width: 50px;
|
border-radius: 3px;
|
padding: 2px 0;
|
list-style-type: none;
|
cursor: pointer;
|
background-color: #3c3c3c;
|
margin-bottom: 5px;
|
text-align: center;
|
font-weight: bold;
|
transition: all 0.3s ease-in-out;
|
|
&:nth-child(3) {
|
width: 100%;
|
background-color: transparent;
|
cursor: auto;
|
|
span {
|
color: #409eff;
|
font-size: 23px;
|
font-weight: bolder;
|
margin-right: 5px;
|
}
|
}
|
|
&:not(:nth-child(3)) {
|
&:hover {
|
background-color: #5d5f61;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
.speed-setting {
|
.speed-box {
|
margin-top: 10px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
.text {
|
font-weight: bolder;
|
|
.value {
|
color: #409eff;
|
width: 60px;
|
font-size: 30px;
|
background-color: transparent;
|
border: 0;
|
|
:deep() {
|
.ant-input-number-handler-wrap {
|
display: none;
|
}
|
|
.ant-input-number-input-wrap {
|
input {
|
font-weight: bolder;
|
}
|
}
|
}
|
}
|
}
|
|
.subtract,
|
.add {
|
width: 32px;
|
height: 32px;
|
text-align: center;
|
line-height: 32px;
|
font-size: 20px;
|
font-weight: bolder;
|
background-color: #3c3c3c;
|
border-radius: 3px;
|
cursor: pointer;
|
|
&:hover {
|
background-color: #5d5f61;
|
}
|
}
|
}
|
}
|
}
|
:deep() {
|
.ant-popover-content {
|
.ant-popover-arrow,
|
.ant-popover-inner {
|
background-color: #101010;
|
}
|
|
.ant-popover-arrow {
|
border-top-color: #101010 !important;
|
border-left-color: #101010 !important;
|
}
|
|
.ant-popover-inner {
|
border-radius: 15px;
|
|
.ant-popover-inner-content {
|
padding: 16px;
|
}
|
}
|
}
|
}
|
}
|
</style>
|