From 41b8a8d0ecea96ace27b5afb9ce63b4193420c49 Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Thu, 14 Aug 2025 08:47:21 +0800
Subject: [PATCH] Merge branch 'refs/heads/历史任务详情' into feature/v5.0/5.0.3
---
src/views/job/components/DeviceJobDetailsMap.vue | 295 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 276 insertions(+), 19 deletions(-)
diff --git a/src/views/job/components/DeviceJobDetailsMap.vue b/src/views/job/components/DeviceJobDetailsMap.vue
index 2bc98ee..ee2ce6b 100644
--- a/src/views/job/components/DeviceJobDetailsMap.vue
+++ b/src/views/job/components/DeviceJobDetailsMap.vue
@@ -1,40 +1,122 @@
<template>
<div id="deviceJobDetailsMap" class="ztzf-cesium">
- <PlanarRouteLineList :curRouteLineData="curRouteLineData" @routeLineListClick="routeLineListClick" />
</div>
</template>
<script setup>
-import PlanarRouteLineList from '@/components/PlanarRouteLineList/PlanarRouteLineList.vue'
-
+import * as Cesium from 'cesium'
import { PublicCesium } from '@/utils/cesium/publicCesium'
-
-const props = defineProps(['detailsData','yuanImages'])
-console.log('props.yua',props.yuanImages);
-import { useRouteLine } from '@/hooks/useRouteLine/useRouteLine.js'
-
-// 加载航线hook
-const { curRouteLineData, routeLineListClick, initViewer, renderPreviewLine } = useRouteLine()
-
-
+import { flyVisual } from '@/utils/cesium/mapUtil'
+import _ from 'lodash'
+import photoDirection from '@/assets/images/historyMapPopup/photoDirection-new.png'
+import panoramaPoint from '@/assets/images/panorama/panorama-point.png' //全景图标
+import { getShowImg } from '@/utils/util'
+import { getEventImage } from '@/utils/stateToImageMap/event'
+import { getPanoramaList } from '@/api/panorama'
+import CreateRouteLine from '@/utils/cesium/createRouteLine'
+import { useStore } from 'vuex'
+import { getOdmToken } from '@/api/model'
+const createRouteLineExample = new CreateRouteLine()
+const store = useStore()
+const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode)
let viewer = null
+let publicCesiumInstance = null
+const viewInstance = shallowRef(null)
+import { cloneDeep } from 'lodash'
+let handler = null
+let curMoveEntity = null
+const tokenStr = ref('')
+const emit = defineEmits(['showImageeclick'])
+const props = defineProps(['detailsData', 'yuanImages', 'jobId'])
+
const initMap = () => {
- viewer = new PublicCesium({ dom: 'deviceJobDetailsMap' }).getViewer()
+ publicCesiumInstance = new PublicCesium({
+ dom: 'deviceJobDetailsMap',
+ terrain: true,
+ flatMode: false,
+ layerMode: 4,
+ })
- initViewer(viewer)
+ viewer = publicCesiumInstance.getViewer()
+ viewInstance.value = publicCesiumInstance
+ viewer.scene.globe.depthTestAgainstTerrain = true
+ createRouteLineExample.initCreateRoute(viewer)
+ handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
+ handler.setInputAction(click => {
+ const pickedObjects = viewer.scene.drillPick(click.position)
+ LeftClickEvent(click, pickedObjects, viewer)
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
+
+ handler.setInputAction(e => {
+ let pick = viewer.scene.drillPick(e.endPosition)
+ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
}
-
// 绘制线和飞行
const drawLine = async () => {
Promise.all(
props.detailsData.way_lines.map(
- async item => await renderPreviewLine(`${item.url}?_t=${new Date().getTime()}`, item.wayline_type)
+ async item =>
+ await createRouteLineExample.parsingFiles(
+ {
+ ...item,
+ url: `${item.url}?_t=${new Date().getTime()}`,
+ },
+ {
+ longitude: item.longitude,
+ latitude: item.latitude,
+ height: item.height,
+ },
+ true,
+ false
+ )
)
- )
+ ).then(res => {
+ createRouteLineExample.showDetailMapPopup(props.detailsData.way_lines)
+ let arr = res.map(i => i.filePositions)
+ let newArr = _.flatten(arr)
+ flyVisual({
+ positionsData: newArr.map(i => [i.lng, i.lat, i.alt]),
+ viewer,
+ pitch: -60,
+ })
+ })
}
-
+const lastSelectedId = ref(null)
+// 鼠标左键点击事件
+const LeftClickEvent = (click, pick, viewer) => {
+ // pick是一个数组
+ if (pick && pick.length > 0) {
+ let startEntity = pick.find(
+ i => i.id.name === 'work-drone-route-planar-polyline' || i.id.name === 'work-drone-route-point-polyline'
+ )?.id
+ if (startEntity) {
+ createRouteLineExample.showSingleDetailMapPopup(startEntity?.customData?.data)
+ return
+ }
+ let imagePath = []
+ let categories = ''
+ let panoramic = ''
+ pick.forEach(item => {
+ const index = item.id.index
+ if (item.id.customType == 'spotImages') {
+ imagePath.push(item.id.customInfo.link)
+ } else if (item.id.customType == 'aggregationSplashed') {
+ imagePath.push(item.id.customInfo.link)
+ } else if (item.id.customType == 'panorama') {
+ //全景
+ imagePath.push(item.id.customInfo.link)
+ categories = item.id.customInfo.resultType
+ }
+ })
+ if (imagePath.length === 0) return
+ const finalImagePaths = categories === 5 ? imagePath : imagePath.map(i => getShowImg(i))
+ emit('showImageeclick', finalImagePaths, 0, categories)
+ }
+}
const removeMap = () => {
viewer.entities.removeAll()
- viewer.destroy()
+ publicCesiumInstance?.viewerDestroy()
+ publicCesiumInstance = null
+ viewer = null
}
watch(
@@ -45,12 +127,187 @@
}
}
)
+const zsList = ref([])
+// 获取odmtoken
+function getOdmTokenStr() {
+ getOdmToken().then(res => {
+ if (res.data.code !== 200) return
+ tokenStr.value = res.data.data
+ })
+}
+// 获取正射列表
+function getZSList(newVal) {
+ let list = []
+ newVal.map((item, index) => {
+ item.childrens.map(zschilditem => {
+ if (zschilditem?.data) {
+ zschilditem?.data.map(dataitem => {
+ list.push(dataitem)
+ })
+ }
+ })
+ })
+ return list
+}
+// 获取正射请求地图聚合数据
+const zsMapList = ref([])
+function getZSMapList(valSn) {
+ const params = {
+ areaCode: userAreaCode.value,
+ deviceSn: valSn,
+ resultType: 4,
+ wayLineJobId: props.jobId,
+ }
+ getPanoramaList(params).then(res => {
+ const resData = res?.data?.data
+ zsMapList.value = resData?.childrens || []
+ zsList.value = getZSList(zsMapList.value)
+ renderOrthophoto()
+ })
+}
+// 解析经纬度
+function getLonLat(str) {
+ if (!str) return []
+ return str
+ .replace('POLYGON((', '')
+ .replace('))', '')
+ .split(',')
+ .map(pair => {
+ const [lon, lat] = pair.trim().split(' ').map(Number)
+ return [lon, lat]
+ })
+}
+// 渲染正射
+function renderOrthophoto() {
+ zsList.value.forEach((item, index) => {
+ const cur = viewInstance.value.addCustomImageryProviderDataSource(
+ new Cesium.UrlTemplateImageryProvider({
+ url: `${import.meta.env.VITE_APP_AREA_NAME}/webodm${item.url}?jwt=${tokenStr.value.split(' ')[1]}`,
+ })
+ )
+ })
+}
+watch(
+ () => props.yuanImages,
+ (newValue, oldValue) => {
+
+ // 增加箭头
+ if (!viewer || !newValue?.length) return;
+ // 清除旧实体
+ const oldEntities = viewer.entities.values.filter(e =>
+ e.id?.startsWith('spotImages') ||
+ e.id?.startsWith('aggregationSplashed') ||
+ e.id?.startsWith('panorama')
+ );
+ oldEntities.forEach(e => viewer.entities.remove(e));
+ // 添加新实体
+ let eventArr = newValue.filter(i => i.resultType === 2)
+ let originalArr = newValue.filter(i => i.resultType === 0)
+ let panoramicArr = newValue.filter(i => i.resultType === 5)
+ let orthographicArr = newValue.filter(i => i.resultType === 4)
+ if (orthographicArr.length >0) {
+ getZSMapList(orthographicArr[0]?.deviceSn)
+ }
+ originalArr.forEach((item_in, index) => {
+ // 根据偏航角度展示图片拍摄的方向
+ let yawAngleDegrees =
+ item_in.metadata.gimbalYawDegree < 0
+ ? 360 + Number(item_in.metadata.gimbalYawDegree)
+ : Number(item_in.metadata.gimbalYawDegree)
+
+ viewer.entities.add({
+ position: Cesium.Cartesian3.fromDegrees(
+ +item_in.metadata.shootPosition.lng,
+ +item_in.metadata.shootPosition.lat,
+ +item_in.metadata.absoluteAltitude
+ ),
+ id: 'spotImages' + item_in.id,
+ customType: 'spotImages',
+ customInfo: {
+ ...item_in,
+ },
+ index: index,
+ billboard: {
+ image: photoDirection,
+ outlineWidth: 0,
+ width: 14,
+ height: 21,
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+ },
+ })
+ })
+
+ eventArr.forEach((item, index) => {
+ viewer.entities.add({
+ id: `aggregationSplashed${item.id}`,
+ customType: 'aggregationSplashed',
+ customInfo: {
+ ...item,
+ },
+ position: Cesium.Cartesian3.fromDegrees(
+ +item.metadata.shootPosition.lng,
+ +item.metadata.shootPosition.lat,
+ +item.metadata.absoluteAltitude
+ ),
+ billboard: {
+ image: getEventImage(item.status),
+ width: 30,
+ height: 30,
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
+ },
+ index: index,
+ properties: {
+ customData: {
+ data: item,
+ },
+ },
+ })
+ })
+ // 全景
+ panoramicArr.forEach((item, index) => {
+ viewer.entities.add({
+ id: `panorama${item.id}`,
+ customType: 'panorama',
+ customInfo: {
+ ...item,
+ },
+ position: Cesium.Cartesian3.fromDegrees(
+ +item.metadata.shootPosition.lng,
+ +item.metadata.shootPosition.lat,
+ +item.metadata.absoluteAltitude
+ ),
+ billboard: {
+ image: panoramaPoint,
+ width: 30,
+ height: 30,
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
+ },
+ index: index,
+ properties: {
+ customData: {
+ data: item,
+ },
+ },
+ })
+ })
+ },
+ { immediate: true, deep: true }
+)
onBeforeUnmount(() => {
+ // 移除事件监听
+ handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
+ handler?.destroy()
+ handler = null
+
+ createRouteLineExample.destroyedCustomDom()
+
removeMap()
})
onMounted(() => {
+ getOdmTokenStr()
nextTick(() => {
initMap()
})
--
Gitblit v1.9.3