From e72969f25dd1a243e48c783dedc0f198ee08c2b8 Mon Sep 17 00:00:00 2001
From: GuLiMmo <2820890765@qq.com>
Date: Wed, 20 Mar 2024 17:19:04 +0800
Subject: [PATCH] update:新增航线、航点事件编辑
---
src/components/GMap.vue | 2
src/utils/cesium/use-map-draw.ts | 44 +++++---
src/hooks/use-cesium-tsa.ts | 3
src/assets/icons/waylinetool/无人机起降场.png | 0
src/pages/page-web/projects/components/route-edit/index.vue | 52 +++++++++-
src/pages/page-web/projects/wayline.vue | 6
src/utils/cesium/use-kmz-tsa.ts | 69 +++++++------
src/pages/page-web/projects/components/route-edit/components/setting.vue | 51 +++++++--
src/pages/page-web/projects/components/route-edit/components/setting-point-tip.vue | 72 ++++++++++++++
src/assets/icons/waylinetool/startpoint.png | 0
src/assets/icons/waylinetool/cursor.png | 0
11 files changed, 228 insertions(+), 71 deletions(-)
diff --git a/src/assets/icons/waylinetool/cursor.png b/src/assets/icons/waylinetool/cursor.png
new file mode 100644
index 0000000..e4421c9
--- /dev/null
+++ b/src/assets/icons/waylinetool/cursor.png
Binary files differ
diff --git a/src/assets/icons/waylinetool/startpoint.png b/src/assets/icons/waylinetool/startpoint.png
new file mode 100644
index 0000000..1a8eaea
--- /dev/null
+++ b/src/assets/icons/waylinetool/startpoint.png
Binary files differ
diff --git "a/src/assets/icons/waylinetool/\346\227\240\344\272\272\346\234\272\350\265\267\351\231\215\345\234\272.png" "b/src/assets/icons/waylinetool/\346\227\240\344\272\272\346\234\272\350\265\267\351\231\215\345\234\272.png"
new file mode 100644
index 0000000..7cad529
--- /dev/null
+++ "b/src/assets/icons/waylinetool/\346\227\240\344\272\272\346\234\272\350\265\267\351\231\215\345\234\272.png"
Binary files differ
diff --git a/src/components/GMap.vue b/src/components/GMap.vue
index e60c697..8b0fbc7 100644
--- a/src/components/GMap.vue
+++ b/src/components/GMap.vue
@@ -848,7 +848,7 @@
:payloads="osdVisible.payloads">
</DroneControlPanel>
</div>
- <waylineTool />
+ <!-- <waylineTool /> -->
<routeProfile />
</div>
<div class="event-wrapper" v-if="false">
diff --git a/src/hooks/use-cesium-tsa.ts b/src/hooks/use-cesium-tsa.ts
index a25ff3b..b4fb7c7 100644
--- a/src/hooks/use-cesium-tsa.ts
+++ b/src/hooks/use-cesium-tsa.ts
@@ -196,6 +196,9 @@
if (pick && (pick.id._id === sid || pick.id._id.includes(sid))) {
cb(click, pick, viewer, handler)
}
+ if (sid === '') {
+ cb(click, pick, viewer, handler)
+ }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}
// 移除左键事件
diff --git a/src/pages/page-web/projects/components/route-edit/components/setting-point-tip.vue b/src/pages/page-web/projects/components/route-edit/components/setting-point-tip.vue
new file mode 100644
index 0000000..ca13c61
--- /dev/null
+++ b/src/pages/page-web/projects/components/route-edit/components/setting-point-tip.vue
@@ -0,0 +1,72 @@
+<template>
+ <Teleport to="body">
+ <div class="tip-container">点击地图设置参考起飞点</div>
+ </Teleport>
+</template>
+
+<script lang="ts" setup>
+import { onMounted, onUnmounted } from 'vue'
+import { cesiumOperation } from '/@/hooks/use-cesium-tsa'
+import * as Cesium from 'cesium'
+import useKmzTsa, { template as xmlTemplate } from '/@/utils/cesium/use-kmz-tsa'
+import useMapDraw, { kmlEntities as globalEntities } from '/@/utils/cesium/use-map-draw'
+const { appContext }: any = getCurrentInstance()
+const global = appContext.config.globalProperties
+const kmzUtils = useKmzTsa()
+const mapDraw = useMapDraw('', [], '', global)
+
+const { addClickEvent, removeClickEvent } = cesiumOperation()
+
+const getResource = (name: string) => {
+ return new URL(`/src/assets/icons/${name}`, import.meta.url).href
+}
+
+const createInitialPoint = () => {
+ const cesiumDom: any = document.querySelector('#cesiumContainer')
+ cesiumDom.style.cursor = `url(${getResource('waylinetool/cursor.png')}), auto`
+ addClickEvent('', addSettingEvent)
+}
+
+const addSettingEvent = (click: { position: Cesium.Cartesian2 }) => {
+ const { position } = click
+ const c3Position = global.$viewer.scene.globe.pick(global.$viewer.camera.getPickRay(position), global.$viewer.scene)
+ const ellipsoid = global.$viewer.scene.globe.ellipsoid
+ const c2Postion = ellipsoid.cartesianToCartographic(c3Position)
+ const longitude = Cesium.Math.toDegrees(c2Postion.longitude)
+ const latitude = Cesium.Math.toDegrees(c2Postion.latitude)
+ const height = 6
+ const takeOffPoint = [latitude, longitude, height]
+ xmlTemplate.value.missionConfig.takeOffRefPoint['#text'] = takeOffPoint.join(',')
+ const xmlStr = kmzUtils.generateXML(xmlTemplate.value)
+ mapDraw.drawWayline(globalEntities.value, xmlStr)
+}
+
+const delSettingEvent = () => {
+ const cesiumDom: any = document.querySelector('#cesiumContainer')
+ cesiumDom.style.cursor = 'auto'
+ removeClickEvent()
+}
+
+onMounted(() => {
+ createInitialPoint()
+})
+onUnmounted(() => {
+ delSettingEvent()
+})
+</script>
+
+<style lang="scss" scoped>
+.tip-container {
+ width: 60%;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background-color: rgba(0, 0, 0, 0.5);
+ padding: 20px;
+ color: #fff;
+ text-align: center;
+ font-weight: bold;
+ pointer-events: none;
+}
+</style>
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 82b043a..fca2f18 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
@@ -3,11 +3,15 @@
<a-popover placement="bottom" trigger="click" :getPopupContainer="(triggerNode: any) => triggerNode.parentNode">
<template #content>
<div class="setting-content">
- <div class="start-point common">
+ <div class="start-point common" v-if="xmlTemplate.missionConfig?.takeOffRefPoint['#text']">
<div class="title">起飞点</div>
<div class="value">
{{ xmlTemplate.missionConfig?.takeOffRefPoint['#text'] !== '' ? '已设置' : '未设置' }}
</div>
+ </div>
+ <div class="no-start-point" v-else>
+ <img :src="getResource('waylinetool/无人机起降场.png')" alt="icon">
+ <span>参考起飞点未设置</span>
</div>
<div class="photo-setting common">
<div class="title">拍照设置</div>
@@ -27,17 +31,6 @@
{{ 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">
@@ -155,6 +148,10 @@
return new URL(`/src/assets/svg/${name}`, import.meta.url).href
}
+const getResource = (name: string) => {
+ return new URL(`/src/assets/icons/${name}`, import.meta.url).href
+}
+
const climbImage = getSvgResource('climb.svg')
const imgs = []
@@ -216,6 +213,13 @@
// 拍照选择
const selectPhotoSetting = (value: string) => {
+ if (!xmlTemplate.value.Folder.payloadParam) {
+ xmlTemplate.value.Folder.payloadParam = {
+ imageFormat: {
+ '#text': '',
+ },
+ }
+ }
const imageFormat = xmlTemplate.value.Folder.payloadParam.imageFormat
const imageFormatArr = imageFormat['#text'].split(',')
if (imageFormatArr.includes(value)) {
@@ -259,6 +263,29 @@
margin-left: auto;
color: #409eff;
}
+
+ .no-setting {
+ &__value {
+ width: 100%;
+ text-align: center;
+ font-weight: bold;
+ }
+ }
+ }
+ .no-start-point {
+ border-radius: 10px;
+ padding: 15px;
+ margin-bottom: 16px;
+ background-color: #409eff;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: bold;
+ img {
+ width: 18px;
+ height: 18px;
+ margin-right: 5px;
+ }
}
.photo-setting {
diff --git a/src/pages/page-web/projects/components/route-edit/index.vue b/src/pages/page-web/projects/components/route-edit/index.vue
index b9955d6..8bd0d1f 100644
--- a/src/pages/page-web/projects/components/route-edit/index.vue
+++ b/src/pages/page-web/projects/components/route-edit/index.vue
@@ -62,15 +62,16 @@
<div v-for="(event, index) in item.eventList" :key="index" class="s-event-icon">
<a-tooltip placement="top">
<template #title>
- {{ event.name }}
+ {{ event?.name }}
</template>
- <img :src="event.icon" alt="icon" />
+ <img :src="event?.icon" alt="icon" />
</a-tooltip>
</div>
</div>
</contextMenu>
</li>
</ul>
+ <startPointTips v-if="xmlTemplate.missionConfig?.takeOffRefPoint['#text'] === ''" />
</div>
</template>
@@ -85,6 +86,7 @@
import { useMyStore } from '/@/store'
import useMapDraw, { kmlEntities as globalEntities, selectPointIndex as pointIdx } from '/@/utils/cesium/use-map-draw'
import contextMenu from './components/content-menu.vue'
+import startPointTips from './components/setting-point-tip.vue'
const store = useMyStore()
const { appContext }: any = getCurrentInstance()
const global = appContext.config.globalProperties
@@ -186,8 +188,33 @@
// 新建航线初始化
const initCreateRoute = () => {
mapDraw = useMapDraw('', [], '', global)
- const xml = kmzUtils.generateXML(xmlTemplate.value)
- mapDraw.drawWayline([], xml)
+ const {
+ drawWayline,
+ waylineDetails: details,
+ waylinePointsEvent,
+ kmlEntities: entities,
+ clearWaylineData
+ } = mapDraw
+ clearWaylineData()
+ drawWayline()
+ waylineDetails.value = details
+ tragetPointArr.value = waylinePointsEvent.value
+ watch(
+ () => waylinePointsEvent.value,
+ (val) => {
+ tragetPointArr.value = val
+ },
+ {
+ deep: true,
+ },
+ )
+ kmlEntities.value = entities.value
+ // const xml = kmzUtils.generateXML(xmlTemplate.value)
+ // mapDraw.drawWayline([], xml)
+ if (!mouseRightClickEvent) {
+ // 添加右键事件
+ addMapPointEvent()
+ }
}
// 创建广告牌
@@ -287,6 +314,7 @@
removeCesiumChildDom(popupDom)
const { position } = click
const { x, y } = position
+ const createTakeOffPointEvent = [{ class: 'start-point', title: '设置参考起飞点' }]
const pointEvents = [
{
class: 'add-prev-point',
@@ -298,7 +326,12 @@
},
]
const defaultEvents = [{ class: 'finally-point', title: '在最后航点新增航点' }]
- const events = selectPointIndex.value !== null ? [...defaultEvents, ...pointEvents] : defaultEvents
+ let events = []
+ if (xmlTemplate.value.missionConfig?.takeOffRefPoint['#text'] === '') {
+ events = createTakeOffPointEvent
+ } else {
+ events = selectPointIndex.value !== null ? [...defaultEvents, ...pointEvents] : defaultEvents
+ }
popupDom = createPointPopupDom(events)
global.$viewer.container.appendChild(popupDom)
popupDom.style.transform = `translate3d(${x}px, ${y}px, 0)`
@@ -398,6 +431,14 @@
},
isRisky: { '#text': 0 },
}
+ // 添加参考点
+ if (className === 'start-point') {
+ // 默认高度为6
+ const height = 6
+ const takeOffPoint = [latitude, longitude, height]
+ xmlTemplate.value.missionConfig.takeOffRefPoint['#text'] = takeOffPoint.join(',')
+ }
+ // 添加航点
if (className === 'finally-point') {
globalEntities.value.push(entity)
xmlTemplate.value.Folder.Placemark.push(setting)
@@ -498,7 +539,6 @@
onMounted(() => {
// 清空画布
clearCesiumMap()
- console.log(!!filePath.value)
if (filePath.value) {
initDrawRoute()
} else {
diff --git a/src/pages/page-web/projects/wayline.vue b/src/pages/page-web/projects/wayline.vue
index 42a9319..ae6d9a4 100644
--- a/src/pages/page-web/projects/wayline.vue
+++ b/src/pages/page-web/projects/wayline.vue
@@ -16,7 +16,7 @@
<SelectOutlined />
</a-button>
</a-upload>
- <a-button type="text" style="color: white" @click="addWaylineDialogShow = true">
+ <a-button type="text" v-if="!isPointListOpen" style="color: white" @click="addWaylineDialogShow = true">
<template #icon>
<PlusOutlined />
</template>
@@ -462,7 +462,9 @@
createWayline(values).then((createRes: any) => {
if (createRes) {
store.commit('SET_WAYLINE_KMZPATH', '')
- isPointListOpen.value = !isPointListOpen.value
+ isPointListOpen.value = true
+ closeAddWaylineDialog()
+ addWaylineDialogShow.value = false
} else {
message.error('创建航线失败,错误码:', createRes)
}
diff --git a/src/utils/cesium/use-kmz-tsa.ts b/src/utils/cesium/use-kmz-tsa.ts
index d7ff54c..01a09c6 100644
--- a/src/utils/cesium/use-kmz-tsa.ts
+++ b/src/utils/cesium/use-kmz-tsa.ts
@@ -160,51 +160,52 @@
81: '1',
} as const
const templateJson = {
- author,
- createTime,
- updateTime: createTime,
+ author: { '#text': author },
+ createTime: { '#text': createTime },
+ updateTime: { '#text': createTime },
missionConfig: {
- flyToWaylineMode: 'safely',
- finishAction: 'goHome',
- exitOnRCLost: 'goContinue',
- executeRCLostAction: 'goBack',
- takeOffSecurityHeight: 20,
- takeOffRefPoint: '0.000000,0.000000,0.000000',
- takeOffRefPointAGLHeight: 0,
- globalTransitionalSpeed: 15,
- globalRTHHeight: 80,
+ flyToWaylineMode: { '#text': 'safely' },
+ finishAction: { '#text': 'goHome' },
+ exitOnRCLost: { '#text': 'goContinue' },
+ executeRCLostAction: { '#text': 'goBack' },
+ takeOffSecurityHeight: { '#text': 20 },
+ takeOffRefPoint: { '#text': '' },
+ takeOffRefPointAGLHeight: { '#text': 0 },
+ globalTransitionalSpeed: { '#text': 15 },
+ globalRTHHeight: { '#text': 80 },
droneInfo: {
- droneEnumValue,
- droneSubEnumValue: droneModel[payloadEnumValue],
+ droneEnumValue: { '#text': droneEnumValue },
+ droneSubEnumValue: { '#text': droneModel[payloadEnumValue] },
},
payloadInfo: {
- payloadEnumValue,
- payloadSubEnumValue: droneModel[payloadEnumValue],
- payloadPositionIndex: 0,
+ payloadEnumValue: { '#text': payloadEnumValue },
+ payloadSubEnumValue: { '#text': droneModel[payloadEnumValue] },
+ payloadPositionIndex: { '#text': 0 },
},
},
Folder: {
- templateType: 'waypoint',
- useGlobalTransitionalSpeed: 0,
- templateId: 0,
+ templateType: { '#text': 'waypoint' },
+ useGlobalTransitionalSpeed: { '#text': 0 },
+ templateId: { '#text': 0 },
waylineCoordinateSysParam: {
- coordinateMode: 'WGS84',
- heightMode: 'EGM96',
- globalShootHeight: 50,
- positioningType: 'GPS',
- surfaceFollowModeEnable: 1,
- surfaceRelativeHeight: 100,
+ coordinateMode: { '#text': 'WGS84' },
+ heightMode: { '#text': 'EGM96' },
+ globalShootHeight: { '#text': 50 },
+ positioningType: { '#text': 'GPS' },
+ surfaceFollowModeEnable: { '#text': 1 },
+ surfaceRelativeHeight: { '#text': 100 },
},
- autoFlightSpeed: 7,
- gimbalPitchMode: 'usePointSetting',
+ autoFlightSpeed: { '#text': 7 },
+ gimbalPitchMode: { '#text': 'usePointSetting' },
+ globalHeight: { '#text': '100' },
globalWaypointHeadingParam: {
- waypointHeadingMode: 'followWayline',
- waypointHeadingAngle: 0,
- waypointPoiPoint: '0.000000,0.000000,0.000000',
- waypointHeadingPathMode: 'followBadArc',
+ waypointHeadingMode: { '#text': 'followWayline' },
+ waypointHeadingAngle: { '#text': 0 },
+ waypointPoiPoint: { '#text': '0.000000,0.000000,0.000000' },
+ waypointHeadingPathMode: { '#text': 'followBadArc' },
},
- globalWaypointTurnMode: 'toPointAndStopWithDiscontinuityCurvature',
- globalUseStraightLine: 0,
+ globalWaypointTurnMode: { '#text': 'toPointAndStopWithDiscontinuityCurvature' },
+ globalUseStraightLine: { '#text': 0 },
Placemark: [],
},
}
diff --git a/src/utils/cesium/use-map-draw.ts b/src/utils/cesium/use-map-draw.ts
index e5a8005..3f411f2 100644
--- a/src/utils/cesium/use-map-draw.ts
+++ b/src/utils/cesium/use-map-draw.ts
@@ -5,6 +5,7 @@
import { ref } from 'vue'
import { cesiumOperation } from '/@/hooks/use-cesium-tsa'
import { XMLToJSON } from './kmz'
+import _ from 'lodash'
const { addPolyline, getEntityById, removeAllDataSource, removeAllPoint } = cesiumOperation()
const getResource = (name: string) => {
@@ -125,7 +126,10 @@
// 绘制路线
const drawWayline = async (entities?: Cesium.Entity[], kmlStr?: string) => {
- if (!entities && !kmlStr) {
+ // if (!entities && !kmlStr) {
+ // dataSource.show = false
+ // }
+ if (dataSource) {
dataSource.show = false
}
let kmlEntityArr = entities || [...entitiesList]
@@ -145,7 +149,9 @@
}
const kmlJson = XMLToJSON(kmlRes)
// 所有航点
- const kmlPoints = kmlJson.Document.Folder.Placemark
+ const kmlPoints = Array.isArray(kmlJson.Document.Folder.Placemark)
+ ? kmlJson.Document.Folder.Placemark
+ : [kmlJson.Document.Folder.Placemark]
// 起飞点
let btmStartPoint = null
// 获取文件中的起飞点
@@ -303,23 +309,26 @@
kmlRes = await fileRes.fileInfoObj['wpmz/template.kml']
}
const kmlJson = XMLToJSON(kmlRes).Document
- const points = kmlJson.Folder?.Placemark
+ const points = Array.isArray(kmlJson.Folder?.Placemark) ? kmlJson.Folder.Placemark : [kmlJson.Folder.Placemark]
let takePhotoNum = 0
points?.forEach((point: { actionGroup: any }, index: number) => {
- if (Reflect.has(point, 'actionGroup')) {
- const action = point.actionGroup.action
- if (Array.isArray(action)) {
- action.forEach((item) => {
- const { actionActuatorFunc } = item
- actionActuatorFunc?.['#text'] === 'takePhoto' && takePhotoNum++
- const actionObj: eventParmas | any = actionList.find((event) => actionActuatorFunc['#text'] === event.key)
+ if (point !== undefined) {
+ if (Reflect.has(point, 'actionGroup')) {
+ const action = point.actionGroup.action
+ if (Array.isArray(action)) {
+ action.forEach((item) => {
+ const { actionActuatorFunc } = item
+ actionActuatorFunc?.['#text'] === 'takePhoto' && takePhotoNum++
+ const actionObj: eventParmas | any = actionList.find((event) => actionActuatorFunc['#text'] === event.key)
+ waylinePointsEvent.value[index].eventList?.push(actionObj)
+ })
+ } else {
+ action?.actionActuatorFunc['#text'] === 'takePhoto' && takePhotoNum++
+ const actionObj: eventParmas | any = actionList.find(
+ (item) => action?.actionActuatorFunc['#text'] === item.key,
+ )
waylinePointsEvent.value[index].eventList?.push(actionObj)
- })
- } else {
- const { actionActuatorFunc } = action
- actionActuatorFunc['#text'] === 'takePhoto' && takePhotoNum++
- const actionObj: eventParmas | any = actionList.find((item) => actionActuatorFunc['#text'] === item.key)
- waylinePointsEvent.value[index].eventList?.push(actionObj)
+ }
}
}
})
@@ -328,6 +337,9 @@
const clearWaylineData = () => {
kmlEntities.value = []
waylinePointsEvent.value = []
+ _.transform(waylineDetails, (_result, value) => {
+ value.value = 0
+ })
}
return {
--
Gitblit v1.9.3