From 016de324c0145632532fcd5450b96a2d1291dac6 Mon Sep 17 00:00:00 2001
From: GuLiMmo <2820890765@qq.com>
Date: Fri, 08 Mar 2024 17:41:24 +0800
Subject: [PATCH] update: 右键添加航点完成、kmz文件编辑等
---
src/components/GMap.vue | 5
src/utils/cesium/use-map-draw.ts | 42 ++++
src/pages/page-web/projects/components/route-edit/index.vue | 140 +++++++++++++++--
src/pages/page-web/projects/wayline.vue | 4
src/utils/cesium/use-kmz-tsa.ts | 96 ++++++++++-
src/utils/cesium/kmz.ts | 1
src/pages/page-web/projects/components/route-edit/components/setting.vue | 32 +--
src/components/waylinetool/route-profile.vue | 115 ++++++++++++++
8 files changed, 378 insertions(+), 57 deletions(-)
diff --git a/src/components/GMap.vue b/src/components/GMap.vue
index c10d0d9..a494cbd 100644
--- a/src/components/GMap.vue
+++ b/src/components/GMap.vue
@@ -736,6 +736,7 @@
</DroneControlPanel>
</div>
<waylineTool />
+ <routeProfile />
</div>
</template>
@@ -784,6 +785,7 @@
import { convertTimestampToDate } from '/@/utils/time'
import { cesiumOperation } from '/@/hooks/use-cesium-tsa'
import waylineTool from './waylinetool/index.vue'
+import routeProfile from './waylinetool/route-profile.vue'
export default defineComponent({
components: {
BorderOutlined,
@@ -809,7 +811,8 @@
CarryOutOutlined,
RocketOutlined,
DesktopOutlined,
- waylineTool
+ waylineTool,
+ routeProfile
},
name: 'GMap',
props: {},
diff --git a/src/components/waylinetool/route-profile.vue b/src/components/waylinetool/route-profile.vue
new file mode 100644
index 0000000..063470a
--- /dev/null
+++ b/src/components/waylinetool/route-profile.vue
@@ -0,0 +1,115 @@
+<template>
+ <div class="profile-container" v-if="isShow">
+ <div class="wayline-author">
+ <div class="wayline-author__file-name" >{{ author.fileName }}</div>
+ <div class="wayline-author__name"><UserOutlined /> {{ author.author }}</div>
+ </div>
+ <ul class="wayline-details">
+ <li class="wayline-details__info" v-for="(info, index) in details" :key="index">
+ <div class="title">{{ info.title }}</div>
+ <div class="value">{{ info.value }}</div>
+ </li>
+ </ul>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { ERouterName } from '/@/types/index'
+import { UserOutlined } from '@ant-design/icons-vue'
+import { waylineDetails } from '/@/utils/cesium/use-map-draw'
+import { fileAuthor, kmlStr } from '/@/utils/cesium/use-kmz-tsa'
+
+const author = reactive({
+ fileName: '',
+ author: '',
+})
+const details = ref<any>([])
+const route = useRoute()
+
+const isShow = computed(() => !kmlStr.value && isWaylineRoute && author.fileName && author.author && details.value.length > 0)
+
+watch(
+ () => fileAuthor,
+ (val) => {
+ author.fileName = val.name
+ author.author = val.author
+ },
+ {
+ deep: true,
+ },
+)
+
+watch(
+ () => waylineDetails,
+ (val) => {
+ details.value = val
+ },
+ {
+ deep: true,
+ },
+)
+
+const isWaylineRoute = ref<boolean>(false)
+watch(
+ () => route,
+ (val) => {
+ console.log(val)
+ if (val.name === ERouterName.WAYLINE) {
+ isWaylineRoute.value = true
+ } else {
+ isWaylineRoute.value = false
+ }
+ }, {
+ deep: true,
+ immediate: true
+ }
+)
+</script>
+
+<style lang="scss" scoped>
+.profile-container {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ pointer-events: none;
+ .wayline-author {
+ color: #fff;
+ font-weight: bold;
+ padding: 10px;
+ background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 100%);
+ &__file-name {
+ font-size: 17px;
+ }
+ }
+ .wayline-details {
+ width: 100%;
+ height: 70px;
+ padding: 0;
+ margin: 0;
+ background: linear-gradient(to top, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 100%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ &__info {
+ width: fit-content;
+ list-style-type: none;
+ margin-left: 10px;
+ font-weight: bold;
+ .title {
+ color: rgba(255, 255, 255, 0.65);
+ text-align: center;
+ }
+ .value {
+ color: #fff;
+ text-align: center;
+ font-size: 17px;
+ }
+ }
+ }
+}
+</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 c898a23..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
@@ -526,28 +526,26 @@
}
}
}
-}
+ :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-arrow {
- border-top-color: #101010 !important;
- border-left-color: #101010 !important;
- }
+ .ant-popover-inner {
+ border-radius: 15px;
- .ant-popover-inner {
- border-radius: 15px;
-
- .ant-popover-inner-content {
- padding: 16px;
+ .ant-popover-inner-content {
+ padding: 16px;
+ }
}
}
}
}
</style>
-../../../../../../utils/cesium/types/kml
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 ea4e04e..e3a05a0 100644
--- a/src/pages/page-web/projects/components/route-edit/index.vue
+++ b/src/pages/page-web/projects/components/route-edit/index.vue
@@ -1,12 +1,26 @@
<template>
<div class="route-edit-box">
<div class="btn-group">
- <a-button type="text" @click="backPage">
- <template #icon>
- <ArrowLeftOutlined />
+ <a-popover
+ :visible="modfiyPopupShow"
+ overlayClassName="popup-container"
+ placement="leftBottom"
+ :getPopupContainer="(triggerNode: any) => triggerNode.parentNode">
+ <template #content>
+ <div class="popup-text">返回将退出航线编辑器,您要保存吗?如果不保存,您更改的内容将会丢失。</div>
+ <div class="btn-tool">
+ <a-button size="small" class="btn-cancel" @click="modfiyPopupShow = false">取消</a-button>
+ <a-button size="small" class="btn-cancel" @click="handleModfiySave(false)">不保存</a-button>
+ <a-button size="small" type="primary" @click="handleModfiySave(true)">保存</a-button>
+ </div>
</template>
- 返回
- </a-button>
+ <a-button type="text" @click="backPage">
+ <template #icon>
+ <ArrowLeftOutlined />
+ </template>
+ 返回
+ </a-button>
+ </a-popover>
<div class="save-button" @click="saveWaylineFile">
<SaveOutlined />
</div>
@@ -34,10 +48,15 @@
:key="index"
:class="{ 'active-point': index == selectPointIndex }"
@click="pointSelect(item, index)">
- <div class="graph">
- <div class="left"></div>
- <div class="right">{{ index + 1 }}</div>
- </div>
+ <a-tooltip placement="top">
+ <template #title>
+ <span>{{ item.isUseGlobalHeight ? '跟随全局' : '不跟随全局' }}</span>
+ </template>
+ <div class="graph">
+ <div class="left" :style="{ borderTopColor: item.isUseGlobalHeight ? '#61d396' : '#409eff' }"></div>
+ <div class="right">{{ index + 1 }}</div>
+ </div>
+ </a-tooltip>
<div class="graph-right">
<div v-for="(event, index) in item.eventList" :key="index" class="s-event-icon">
<a-tooltip placement="top">
@@ -88,6 +107,7 @@
interface tragetPoint {
position: Cesium.Cartesian3
+ isUseGlobalHeight: boolean
eventList: eventParmas[]
}
@@ -246,7 +266,7 @@
},
{
class: 'add-next-point',
- title: `在${Number(selectPointIndex.value) + 1}号航点前插入`,
+ title: `在${Number(selectPointIndex.value) + 1}号航点后插入`,
},
]
const defaultEvents = [{ class: 'finally-point', title: '在最后航点新增航点' }]
@@ -320,6 +340,11 @@
const entity: Cesium.Entity = global.$viewer.entities.add({
position: createPointPosition,
})
+ const posterHeightRegStr = getKmlParams(kmlStr.value, true, {
+ name: 'takeOffRefPointAGLHeight',
+ findRegx: '([\\s\\S]*?)',
+ }) || ['', 0]
+ const posterHeight = Number(posterHeightRegStr[1])
// 加入kml文件中
const setting = {
Point: {
@@ -327,27 +352,36 @@
},
index: tragetPointArr.value.length,
height,
- ellipsoidHeight: height,
+ ellipsoidHeight: height - posterHeight,
}
+ removeAllDataSource()
+ removeAllPoint()
if (className === 'finally-point') {
- removeAllDataSource()
- removeAllPoint()
- kmzUtils.writePoint(setting)
+ kmzUtils.writePoint(setting, 'add')
globalEntities.value.push(entity)
- mapDraw.drawWayline(globalEntities.value, kmlStr.value)
tragetPointArr.value.push({
position: createPointPosition,
eventList: [],
})
}
if (className === 'add-prev-point') {
- // console.log(1)
+ kmzUtils.writePoint(setting, 'prev', selectPointIndex.value)
+ globalEntities.value.splice(selectPointIndex.value, 0, entity)
+ tragetPointArr.value.splice(selectPointIndex.value, 0, {
+ position: createPointPosition,
+ eventList: [],
+ })
}
if (className === 'add-next-point') {
- // const index = selectPointIndex.value
- // globalEntities.value.splice(index, 0, entity)
- // console.log()
+ kmzUtils.writePoint(setting, 'next', selectPointIndex.value)
+ const index = _.cloneDeep(selectPointIndex.value + 1)
+ globalEntities.value.splice(index, 0, entity)
+ tragetPointArr.value.splice(index, 0, {
+ position: createPointPosition,
+ eventList: [],
+ })
}
+ mapDraw.drawWayline(globalEntities.value, kmlStr.value)
// clearCesiumMap()
// createMapMarker(undefined, [...kmlEntities.value, entity])
})
@@ -361,8 +395,25 @@
}
}
+const modfiyPopupShow = ref<boolean>(false)
const backPage = () => {
- emits('backFn')
+ if (isModify.value) {
+ modfiyPopupShow.value = true
+ } else {
+ mapDraw.clearWaylineData()
+ kmlStr.value = ''
+ emits('backFn')
+ }
+}
+const handleModfiySave = (isSave: boolean) => {
+ if (isSave) {
+ saveWaylineFile()
+ modfiyPopupShow.value = false
+ } else {
+ mapDraw.clearWaylineData()
+ kmlStr.value = ''
+ emits('backFn')
+ }
}
// 清空画布
const clearCesiumMap = () => {
@@ -379,7 +430,22 @@
// 保存文件
const saveWaylineFile = () => {
kmzUtils.save()
+ mapDraw.clearWaylineData()
+ kmlStr.value = ''
+ emits('backFn')
}
+
+// 判断当前文件是否被修改
+const isModify = ref<boolean>(false)
+watch(
+ () => kmlStr.value,
+ (val) => {
+ isModify.value = true
+ },
+ {
+ deep: true,
+ },
+)
onMounted(() => {
// 清空画布
@@ -410,17 +476,48 @@
align-items: center;
justify-content: flex-start;
+ :deep() {
+ .popup-container {
+ .ant-popover-content {
+ .ant-popover-arrow,
+ .ant-popover-inner {
+ border-color: #282828;
+ background-color: #282828;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
+ .popup-text {
+ color: #fff;
+ width: 400px;
+ }
+ .btn-tool {
+ margin-top: 10px;
+ display: flex;
+ justify-content: flex-end;
+ .ant-btn {
+ border: 0;
+ }
+ .btn-cancel {
+ background-color: #3c3c3c;
+ margin-right: 5px;
+ }
+ }
+ }
+ }
+ }
+ }
.ant-btn {
color: #fff;
}
+
.save-button {
font-size: 20px;
margin: 0 10px 0 auto;
cursor: pointer;
+
&:hover {
color: #409eff;
}
}
+
.setting-btn {
background-color: #3c3c3c;
margin-right: 10px;
@@ -472,6 +569,7 @@
padding: 0;
height: calc(100vh - 180px);
overflow: auto;
+
li {
cursor: pointer;
padding: 10px 0;
@@ -522,8 +620,10 @@
}
}
}
+
.active-point {
background-color: #3c3c3c;
+
.graph {
.left {
border-top-color: #f3bf4e !important;
diff --git a/src/pages/page-web/projects/wayline.vue b/src/pages/page-web/projects/wayline.vue
index d79c70d..983dc21 100644
--- a/src/pages/page-web/projects/wayline.vue
+++ b/src/pages/page-web/projects/wayline.vue
@@ -230,6 +230,7 @@
importKmzFile,
getWayLineFile,
} from '/@/api/wayline'
+import EventBus from '/@/event-bus/'
import { ELocalStorageKey, ERouterName } from '/@/types'
import { EDeviceType } from '/@/types/device'
import { useMyStore } from '/@/store'
@@ -242,6 +243,7 @@
import * as Cesium from 'cesium'
import { cesiumOperation } from '/@/hooks/use-cesium-tsa'
import useMapDraw from '/@/utils/cesium/use-map-draw'
+import { fileAuthor } from '/@/utils/cesium/use-kmz-tsa'
import axios from 'axios'
import JSZIP from 'jszip'
// 初始化jszip
@@ -394,6 +396,8 @@
function selectRoute (wayline: WaylineFile) {
loading.value = true
+ fileAuthor.name = wayline.name
+ fileAuthor.author = wayline.user_name
getWayLineFile(workspaceId.value, wayline.id)
.then((res) => {
store.commit('SET_SELECT_WAYLINE_INFO', wayline)
diff --git a/src/utils/cesium/kmz.ts b/src/utils/cesium/kmz.ts
index fd1c3a8..de95d36 100644
--- a/src/utils/cesium/kmz.ts
+++ b/src/utils/cesium/kmz.ts
@@ -1,5 +1,4 @@
import axios from 'axios'
-import { mode } from 'crypto-js'
import JsZip from 'jszip'
const noWmpl: string[] = ['Folder', 'Placemark', 'Point', 'coordinates']
diff --git a/src/utils/cesium/use-kmz-tsa.ts b/src/utils/cesium/use-kmz-tsa.ts
index 2f49acf..3017b97 100644
--- a/src/utils/cesium/use-kmz-tsa.ts
+++ b/src/utils/cesium/use-kmz-tsa.ts
@@ -1,11 +1,15 @@
import { ref, getCurrentInstance } from 'vue'
import { analyzeKmzFile, getKmlParams, generateKmlFormat } from '/@/utils/cesium/kmz'
-import { getLngLatAltitude } from './mapUtils'
import JSZIP from 'jszip'
import { saveAs } from 'file-saver'
+import { point } from '@turf/turf'
const JsZip = new JSZIP()
+const fileAuthor = reactive({
+ name: '',
+ author: '',
+})
const kmlStr = ref('')
const kmzFile = ref<any>(null)
@@ -71,7 +75,7 @@
// const write = (settingParmas: any = {}, name: string) => {
// }
- const writePoint = (settingParmas: any = {}) => {
+ const writePoint = (settingParmas: any = {}, place: string, pointNumber: number = 0) => {
Object.keys(settingParmas).forEach((key: string) => {
placemark[key] = settingParmas[key]
})
@@ -81,11 +85,46 @@
findRegx: '([\\s\\S]*?)',
mode: 'g',
}) || ['']
- const lastPoint = points[points.length - 1]
- const index = kmlStr.value.indexOf(lastPoint)
- const beforeStr = kmlStr.value.slice(0, index)
- const afterStr = kmlStr.value.slice(index + lastPoint.length)
- kmlStr.value = beforeStr + lastPoint + Placemark + afterStr
+ if (place === 'add') {
+ const lastPoint = points[points.length - 1]
+ const index = kmlStr.value.indexOf(lastPoint)
+ const beforeStr = kmlStr.value.slice(0, index)
+ const afterStr = kmlStr.value.slice(index + lastPoint.length)
+ kmlStr.value = beforeStr + lastPoint + Placemark + afterStr
+ }
+ if (place === 'prev') {
+ const currentPoint: string = points[pointNumber]
+ const index = kmlStr.value.indexOf(currentPoint)
+ const beforeStr = kmlStr.value.slice(0, index)
+ const afterStr = kmlStr.value.slice(index + currentPoint.length)
+ kmlStr.value = beforeStr + Placemark + currentPoint + afterStr
+ // 更新点位序号
+ const pointIndexList = getKmlParams(kmlStr.value, true, {
+ name: 'index',
+ findRegx: '([\\s\\S]*?)',
+ mode: 'g',
+ })
+ pointIndexList?.forEach((pintIndex: string, index: number) => {
+ kmlStr.value.replace(pintIndex, `<wpml:index>${index}</wpml:index>`)
+ })
+ }
+ if (place === 'next') {
+ const currentPoint: string = points[pointNumber + 1]
+ const index = kmlStr.value.indexOf(currentPoint)
+ const beforeStr = kmlStr.value.slice(0, index)
+ const currentPointLength = currentPoint?.length || 0
+ const afterStr = kmlStr.value.slice(index + currentPointLength)
+ kmlStr.value = beforeStr + Placemark + currentPoint + afterStr
+ // 更新点位序号
+ const pointIndexList = getKmlParams(kmlStr.value, true, {
+ name: 'index',
+ findRegx: '([\\s\\S]*?)',
+ mode: 'g',
+ })
+ pointIndexList?.forEach((pintIndex: string, index: number) => {
+ kmlStr.value.replace(pintIndex, `<wpml:index>${index}</wpml:index>`)
+ })
+ }
}
const del = () => {}
@@ -104,9 +143,44 @@
findRegx: '([\\s\\S]*?)',
mode: 'g',
})
- regxVal.forEach((heightStr: string) => {
- const rstr = generateKmlFormat({ height: settingParmas[key] })
- kmlStr.value = kmlStr.value.replace(heightStr, rstr)
+ const ellipsoidHeightRegx = getKmlParams(kmlStr.value, true, {
+ name: 'ellipsoidHeight',
+ findRegx: '([\\s\\S]*?)',
+ mode: 'g',
+ }) || ['']
+ // 文件中的海拔高度
+ const takeOffRefPointAGLHeightRegxStr = getKmlParams(kmlStr.value, true, {
+ name: 'takeOffRefPointAGLHeight',
+ findRegx: '([\\s\\S]*?)'
+ }) || ['', '0']
+ const posterHeight = Number(takeOffRefPointAGLHeightRegxStr[1])
+ // 获取每个点是否使用全局高度
+ const useGlobalHeightRegStr = getKmlParams(kmlStr.value, true, {
+ name: 'useGlobalHeight',
+ findRegx: '([\\s\\S]*?)',
+ mode: 'g',
+ }) || ['', '0']
+ regxVal.forEach((heightStr: string, index: number) => {
+ // 使用正则取值
+ const getUseGlobalHeightValStr = getKmlParams(useGlobalHeightRegStr[index], true, {
+ name: 'useGlobalHeight',
+ findRegx: '([\\s\\S]*?)',
+ }) || ['', '0']
+ const isGlobalHeight = Boolean(Number(getUseGlobalHeightValStr[1]))
+ if (isGlobalHeight) {
+ // 替换height
+ const rstr = generateKmlFormat({ height: settingParmas[key] })
+ const rEllipsoidHeightStr = generateKmlFormat({ ellipsoidHeight: settingParmas[key] - posterHeight })
+ kmlStr.value = kmlStr.value.replace(heightStr, rstr)
+ kmlStr.value = kmlStr.value.replace(ellipsoidHeightRegx[index], rEllipsoidHeightStr)
+ // 替换
+ } else {
+ const heightRegxVal: any = getKmlParams(heightStr, true, {
+ name: 'height',
+ findRegx: '([\\s\\S]*?)',
+ })
+ console.log(heightRegxVal)
+ }
})
}
const replaceStr = generateKmlFormat({ [key]: settingParmas[key] })
@@ -136,5 +210,5 @@
}
}
-export { kmlStr }
+export { kmlStr, fileAuthor }
export default useKmzTsa
diff --git a/src/utils/cesium/use-map-draw.ts b/src/utils/cesium/use-map-draw.ts
index c088045..96fb23c 100644
--- a/src/utils/cesium/use-map-draw.ts
+++ b/src/utils/cesium/use-map-draw.ts
@@ -22,6 +22,7 @@
}
interface tragetPoint {
position: Cesium.Cartesian3
+ isUseGlobalHeight: boolean,
eventList: eventParmas[]
}
@@ -122,9 +123,10 @@
// 记录点位信息
let cartesianArr: Cesium.Cartesian3[] = []
- // 绘制路线
+ // 绘制路线
+ // 起飞点
+ // let btmStartPoint: Cesium.Cartesian3 | null = null
const drawWayline = async (entities?: Cesium.Entity[], kmlStr?: string) => {
- console.log(kmlStr)
if (!entities && !kmlStr) {
dataSource.show = false
}
@@ -149,6 +151,23 @@
})
// 起飞点
let btmStartPoint = null
+ // 获取文件中的起飞点
+ const startPointRegStr = getKmlParams(kmlRes, true, {
+ name: 'takeOffRefPoint',
+ findRegx: '([\\s\\S]*?)',
+ }) || ['', '0.00000,0.00000,0.00000']
+ const startPointPosition = startPointRegStr[1].split(',')
+ btmStartPoint = Cesium.Cartesian3.fromDegrees(
+ Number(startPointPosition[1]),
+ Number(startPointPosition[0]),
+ Number(startPointPosition[2])
+ )
+ // 参考起飞点“海拔高度,与“参考起飞点”中的椭球高度对应
+ // const posterHeightRegStr = getKmlParams(kmlRes, true, {
+ // name: 'takeOffRefPointAGLHeight',
+ // findRegx: '([\\s\\S]*?)',
+ // }) || ['', 0]
+ // const posterHeight = Number(posterHeightRegStr[1])
// 判断是否存在实体集
if (entities) {
cartesianArr = []
@@ -172,15 +191,23 @@
name: 'height',
findRegx: '([\\s\\S]*?)',
})
+ // 获取是否使用全局高度
+ const useGlobalHeightRegStr = getKmlParams(point, true, {
+ name: 'useGlobalHeight',
+ findRegx: '([\\s\\S]*?)',
+ }) || ['', '0']
+ const isUseGlobalHeight = Boolean(Number(useGlobalHeightRegStr[1]))
const AslHeight = Number(getPointHeight[1])
const HeaHeight = Number(getHaeHeight[1])
entity.position = Cesium.Cartesian3.fromDegrees(longitude, latitude, AslHeight)
- if (i === 0) {
- btmStartPoint = Cesium.Cartesian3.fromDegrees(longitude, latitude, 0)
- }
// 创建广告牌信息
- const title = Number(i + 1) === 1 ? 'S' : i
- const billboard = createTriangleMarker(title, '#61d396')
+ const title = Number(i + 1) === 1 ? 'S' : i + 1
+ let billboard = null
+ if (isUseGlobalHeight) {
+ billboard = createTriangleMarker(title, '#61d396')
+ } else {
+ billboard = createTriangleMarker(title, '#409eff')
+ }
// 修改id
entity._id = 'tragetPoint' + i
// 修改广告牌样式
@@ -228,6 +255,7 @@
// 当前航线点位事件信息等
waylinePointsEvent.value.push({
position: entity.position._value,
+ isUseGlobalHeight,
eventList: [],
})
}
--
Gitblit v1.9.3