From 55fcb97a3d487f54353564f1e402e4d4b61feee9 Mon Sep 17 00:00:00 2001
From: GuLiMmo <2820890765@qq.com>
Date: Tue, 12 Mar 2024 17:54:05 +0800
Subject: [PATCH] update:kmz/json转换、kmz打包后无法解析等
---
src/pages/page-web/projects/components/route-edit/components/setting.vue | 483 +++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 447 insertions(+), 36 deletions(-)
diff --git a/src/pages/page-web/projects/components/route-edit/components/setting.vue b/src/pages/page-web/projects/components/route-edit/components/setting.vue
index 1548230..86560dc 100644
--- a/src/pages/page-web/projects/components/route-edit/components/setting.vue
+++ b/src/pages/page-web/projects/components/route-edit/components/setting.vue
@@ -1,33 +1,113 @@
<template>
<div class="setting">
- <a-popover
- placement="bottom"
- trigger="click"
- :getPopupContainer="(triggerNode: any) => triggerNode.parentNode">
+ <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">广角照片</li>
- <li class="select-item">变焦照片</li>
+ <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="auto-low-light">
<div class="title">自动低光</div>
- <a-switch />
- </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">
- <div class="title">航线高度模式</div>
- <div class="mode-box">
- <a-radio-group button-style="solid">
- <a-radio-button value="a">绝对高度</a-radio-button>
- <a-radio-button value="b">相对起飞高度</a-radio-button>
- <a-radio-button value="c">相对地面高度</a-radio-button>
- </a-radio-group>
+ <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>
@@ -38,65 +118,283 @@
</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 waylineSetting = reactive({})
+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 {
- margin-left: auto;
.setting-content {
width: 390px;
- height: 50vh;
+ 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: #409eff;
+ 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 {
+
+ .height-mode,
+ .climb-mode {
.mode-box {
margin-top: 10px;
+
:deep() {
.ant-radio-group {
display: flex;
+
.ant-radio-button-wrapper {
flex: 1;
text-align: center;
@@ -105,9 +403,11 @@
color: #fff;
font-weight: bold;
border: 0;
+
&::before {
background-color: #101010;
}
+
&-checked {
background-color: #409eff !important;
}
@@ -115,24 +415,135 @@
}
}
}
+
+ .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;
+ }
-: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;
+ .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;
+ }
}
}
}
--
Gitblit v1.9.3