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