From c229d46edd6bb7f731417ead8c4576bebbb36580 Mon Sep 17 00:00:00 2001
From: GuLiMmo <2820890765@qq.com>
Date: Tue, 27 Feb 2024 18:08:23 +0800
Subject: [PATCH] 无人机控制调整、航线库航线样式调整
---
src/assets/icons/arrow-right.png | 0
src/pages/page-web/projects/wayline.vue | 439 +++++++++++++++++++++++++++----------------
src/utils/cesium/ImageTrailMaterial.ts | 127 ++++++++++++
src/components/g-map/DroneControlPanel.vue | 16
4 files changed, 412 insertions(+), 170 deletions(-)
diff --git a/src/assets/icons/arrow-right.png b/src/assets/icons/arrow-right.png
new file mode 100644
index 0000000..900119c
--- /dev/null
+++ b/src/assets/icons/arrow-right.png
Binary files differ
diff --git a/src/components/g-map/DroneControlPanel.vue b/src/components/g-map/DroneControlPanel.vue
index 55671e0..c09cc48 100644
--- a/src/components/g-map/DroneControlPanel.vue
+++ b/src/components/g-map/DroneControlPanel.vue
@@ -21,49 +21,49 @@
</div>
<div class="row">
<div class="drone-control-direction">
- <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_Q)" @onmouseup="onMouseUp">
+ <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_Q)" @mouseup="onMouseUp">
<template #icon>
<UndoOutlined/>
</template>
<span class="word">Q</span>
</Button>
- <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_W)" @onmouseup="onMouseUp">
+ <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_W)" @mouseup="onMouseUp">
<template #icon>
<UpOutlined/>
</template>
<span class="word">W</span>
</Button>
- <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_E)" @onmouseup="onMouseUp">
+ <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_E)" @mouseup="onMouseUp">
<template #icon>
<RedoOutlined/>
</template>
<span class="word">E</span>
</Button>
- <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_UP)" @onmouseup="onMouseUp">
+ <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_UP)" @mouseup="onMouseUp">
<template #icon>
<ArrowUpOutlined/>
</template>
</Button>
<br/>
- <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_A)" @onmouseup="onMouseUp">
+ <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_A)" @mouseup="onMouseUp">
<template #icon>
<LeftOutlined/>
</template>
<span class="word">A</span>
</Button>
- <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_S)" @onmouseup="onMouseUp">
+ <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_S)" @mouseup="onMouseUp">
<template #icon>
<DownOutlined/>
</template>
<span class="word">S</span>
</Button>
- <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_D)" @onmouseup="onMouseUp">
+ <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_D)" @mouseup="onMouseUp">
<template #icon>
<RightOutlined/>
</template>
<span class="word">D</span>
</Button>
- <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @onmouseup="onMouseUp">
+ <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @mouseup="onMouseUp">
<template #icon>
<ArrowDownOutlined/>
</template>
diff --git a/src/pages/page-web/projects/wayline.vue b/src/pages/page-web/projects/wayline.vue
index 9435c54..0776a50 100644
--- a/src/pages/page-web/projects/wayline.vue
+++ b/src/pages/page-web/projects/wayline.vue
@@ -1,14 +1,21 @@
<template>
<div class="project-wayline-wrapper height-100" ref="projectWayLine">
<a-spin :spinning="loading" :delay="300" tip="加载中" size="large">
- <div style="height: 50px; line-height: 50px; border-bottom: 1px solid #4f4f4f; font-weight: 450;">
+ <div style="
+ height: 50px;
+ line-height: 50px;
+ border-bottom: 1px solid #4f4f4f;
+ font-weight: 450;
+ ">
<a-row>
<a-col :span="1"></a-col>
- <a-col :span="15">{{ isPointListOpen ? '航点列表' : '航线库' }}</a-col>
+ <a-col :span="15">{{
+ isPointListOpen ? "航点列表" : "航线库"
+ }}</a-col>
<a-col :span="8" v-if="importVisible" class="flex-row flex-justify-end flex-align-center">
<a-upload name="file" :multiple="false" :before-upload="beforeUpload" :show-upload-list="false"
:customRequest="uploadFile">
- <a-button type="text" style="color: white;">
+ <a-button type="text" style="color: white">
<SelectOutlined />
</a-button>
</a-upload>
@@ -17,31 +24,42 @@
</div>
<div :style="{ height: height + 'px' }" class="scrollbar" v-if="!isPointListOpen">
<div id="data" class="height-100 uranus-scrollbar" v-if="waylinesData.data.length !== 0" @scroll="onScroll">
- <div v-for="wayline in waylinesData.data" :key="wayline.id">
- <div class="wayline-panel" style="padding-top: 5px;" @click="selectRoute(wayline)">
+ <div v-for="wayline in waylinesData.data" :key="wayline.id" @click="selectRoute(wayline)">
+ <div class="wayline-panel" style="padding-top: 5px">
<div class="title">
<a-tooltip :title="wayline.name">
- <div class="pr10" style="width: 120px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">
- {{ wayline.name }}</div>
+ <div class="pr10" style="
+ width: 120px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ ">
+ {{ wayline.name }}
+ </div>
</a-tooltip>
<div class="ml10">
<UserOutlined />
</div>
<a-tooltip :title="wayline.user_name">
- <div class="ml5 pr10"
- style="width: 80px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">{{
- wayline.user_name }}</div>
+ <div class="ml5 pr10" style="
+ width: 80px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ ">
+ {{ wayline.user_name }}
+ </div>
</a-tooltip>
- <div class="fz20">
- <!-- <span style="margin-right: 10px;">
- <EditOutlined style="font-size: 15px;" />
- </span> -->
+ <div class="fz20 tools">
+ <span style="margin-right: 10px">
+ <EditOutlined style="font-size: 15px" @click="routeEventEdit" />
+ </span>
<a-dropdown>
- <a style="color: white;">
+ <a style="color: white">
<EllipsisOutlined />
</a>
<template #overlay>
- <a-menu theme="dark" class="more" style="background: #3c3c3c;">
+ <a-menu theme="dark" class="more" style="background: #3c3c3c">
<a-menu-item @click="openEditModal(wayline)">
<span>重命名</span>
</a-menu-item>
@@ -56,21 +74,29 @@
</a-dropdown>
</div>
</div>
- <div class="ml10 mt5" style="color: hsla(0,0%,100%,0.65);">
+ <div class="ml10 mt5" style="color: hsla(0, 0%, 100%, 0.65)">
<span>
<RocketOutlined />
</span>
- <span class="ml5">{{ Object.keys(EDeviceType)[Object.values(EDeviceType).indexOf(wayline.drone_model_key)]
+ <span class="ml5">{{
+ Object.keys(EDeviceType)[
+ Object.values(EDeviceType).indexOf(wayline.drone_model_key)
+ ]
}}</span>
<span class="ml10">
- <CameraFilled style="border-top: 1px solid; padding-top: -3px;" />
+ <CameraFilled style="border-top: 1px solid; padding-top: -3px" />
</span>
<span class="ml5" v-for="payload in wayline.payload_model_keys" :key="payload.id">
- {{ Object.keys(EDeviceType)[Object.values(EDeviceType).indexOf(payload)] }}
+ {{
+ Object.keys(EDeviceType)[
+ Object.values(EDeviceType).indexOf(payload)
+ ]
+ }}
</span>
</div>
- <div class="mt5 ml10" style="color: hsla(0,0%,100%,0.35);">
- <span class="mr10">更新时间: {{ new Date(wayline.update_time).toLocaleString() }}</span>
+ <div class="mt5 ml10" style="color: hsla(0, 0%, 100%, 0.35)">
+ <span class="mr10">更新时间:
+ {{ new Date(wayline.update_time).toLocaleString() }}</span>
</div>
</div>
</div>
@@ -80,7 +106,7 @@
</div>
<a-modal v-model:visible="deleteTip" okText="确定" cancelText="取消" width="450px" :closable="false"
:maskClosable="false" centered :okButtonProps="{ danger: true }" @ok="deleteWayline">
- <p class="pt10 pl20" style="height: 50px;">确定要删除该文件吗?</p>
+ <p class="pt10 pl20" style="height: 50px">确定要删除该文件吗?</p>
<template #title>
<div class="flex-row flex-justify-center">
<span>删除</span>
@@ -102,7 +128,9 @@
<li v-for="(item, index) in tragetPointArr" :key="index" :class="{ selectedColor: index === selectedPoint }"
@click="tragetPointClick(item.position, index)">
<div class="graph">
- <div class="left" :style="{ borderTopColor: index === selectedPoint ? '#FF9900' : '#2D8CF0' }"></div>
+ <div class="left" :style="{
+ borderTopColor: index === selectedPoint ? '#FF9900' : '#2D8CF0',
+ }"></div>
<div class="right">{{ index + 1 }}</div>
</div>
<div class="graph-right">
@@ -125,9 +153,24 @@
import { reactive } from '@vue/reactivity'
import { message } from 'ant-design-vue'
import { onMounted, onUpdated, ref } from 'vue'
-import { deleteWaylineFile, downloadWaylineFile, getWaylineFiles, importKmzFile, getWayLineFile } from '/@/api/wayline'
+import ImageTrailMaterial from '/@/utils/cesium/ImageTrailMaterial'
+import {
+ deleteWaylineFile,
+ downloadWaylineFile,
+ getWaylineFiles,
+ importKmzFile,
+ getWayLineFile,
+} from '/@/api/wayline'
import { ELocalStorageKey, ERouterName } from '/@/types'
-import { ArrowLeftOutlined, EllipsisOutlined, RocketOutlined, CameraFilled, UserOutlined, SelectOutlined, EditOutlined } from '@ant-design/icons-vue'
+import {
+ ArrowLeftOutlined,
+ EllipsisOutlined,
+ RocketOutlined,
+ CameraFilled,
+ UserOutlined,
+ SelectOutlined,
+ EditOutlined,
+} from '@ant-design/icons-vue'
import { EDeviceType } from '/@/types/device'
import { useMyStore } from '/@/store'
import { WaylineFile } from '/@/types/wayline'
@@ -153,43 +196,56 @@
const { appContext }: any = getCurrentInstance()
const global = appContext.config.globalProperties
const store = useMyStore()
-let kmlDataSource: { entities: { values: { _children: any }[] }; show: boolean } | null | any = null
+let kmlDataSource:
+ | { entities: { values: { _children: any }[] }; show: boolean }
+ | null
+ | any = null
const pagination: IPage = {
page: 1,
total: -1,
- page_size: 10
+ page_size: 10,
}
const kmlEntity = ref<any>([])
const waylinesData = reactive({
- data: [] as WaylineFile[]
+ data: [] as WaylineFile[],
})
// 当前点击的信息
const currentWayLine = ref<any>({})
const root = getRoot()
-const workspaceId = computed(() => store.state.common.projectId || localStorage.getItem(ELocalStorageKey.WorkspaceId))
+const workspaceId = computed(
+ () =>
+ store.state.common.projectId ||
+ localStorage.getItem(ELocalStorageKey.WorkspaceId)
+)
const deleteTip = ref(false)
const deleteWaylineId = ref<string>('')
const canRefresh = ref(true)
-const importVisible = ref<boolean>(root.$router.currentRoute.value.name === ERouterName.WAYLINE)
+const importVisible = ref<boolean>(
+ root.$router.currentRoute.value.name === ERouterName.WAYLINE
+)
const editVisible = ref<boolean>(false)
const height = ref()
-const { removeById, addClickEvent, getEntityById } = cesiumOperation()
+const { removeById, addClickEvent, getEntityById, addPolyline } = cesiumOperation()
const isPointListOpen = ref<boolean>(false)
-const tragetPointArr = ref<{
- position: Cesium.Cartesian3,
- eventList: any[]
-}[]>([])
+const tragetPointArr = ref<
+ {
+ position: Cesium.Cartesian3;
+ eventList: any[];
+ }[]
+>([])
const selectedPoint = ref<number | null>(null)
// 对应事件
-const eventList = reactive<{
- key: string,
- name: string,
- distinguish?: string,
- icon?: string
-}[]>([
+const eventList = reactive<
+ {
+ key: string;
+ name: string;
+ distinguish?: string;
+ icon?: string;
+ }[]
+>([
{
key: 'takePhoto',
name: '单拍',
@@ -246,17 +302,24 @@
key: 'hover',
name: '悬停等待',
icon: getResource('waylinetool/xt.png'),
- }
+ },
])
onMounted(() => {
- const parent = document.getElementsByClassName('scrollbar').item(0)?.parentNode as HTMLDivElement
- height.value = document.body.clientHeight - parent.firstElementChild!.clientHeight
+ const parent = document.getElementsByClassName('scrollbar').item(0)
+ ?.parentNode as HTMLDivElement
+ height.value =
+ document.body.clientHeight - parent.firstElementChild!.clientHeight
getWaylines()
const key = setInterval(() => {
- const data = document.getElementById('data')?.lastElementChild as HTMLDivElement
- if (pagination.total === 0 || Math.ceil(pagination.total / pagination.page_size) <= pagination.page || height.value <= data?.clientHeight + data?.offsetTop) {
+ const data = document.getElementById('data')
+ ?.lastElementChild as HTMLDivElement
+ if (
+ pagination.total === 0 ||
+ Math.ceil(pagination.total / pagination.page_size) <= pagination.page ||
+ height.value <= data?.clientHeight + data?.offsetTop
+ ) {
clearInterval(key)
return
}
@@ -270,7 +333,8 @@
if (kmlDataSource) {
global.$viewer.dataSources.remove(kmlDataSource)
}
- removeById('kmzLine')
+ removeById('entityLine')
+ removeById('bottomLine')
removeById('clickBox')
store.commit('SET_WAYLINE_INFO', {
isShow: false,
@@ -287,17 +351,19 @@
getWaylineFiles(workspaceId.value, {
page: pagination.page,
page_size: pagination.page_size,
- order_by: 'update_time desc'
- }).then(res => {
- if (res.code !== 0) {
- return
- }
- waylinesData.data = [...waylinesData.data, ...res.data.list]
- pagination.total = res.data.pagination.total
- pagination.page = res.data.pagination.page
- }).finally(() => {
- canRefresh.value = true
+ order_by: 'update_time desc',
})
+ .then((res) => {
+ if (res.code !== 0) {
+ return
+ }
+ waylinesData.data = [...waylinesData.data, ...res.data.list]
+ pagination.total = res.data.pagination.total
+ pagination.page = res.data.pagination.page
+ })
+ .finally(() => {
+ canRefresh.value = true
+ })
}
function showWaylineTip (waylineId: string) {
@@ -306,7 +372,7 @@
}
function deleteWayline () {
- deleteWaylineFile(workspaceId.value, deleteWaylineId.value).then(res => {
+ deleteWaylineFile(workspaceId.value, deleteWaylineId.value).then((res) => {
if (res.code === 0) {
message.success('文件删除成功')
}
@@ -321,35 +387,45 @@
function downloadWayline (waylineId: string, fileName: string) {
loading.value = true
- downloadWaylineFile(workspaceId.value, waylineId).then(res => {
- if (!res) {
- return
- }
- const data = new Blob([res], { type: 'application/zip' })
- downloadFile(data, fileName + '.kmz')
- }).finally(() => {
- loading.value = false
- })
+ downloadWaylineFile(workspaceId.value, waylineId)
+ .then((res) => {
+ if (!res) {
+ return
+ }
+ const data = new Blob([res], { type: 'application/zip' })
+ downloadFile(data, fileName + '.kmz')
+ })
+ .finally(() => {
+ loading.value = false
+ })
}
function selectRoute (wayline: WaylineFile) {
loading.value = true
- getWayLineFile(workspaceId.value, wayline.id).then(res => {
- store.commit('SET_SELECT_WAYLINE_INFO', wayline)
- initKmlFile(res.data)
- store.commit('SET_WAYLINE_KMZPATH', res.data)
- }).finally(() => {
- loading.value = false
- })
+ getWayLineFile(workspaceId.value, wayline.id)
+ .then((res) => {
+ store.commit('SET_SELECT_WAYLINE_INFO', wayline)
+ initKmlFile(res.data)
+ store.commit('SET_WAYLINE_KMZPATH', res.data)
+ })
+ .finally(() => {
+ loading.value = false
+ })
// 清除选中点柱形和隐藏按钮
store.commit('SET_WAYLINE_INFO', {
isShow: false,
wayline: {},
- position: null
+ position: null,
})
removeById('clickBox')
+ // isPointListOpen.value = !isPointListOpen.value
+}
+
+// 编辑显示
+const routeEventEdit = () => {
isPointListOpen.value = !isPointListOpen.value
}
+
/**
* 加载kml文件
* @param file
@@ -357,7 +433,8 @@
function initKmlFile (file: string) {
// const [, address] = file.split('cloud-bucket')
// file = import.meta.env.VITE_MEDIAPANEL_API_URL + address
- removeById('kmzLine')
+ removeById('entityLine')
+ removeById('bottomLine')
const options = {
camera: global.$viewer.scene.camera,
canvas: global.$viewer.scene.canvas,
@@ -366,55 +443,69 @@
if (kmlDataSource) {
global.$viewer.dataSources.remove(kmlDataSource)
}
- global.$viewer.dataSources.add(
- Cesium.KmlDataSource.load(
- file,
- options
- )).then((res: any) => {
- kmlDataSource = res
- kmlEntity.value = kmlDataSource.entities.values
- kmlDataSource.show = true
- const kmlEntityArr = kmlDataSource.entities.values[0]._children
- const cartesianArr: any[] = []
- for (let i = 0; i < kmlEntityArr.length; i++) {
- const entity = kmlEntityArr[i]
- const billboard = createBillboard(`${i + 1}`, '#2D8CF0')
- entity._id = 'tragetPoint' + i
- entity.billboard = new Cesium.BillboardGraphics({
- image: billboard,
- pixelOffset: new Cesium.Cartesian2(0, -20)
- })
- entity.point = new Cesium.PointGraphics({
- pixelSize: 20,
- color: Cesium.Color.GHOSTWHITE,
- outlineColor: Cesium.Color.BLACK,
- })
- cartesianArr.push(entity.position._value)
- tragetPointArr.value[i] = {
- position: entity.position._value,
- eventList: []
+ global.$viewer.dataSources
+ .add(Cesium.KmlDataSource.load(file, options))
+ .then((res: any) => {
+ kmlDataSource = res
+ kmlEntity.value = kmlDataSource.entities.values
+ kmlDataSource.show = true
+ const kmlEntityArr = kmlDataSource.entities.values[0]._children
+ const cartesianArr: any[] = []
+ for (let i = 0; i < kmlEntityArr.length; i++) {
+ const entity = kmlEntityArr[i]
+ const billboard = createBillboard(`${i + 1}`, '#2D8CF0')
+ entity._id = 'tragetPoint' + i
+ entity.billboard = new Cesium.BillboardGraphics({
+ image: billboard,
+ pixelOffset: new Cesium.Cartesian2(0, -20),
+ })
+ entity.point = new Cesium.PointGraphics({
+ pixelSize: 20,
+ color: Cesium.Color.GHOSTWHITE,
+ outlineColor: Cesium.Color.BLACK,
+ })
+ cartesianArr.push(entity.position._value)
+ tragetPointArr.value[i] = {
+ position: entity.position._value,
+ eventList: [],
+ }
}
- }
- // tragetPointArr.value = cartesianArr
- // const stripe = createStripe()
- const lineEntity = global.$viewer.entities.add({
- name: 'entityLine',
- id: 'kmzLine',
- polyline: {
- positions: cartesianArr,
- width: 20,
- material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.MEDIUMSPRINGGREEN),
- clampToGround: false, // 关闭贴地效果,保留高度
- },
- })
+ // tragetPointArr.value = cartesianArr
+ // const stripe = createStripe()
+ // 绘制静态线
+ addPolyline({
+ id: 'entityLine',
+ polyline: {
+ positions: cartesianArr,
+ width: 10,
+ material: new Cesium.ImageMaterialProperty({
+ image: getResource('arrow-right.png'),
+ color: Cesium.Color.WHITE,
+ repeat: new Cesium.Cartesian2(30, 1),
+ }),
+ zIndex: 2,
+ clampToGround: true, // 关闭贴地效果,保留高度
+ },
+ })
+ addPolyline({
+ id: 'bottomLine',
+ polyline: {
+ positions: cartesianArr,
+ width: 7,
+ material: Cesium.Color.fromBytes(96, 210, 149),
+ zIndex: 1,
+ clampToGround: true, // 关闭贴地效果,保留高度
+ },
+ })
- global.$viewer.flyTo(lineEntity, {
- offset: new Cesium.HeadingPitchRange(0, -90, 8000)
- })
+ const lineEntity = getEntityById('entityLine')
+ global.$viewer.flyTo(lineEntity, {
+ offset: new Cesium.HeadingPitchRange(0, -90, 200),
+ })
- // 解析kmz文件
- readKmzFile(file)
- })
+ // 解析kmz文件
+ readKmzFile(file)
+ })
}
// 点击目标点
@@ -423,17 +514,25 @@
store.commit('SET_WAYLINE_INFO', {
isShow: true,
wayline: currentWayLine,
- position: index
+ position: index,
})
if (getEntityById('clickBox')) {
removeById('clickBox')
}
- kmlDataSource.entities._entities._array.forEach((entity: { _id: string; billboard: Cesium.BillboardGraphics }, i: number) => {
- entity.billboard = new Cesium.BillboardGraphics({
- image: createBillboard(`${i}`, entity._id === `tragetPoint${index}` ? '#FF9900' : '#2D8CF0'),
- pixelOffset: new Cesium.Cartesian2(0, -20)
- })
- })
+ kmlDataSource.entities._entities._array.forEach(
+ (
+ entity: { _id: string; billboard: Cesium.BillboardGraphics },
+ i: number
+ ) => {
+ entity.billboard = new Cesium.BillboardGraphics({
+ image: createBillboard(
+ `${i}`,
+ entity._id === `tragetPoint${index}` ? '#FF9900' : '#2D8CF0'
+ ),
+ pixelOffset: new Cesium.Cartesian2(0, -20),
+ })
+ }
+ )
// 创建盒子
const entity = {
id: 'clickBox',
@@ -443,8 +542,8 @@
material: Cesium.Color.MEDIUMSPRINGGREEN.withAlpha(0.1),
// outline: true,
// outlineColor: Cesium.Color.MEDIUMSPRINGGREEN.withAlpha(0.8),
- heightReference: true
- }
+ heightReference: true,
+ },
}
const boxEntity = global.$viewer.entities.add(entity)
@@ -455,7 +554,11 @@
function onScroll (e: any) {
const element = e.srcElement
- if (element.scrollTop + element.clientHeight >= element.scrollHeight - 5 && Math.ceil(pagination.total / pagination.page_size) > pagination.page && canRefresh.value) {
+ if (
+ element.scrollTop + element.clientHeight >= element.scrollHeight - 5 &&
+ Math.ceil(pagination.total / pagination.page_size) > pagination.page &&
+ canRefresh.value
+ ) {
pagination.page++
getWaylines()
}
@@ -484,19 +587,21 @@
fileList.value.forEach(async (file: FileItem) => {
const fileData = new FormData()
fileData.append('file', file, file.name)
- await importKmzFile(workspaceId.value, fileData).then((res) => {
- if (res.code === 0) {
- message.success(`${file.name} 文件上传成功`)
- canRefresh.value = true
- pagination.total = 0
- pagination.page = 1
- waylinesData.data = []
- getWaylines()
- }
- }).finally(() => {
- loading.value = false
- fileList.value = []
- })
+ await importKmzFile(workspaceId.value, fileData)
+ .then((res) => {
+ if (res.code === 0) {
+ message.success(`${file.name} 文件上传成功`)
+ canRefresh.value = true
+ pagination.total = 0
+ pagination.page = 1
+ waylinesData.data = []
+ getWaylines()
+ }
+ })
+ .finally(() => {
+ loading.value = false
+ fileList.value = []
+ })
})
}
@@ -553,25 +658,30 @@
*/
const readKmzFile = (kmzPath: string) => {
// 使用axios读取文件
- return axios.get(kmzPath, { responseType: 'arraybuffer' })
- .then(fileRes => fileRes.data)
- .then(kmzData => JsZip.loadAsync(kmzData)) // 解压kmz文件
- .then(kmzZip => {
+ return axios
+ .get(kmzPath, { responseType: 'arraybuffer' })
+ .then((fileRes) => fileRes.data)
+ .then((kmzData) => JsZip.loadAsync(kmzData)) // 解压kmz文件
+ .then((kmzZip) => {
// 通过文件名找到 KML 文件
const kmlFile = kmzZip.file(/\.kml$/i)[0]
return kmlFile.async('text')
- }).then(kml => {
+ })
+ .then((kml) => {
// 查找航点标签reg
const regx = /<Placemark>([\s\S]*?)<\/Placemark>/g
// 查找事件组reg
- const actionGroupReg = /<wpml:actionGroup>([\s\S]*?)<\/wpml:actionGroup>/g
+ const actionGroupReg =
+ /<wpml:actionGroup>([\s\S]*?)<\/wpml:actionGroup>/g
// 查找单个事件reg
const actionRegx = /<wpml:action>([\s\S]*?)<\/wpml:action>/g
// 获取shootType
const shootTypeRegx = /<wpml:shootType>([\s\S]*?)<\/wpml:shootType>/g
// 云台角度
- const gimbalPitchRotateAngleRegx = /<wpml:gimbalPitchRotateAngle>(.*?)<\/wpml:gimbalPitchRotateAngle>/
- const gimbalYawRotateAngleRegx = /<wpml:gimbalYawRotateAngle>(.*?)<\/wpml:gimbalYawRotateAngle>/
+ const gimbalPitchRotateAngleRegx =
+ /<wpml:gimbalPitchRotateAngle>(.*?)<\/wpml:gimbalPitchRotateAngle>/
+ const gimbalYawRotateAngleRegx =
+ /<wpml:gimbalYawRotateAngle>(.*?)<\/wpml:gimbalYawRotateAngle>/
// 当前kmz文件航点
const kmlPoints = kml.match(regx)
kmlPoints?.forEach((point: string, index: number) => {
@@ -581,12 +691,13 @@
if (ponitAction) {
// 当前事件
const actions = ponitAction[0].match(actionRegx)
- actions?.forEach(action => {
+ actions?.forEach((action) => {
eventList.forEach((item: any) => {
if (!item.distinguish) {
action.includes(item.key) && eventArr.push(item)
} else {
- const pitchAngle = action?.match(gimbalPitchRotateAngleRegx) || []
+ const pitchAngle =
+ action?.match(gimbalPitchRotateAngleRegx) || []
const yawAngle = action?.match(gimbalYawRotateAngleRegx) || []
if (!!Number(pitchAngle[1]) && item.distinguish === 'pitch') {
eventArr.push(item)
@@ -620,7 +731,6 @@
const handleEditName = () => {
editVisible.value = false
}
-
</script>
<style lang="scss" scoped>
@@ -642,6 +752,10 @@
height: 30px;
font-weight: bold;
margin: 0px 10px 0 10px;
+
+ .tools {
+ display: flex;
+ }
}
}
@@ -685,7 +799,7 @@
.left {
width: 0;
height: 0;
- border-top: 15px solid #2D8CF0;
+ border-top: 15px solid #2d8cf0;
border-right: 10px solid transparent;
border-left: 10px solid transparent;
}
@@ -716,7 +830,7 @@
}
&:hover {
- background-color: #3C3C3C;
+ background-color: #3c3c3c;
}
}
}
@@ -748,7 +862,7 @@
.ant-modal-body,
.ant-modal-footer {
- background-color: #1C1C1C;
+ background-color: #1c1c1c;
border: 0;
.wayline-title {
@@ -765,5 +879,6 @@
}
.selectedColor {
- background-color: #3C3C3C;
-}</style>
+ background-color: #3c3c3c;
+}
+</style>
diff --git a/src/utils/cesium/ImageTrailMaterial.ts b/src/utils/cesium/ImageTrailMaterial.ts
new file mode 100644
index 0000000..b0394d1
--- /dev/null
+++ b/src/utils/cesium/ImageTrailMaterial.ts
@@ -0,0 +1,127 @@
+import * as Cesium from 'cesium'
+/**
+ * 定义Cesium材质对象
+ */
+class ImageTrailMaterial {
+ _definitionChanged: Cesium.Event<(...args: any[]) => void>;
+ _color: undefined;
+ _colorSubscription: undefined;
+ _speed: undefined;
+ _speedSubscription: undefined;
+ _image: undefined;
+ _imageSubscription: undefined;
+ _repeat: undefined;
+ _repeatSubscription: undefined;
+ color: any;
+ speed: any;
+ image: any;
+ repeat: Cesium.Cartesian2;
+ constructor (options : any = {}) {
+ this._definitionChanged = new Cesium.Event()
+ this._color = undefined
+ this._colorSubscription = undefined
+ this._speed = undefined
+ this._speedSubscription = undefined
+ this._image = undefined
+ this._imageSubscription = undefined
+ this._repeat = undefined
+ this._repeatSubscription = undefined
+ this.color = options.color || Cesium.Color.fromBytes(0, 0, 255, 255)
+ this.speed = options.speed || 1
+ this.image = options.image
+ this.repeat = new Cesium.Cartesian2(
+ options.repeat?.x || 1,
+ options.repeat?.y || 1
+ )
+ }
+
+ get isConstant () {
+ return false
+ }
+
+ get definitionChanged () {
+ return this._definitionChanged
+ }
+
+ getType () {
+ return Cesium.Material.ImageTrailMaterialType
+ }
+
+ getValue (time: any, result: any) {
+ if (!result) {
+ result = {}
+ }
+ result.color = Cesium.Property?.getValueOrUndefined(this._color, time)
+ result.image = Cesium.Property?.getValueOrUndefined(this._image, time)
+ result.repeat = Cesium.Property?.getValueOrUndefined(this._repeat, time)
+ result.speed = this._speed
+ return result
+ }
+
+ equals (other: this) {
+ return (
+ this === other ||
+ (other instanceof ImageTrailMaterial &&
+ Cesium.Property.equals(this._color, other._color) &&
+ Cesium.Property.equals(this._image, other._image) &&
+ Cesium.Property.equals(this._repeat, other._repeat) &&
+ Cesium.Property.equals(this._speed, other._speed))
+ )
+ }
+}
+
+Object.defineProperties(ImageTrailMaterial.prototype, {
+ color: Cesium.createPropertyDescriptor('color'),
+ speed: Cesium.createPropertyDescriptor('speed'),
+ image: Cesium.createPropertyDescriptor('image'),
+ repeat: Cesium.createPropertyDescriptor('repeat'),
+})
+// 材质类型
+Cesium.Material.ImageTrailMaterialType = 'PolylineImageTrail'
+// 添加材质到缓冲区中
+Cesium.Material._materialCache.addMaterial(
+ Cesium.Material.ImageTrailMaterialType,
+ {
+ fabric: {
+ type: Cesium.Material.ImageTrailMaterialType,
+ // uniform变量
+ uniforms: {
+ color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
+ image: Cesium.Material.DefaultImageId,
+ speed: 1,
+ repeat: new Cesium.Cartesian2(1, 1),
+ },
+ //
+ source: `
+ uniform sampler2D image;
+ uniform float speed;
+ uniform vec4 color;
+ uniform vec2 repeat;
+
+ czm_material czm_getMaterial(czm_materialInput materialInput){
+ czm_material material=czm_getDefaultMaterial(materialInput);
+ vec2 st=repeat * materialInput.st;
+ float time=fract(czm_frameNumber*speed/1000.);
+ // st.s是横轴方向运动,st.t是纵轴,
+ // vec2(fract(st.s-time),st.t)是横轴按照时间变化而变化,纵轴保持正常不变化
+ vec4 colorImage=texture2D(image,vec2(fract(st.s-time),st.t));
+ vec4 fragColor;
+ fragColor.rgb=color.rgb / 1.0;
+ if(color.a==0.){
+ material.alpha=colorImage.a;
+ material.diffuse=colorImage.rgb;
+ }else{
+ material.alpha=colorImage.a*color.a;
+ material.diffuse=max(color.rgb*material.alpha*3.,color.rgb);
+ }
+ return material;
+ }
+ `
+ },
+ translucent: function () {
+ return true
+ },
+ }
+)
+
+export default ImageTrailMaterial
--
Gitblit v1.9.3