GuLiMmo
2024-03-19 aec00ecc093be803860c8675cbe1c4c776a7cb4e
src/pages/page-web/projects/components/route-edit/components/setting.vue
@@ -1,33 +1,123 @@
<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">
              {{ xmlTemplate.missionConfig?.takeOffRefPoint['#text'] !== '' ? '已设置' : '未设置' }}
            </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"
                v-for="item in photoSetting"
                :key="item.value"
                :style="{
                  '--settingColor': xmlTemplate.Folder.payloadParam?.imageFormat['#text']
                    .split(',')
                    .includes(item.value)
                    ? '#409eff'
                    : '#3c3c3c',
                }"
                @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="xmlTemplate.missionConfig.flyToWaylineMode['#text']" 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 class="parameter-input">
                    <a-input-number
                      :min="2"
                      :max="1500"
                      v-model:value="xmlTemplate.missionConfig.takeOffSecurityHeight['#text']"></a-input-number
                    >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[xmlTemplate.Folder.waylineCoordinateSysParam.heightMode['#text']]">
              <div class="title">航线高度模式</div>
              <div class="mode-box">
                <a-radio-group
                  v-model:value="xmlTemplate.Folder.waylineCoordinateSysParam.heightMode['#text']"
                  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="true ? 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 class="parameter-input">
                    <a-input-number
                      :min="0"
                      :max="10000"
                      v-model:value="xmlTemplate.Folder.globalHeight['#text']"></a-input-number
                    >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
                  v-model:value="xmlTemplate.Folder.autoFlightSpeed['#text']"
                  :min="1"
                  :max="15"
                  class="value">
                </a-input-number>
                m / s
              </div>
              <div class="add" @click="numberControls(true, 1, 'autoFlightSpeed')">+</div>
            </div>
          </div>
        </div>
@@ -38,65 +128,179 @@
</template>
<script setup lang="ts">
const getResource = (name: string) => {
  return new URL(`/src/assets/icons/${name}`, import.meta.url).href
import { reactive, defineProps } from 'vue'
import { tipDescriptionEnums } from './enums'
import useKmzTsa, { kmlStr, template as xmlTemplate } from '/@/utils/cesium/use-kmz-tsa'
import useMapDraw, { kmlEntities as globalEntities } 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()
interface setting {
  imageFormat: string[]
}
const waylineSetting = reactive({})
const props = defineProps({
  loadCompleted: Boolean,
})
const getSvgResource = (name: string) => {
  return new URL(`/src/assets/svg/${name}`, import.meta.url).href
}
const climbImage = getSvgResource('climb.svg')
const imgs = []
// 拍照设置
interface photoSetting {
  title: string
  value: string
}
const photoSetting = reactive<photoSetting[]>([
  { 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'),
  },
])
// 计算
const numberControls = (isAdd: boolean, computeVal: number, key: string) => {
  let obj = { '#text': '0' }
  if (key === 'takeOffSecurityHeight') {
    obj = xmlTemplate.value.missionConfig.takeOffSecurityHeight
  }
  if (key === 'globalHeight') {
    obj = xmlTemplate.value.Folder.globalHeight
  }
  if (key === 'autoFlightSpeed') {
    obj = xmlTemplate.value.Folder.autoFlightSpeed
  }
  let value = Number(obj['#text'])
  if (isAdd) {
    value += computeVal
  } else {
    value -= computeVal
  }
  obj['#text'] = value.toString()
  if (key === 'globalHeight') {
    const placemarkArr = xmlTemplate.value.Folder.Placemark
    placemarkArr.forEach((placemark: { useGlobalHeight: { [x: string]: any }; height: { [x: string]: string } }) => {
      if (Reflect.has(placemark, 'useGlobalHeight')) {
        placemark.height['#text'] = value.toString()
      }
    })
    const xmlString = kmzUtils.generateXML(xmlTemplate.value)
    mapDraw.drawWayline(globalEntities.value, xmlString)
  }
}
// 拍照选择
const selectPhotoSetting = (value: string) => {
  const imageFormat = xmlTemplate.value.Folder.payloadParam.imageFormat
  const imageFormatArr = imageFormat['#text'].split(',')
  if (imageFormatArr.includes(value)) {
    const index = imageFormatArr.findIndex((item: string) => item === value)
    imageFormatArr.splice(index, 1)
  } else {
    imageFormatArr.push(value)
  }
  xmlTemplate.value.Folder.payloadParam.imageFormat['#text'] = imageFormatArr.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 +309,11 @@
              color: #fff;
              font-weight: bold;
              border: 0;
              &::before {
                background-color: #101010;
              }
              &-checked {
                background-color: #409eff !important;
              }
@@ -115,24 +321,161 @@
          }
        }
      }
      .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;
              }
            }
          }
          .parameter-input {
            display: flex;
            align-items: center;
            :deep() {
              .ant-input-number {
                background-color: transparent;
                color: #409eff;
                font-size: 23px;
                border: 0;
                .ant-input-number-handler-wrap {
                  display: none;
                }
                .ant-input-number-input-wrap {
                  input {
                    font-weight: bold;
                    text-align: center;
                  }
                }
              }
            }
          }
        }
      }
    }
    .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;
  :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;
        }
      }
    }
  }