From 91f425a9e4c11016dccd78186a4ab0dec3c49870 Mon Sep 17 00:00:00 2001
From: GuLiMmo <2820890765@qq.com>
Date: Wed, 27 Mar 2024 17:50:29 +0800
Subject: [PATCH] update
---
src/utils/cesium/use-kmz-tsa.ts | 9 +
src/components/waylinetool/event-edit.vue | 110 +++------------
src/components/waylinetool/component/take-photo.vue | 235 +++++++++++++++++++++++++++++++++
src/utils/cesium/mapUtils.ts | 25 +++
4 files changed, 290 insertions(+), 89 deletions(-)
diff --git a/src/components/waylinetool/component/take-photo.vue b/src/components/waylinetool/component/take-photo.vue
new file mode 100644
index 0000000..25dbdf5
--- /dev/null
+++ b/src/components/waylinetool/component/take-photo.vue
@@ -0,0 +1,235 @@
+<!--
+ * @Author: GuLiMmo 2820890765@qq.com
+ * @Date: 2024-03-27 15:15:50
+ * @LastEditors: GuLiMmo 2820890765@qq.com
+ * @LastEditTime: 2024-03-27 17:31:10
+ * @FilePath: /drone-web/src/components/waylinetool/component/take-photo.vue
+ * @Description: 航点事件-单拍
+ * Copyright (c) 2024 by GuLiMmo, All Rights Reserved.
+-->
+
+<template>
+ <div class="container">
+ <div :class="['fileSuffix', isInputShow && 'no-select']">
+ <span>DJI_YYYYMMDDhhmm_XXX_</span>
+ <span class="icon" @click="isInputShow = !isInputShow"><EditOutlined /></span>
+ </div>
+ <div class="fileSuffix-input" v-if="isInputShow">
+ <a-input
+ v-model:value="fileSuffix"
+ placeholder="请输入文件后缀名称"
+ size="small"></a-input>
+ <a-button type="primary" shape="circle" size="small" @click="confirmInput">
+ <template #icon>
+ <CheckOutlined />
+ </template>
+ </a-button>
+ <a-button type="danger" shape="circle" size="small" @click="cencalInput">
+ <template #icon>
+ <CloseOutlined />
+ </template>
+ </a-button>
+ </div>
+ <ul class="btn-group">
+ <li
+ :class="[
+ 'btn',
+ isGlobalPhotoFormat && 'disabled-btn',
+ !defaultParams.payloadLensIndex?.['#text'].includes('wide') && 'no-btn-selected',
+ ]"
+ @click="!isGlobalPhotoFormat && addFormatEvent('wide')">
+ 广角照片
+ </li>
+ <li
+ :class="[
+ 'btn',
+ isGlobalPhotoFormat && 'disabled-btn',
+ !defaultParams.payloadLensIndex?.['#text'].includes('zoom') && 'no-btn-selected',
+ ]"
+ @click="!isGlobalPhotoFormat && addFormatEvent('zoom')">
+ 变焦照片
+ </li>
+ <li :class="['btn', !isGlobalPhotoFormat && 'no-btn-selected']" @click="addFormatEvent('global')">跟随全局</li>
+ </ul>
+ </div>
+</template>
+
+<script lang="ts" setup>
+import { defineProps, ref } from 'vue'
+import { template as xmlJson } from '/@/utils/cesium/use-kmz-tsa'
+import { EditOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons-vue'
+import { message } from 'ant-design-vue'
+
+interface serialProp {
+ placemark: number
+ action: number
+}
+
+interface text {
+ '#text': any
+}
+
+interface takePhoto {
+ fileSuffix?: text
+ payloadLensIndex: text
+ payloadPositionIndex: text
+ useGlobalPayloadLensIndex: text
+}
+
+const isInputShow = ref<boolean>(false)
+
+const fileSuffix = ref<string>('')
+
+const defaultParams = ref<takePhoto | any>({
+ fileSuffix: { '#text': null },
+ payloadLensIndex: { '#text': null },
+ payloadPositionIndex: { '#text': null },
+ useGlobalPayloadLensIndex: { '#text': null },
+})
+
+const confirmInput = () => {
+ defaultParams.value.fileSuffix['#text'] = fileSuffix.value
+ message.success('修改拍摄照片文件后缀成功!!')
+}
+
+const cencalInput = () => {
+ fileSuffix.value = defaultFileSuffix.value
+ message.success('恢复初始拍摄照片文件后缀成功!!')
+}
+
+const props = defineProps<{
+ serial: serialProp
+}>()
+
+const defaultFileSuffix = ref<string>('')
+const getDefaultParams = (serial: serialProp) => {
+ const placemarkJson = xmlJson.value.Folder.Placemark[serial.placemark]
+ let action = placemarkJson.actionGroup.action
+ if (Array.isArray(action)) {
+ action = action[serial.action]
+ }
+ const actionActuatorFuncParam = action.actionActuatorFuncParam
+ defaultParams.value = actionActuatorFuncParam
+ fileSuffix.value = actionActuatorFuncParam.fileSuffix['#text']
+ defaultFileSuffix.value = actionActuatorFuncParam.fileSuffix['#text']
+ isInputShow.value = !!defaultParams.value.fileSuffix
+}
+
+// 判断当前是否使用全局照片设置
+const isGlobalPhotoFormat = computed(() => Number(defaultParams.value.useGlobalPayloadLensIndex['#text']))
+
+// 照片格式
+const addFormatEvent = (value: string) => {
+ if (value === 'global') {
+ defaultParams.value.useGlobalPayloadLensIndex['#text'] = Number(!isGlobalPhotoFormat.value)
+ if (!isGlobalPhotoFormat.value) {
+ defaultParams.value.payloadLensIndex = { '#text': 'zoom,wide' }
+ } else {
+ delete defaultParams.value.payloadLensIndex
+ }
+ } else {
+ if (!defaultParams.value.payloadLensIndex) {
+ defaultParams.value.payloadLensIndex = { '#text': '' }
+ }
+ const payloadLensIndex = defaultParams.value.payloadLensIndex['#text']
+ const payloadLensIndexArr = payloadLensIndex.split(',')
+ if (!payloadLensIndex) {
+ defaultParams.value.payloadLensIndex['#text'] = value
+ } else {
+ const index = payloadLensIndexArr.findIndex((item: string) => item === value)
+ if (index === -1) {
+ payloadLensIndexArr.push(value)
+ } else {
+ payloadLensIndexArr.splice(index, 1)
+ }
+ defaultParams.value.payloadLensIndex['#text'] = payloadLensIndexArr.join(',')
+ }
+ }
+}
+
+// 最新值
+watch(
+ () => defaultParams.value,
+ (newParams) => {
+ console.log(newParams)
+ },
+ {
+ deep: true,
+ },
+)
+
+// 默认值
+watch(
+ () => props.serial,
+ (newVal: serialProp) => {
+ getDefaultParams(newVal)
+ },
+ {
+ deep: true,
+ immediate: true,
+ },
+)
+</script>
+
+<style lang="scss" scoped>
+.container {
+ width: 100%;
+ height: 100%;
+ .fileSuffix {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ .icon {
+ cursor: pointer;
+ &:hover {
+ color: #409eff;
+ }
+ }
+ }
+ .fileSuffix-input {
+ margin-top: 10px;
+ display: flex;
+ input {
+ background-color: transparent;
+ color: #fff;
+ }
+ .ant-btn {
+ margin-left: 10px;
+ }
+ }
+ .btn-group {
+ list-style-type: none;
+ margin: 15px 0 0 0;
+ padding: 0;
+ display: flex;
+ gap: 10px;
+ justify-content: flex-start;
+ .btn {
+ font-size: 13px;
+ padding: 2px 10px;
+ background-color: #409eff;
+ border-radius: 999px;
+ cursor: pointer;
+ font-weight: bold;
+ &:last-child {
+ margin-left: auto;
+ }
+ }
+ }
+}
+
+.no-select {
+ color: hsla(0, 0%, 100%, 0.45);
+}
+
+.no-btn-selected {
+ background-color: hsla(0, 0%, 100%, 0.45) !important;
+ border: hsla(0, 0%, 100%, 0.45) !important;
+}
+.disabled-btn {
+ cursor: not-allowed !important;
+ background-color: #314768 !important;
+ border: #314768 !important;
+ color: #ccc;
+}
+</style>
diff --git a/src/components/waylinetool/event-edit.vue b/src/components/waylinetool/event-edit.vue
index c708160..a9b1b8b 100644
--- a/src/components/waylinetool/event-edit.vue
+++ b/src/components/waylinetool/event-edit.vue
@@ -12,34 +12,7 @@
</div>
</div>
<div class="event-edit">
- <!-- 单拍 -->
- <template v-if="currentPointEvent.aciton.key === 'takePhoto'">
- <div class="take-photo">
- <div class="title">
- <span
- :style="{
- color: isTakePhotoNameShow || takePhotoSetting.fileSuffix ? 'rgba(255,255,255,0.4)' : '#fff',
- }"
- >DJI_YYYYMMDDhhmm_XXX_</span
- >
- <span @click="isTakePhotoNameShow = !isTakePhotoNameShow"><EditOutlined /></span>
- </div>
- <div class="title-name-input" v-if="isTakePhotoNameShow">
- <div class="input"><a-input size="small" v-model:value="takePhotoSetting.fileSuffix"></a-input></div>
- <div class="btn">
- <span class="check"><CheckOutlined /></span>
- <span class="close"><CloseOutlined /></span>
- </div>
- </div>
- <div class="photo-format">
- <a-button type="primary" shape="round" size="small" @click="photoFormatClick('wide')">广角照片</a-button>
- <a-button type="primary" shape="round" size="small" @click="photoFormatClick('zoom')">变焦照片</a-button>
- <a-button type="primary" shape="round" size="small" @click="photoFormatClick('global')"
- >跟随全局</a-button
- >
- </div>
- </div>
- </template>
+ <takePhoto v-model:serial="serial" v-if="currentPointEvent.aciton.key === 'takePhoto'" />
</div>
</div>
<div class="map-box"></div>
@@ -48,10 +21,10 @@
<script lang="ts" setup>
import _ from 'lodash'
-import { DeleteOutlined, EditOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons-vue'
+import { DeleteOutlined } from '@ant-design/icons-vue'
import { useMyStore } from '/@/store'
-import { actionList } from '/@/utils/cesium/use-map-draw'
import { template as xmlTemplate } from '/@/utils/cesium/use-kmz-tsa'
+import takePhoto from './component/take-photo.vue'
const store = useMyStore()
// 事件编辑是否显示
@@ -87,51 +60,7 @@
}
})
-// 单拍
-const isTakePhotoNameShow = ref<boolean>(false)
-const takePhotoSetting = reactive({
- fileSuffix: '',
- payloadLensIndex: '',
- useGlobalPayloadLensIndex: 0,
-})
-const photoFormatClick = (value: string) => {
- if (value === 'global') {
- takePhotoSetting.useGlobalPayloadLensIndex = 1
- } else {
- let formats = takePhotoSetting.payloadLensIndex.split(',')
- const index = formats.findIndex((item: string) => item === value)
- if (index === -1) {
- if (takePhotoSetting.payloadLensIndex === '') {
- formats = [value]
- } else {
- formats.push(value)
- }
- } else {
- formats.splice(index, 1)
- }
- takePhotoSetting.payloadLensIndex = formats.join(',')
- }
- addActionParam(takePhotoSetting)
-}
-
const handleDelAction = () => {}
-
-// 加入事件参数
-const addActionParam = <T extends { [key: string] : string }, >(params: T): void => {
- const obj = _.cloneDeep(params)
- const placemarks = xmlTemplate.value.Folder.Placemark
- let aciton = placemarks[serial.placemark].actionGroup?.action
- if (Array.isArray(aciton)) {
- aciton = aciton[serial.action]
- }
- console.log(aciton)
- const actionActuatorFuncParam = aciton.actionActuatorFuncParam
- // Object.keys(obj).forEach((key: string) => {
- // if (!obj[key]) {
- // delete obj[key]
- // }
- // })
-}
</script>
<style lang="scss" scoped>
@@ -184,7 +113,7 @@
height: calc(100% - 50px);
padding: 15px;
overflow: auto;
- // 单排
+ // 单拍
.take-photo {
.title {
display: flex;
@@ -230,19 +159,24 @@
}
}
}
- .photo-format {
- margin-top: 20px;
- display: flex;
- justify-content: flex-start;
- .ant-btn {
- margin-left: 10px;
- font-weight: bold;
- &:first-child {
- margin: 0;
- }
- &:nth-child(3) {
- margin-left: auto;
- }
+ }
+
+ .btn-group {
+ margin-top: 20px;
+ display: flex;
+ justify-content: flex-start;
+ button {
+ margin-left: 10px;
+ font-weight: bold;
+ background-color: #409eff;
+ border-radius: 999px;
+ border: 0;
+ padding: 0 10px 0 10px;
+ &:first-child {
+ margin: 0;
+ }
+ &:nth-child(3) {
+ margin-left: auto;
}
}
}
diff --git a/src/utils/cesium/mapUtils.ts b/src/utils/cesium/mapUtils.ts
index ef5b8f6..47d01a4 100644
--- a/src/utils/cesium/mapUtils.ts
+++ b/src/utils/cesium/mapUtils.ts
@@ -57,7 +57,10 @@
}
// 获取当前经纬度海拔
-export const getHaeHeight = (start: { longitude: number; latitude: number; height: number }, end: { longitude: number; latitude: number; height: number }) => {
+export const getHaeHeight = (
+ start: { longitude: number; latitude: number; height: number },
+ end: { longitude: number; latitude: number; height: number },
+) => {
const ellipsoid = Cesium.Ellipsoid.WGS84 // 选择合适的椭圆体模型
// const { longitude, latitude, height } = start
// const { longitude: endLng, latitude: endLat, height: endHeight } = end
@@ -74,3 +77,23 @@
const haeHeight = ellipsoid.cartesianToCartographic(cartesianPosition).height
return haeHeight
}
+
+// Cesium Cartesian3 转正常经纬度
+export const cartesian3Convert = (cartesian3Position: Cesium.Cartesian3, viewer: { scene: { globe: { ellipsoid: any } } }) => {
+ // 转换为经纬度
+ const ellipsoid = viewer.scene.globe.ellipsoid
+ const cartographicPosition = Cesium.Cartographic.fromCartesian(cartesian3Position, ellipsoid)
+ const longitude = Cesium.Math.toDegrees(cartographicPosition.longitude)
+ const latitude = Cesium.Math.toDegrees(cartographicPosition.latitude)
+ const height = cartographicPosition.height
+
+ console.log('经度: ' + longitude)
+ console.log('纬度: ' + latitude)
+ console.log('高度: ' + height)
+
+ return {
+ longitude,
+ latitude,
+ height,
+ }
+}
diff --git a/src/utils/cesium/use-kmz-tsa.ts b/src/utils/cesium/use-kmz-tsa.ts
index 01a09c6..8a2f993 100644
--- a/src/utils/cesium/use-kmz-tsa.ts
+++ b/src/utils/cesium/use-kmz-tsa.ts
@@ -82,6 +82,15 @@
},
},
],
+ payloadParam: {
+ payloadPositionIndex: { '#text': 0 },
+ focusMode: { '#text': 'firstPoint' },
+ meteringMode: { '#text': 'average' },
+ returnMode: { '#text': 'singleReturnFirst' },
+ samplingRate: { '#text': '240000' },
+ scanningMode: { '#text': 'repetitive' },
+ imageFormat: { '#text': 'wide,zoom' }
+ }
},
})
const waylines = ref<any>({
--
Gitblit v1.9.3