From d5e1d8a5f773738f6766175ea409f47740a24c97 Mon Sep 17 00:00:00 2001
From: GuLiMmo <2820890765@qq.com>
Date: Wed, 28 Feb 2024 19:09:25 +0800
Subject: [PATCH] 航线库更新

---
 src/pages/page-web/projects/wayline.vue |  275 +++++++++++++++++++++++++++++++++----------------------
 1 files changed, 165 insertions(+), 110 deletions(-)

diff --git a/src/pages/page-web/projects/wayline.vue b/src/pages/page-web/projects/wayline.vue
index 0776a50..072dd6f 100644
--- a/src/pages/page-web/projects/wayline.vue
+++ b/src/pages/page-web/projects/wayline.vue
@@ -120,10 +120,17 @@
           <a-input v-model:value="currentWayLine.name" placeholder="请输入航线名称" />
         </a-modal>
       </div>
+      <!-- 航线编辑 -->
       <ul class="targt-point scrollbar" :style="{ height: height + 'px' }" v-else>
-        <div class="back-btn" @click="isPointListOpen = !isPointListOpen">
+        <div class="back-btn" @click="backPage">
           <ArrowLeftOutlined />
           <span>返回上一页</span>
+        </div>
+        <div class="wayline-info">
+          <div class="info-box" v-for="(item, index) in waylineDetails" :key="index">
+            <div class="title">{{ item.title }}</div>
+            <div class="info">{{ item.value }}</div>
+          </div>
         </div>
         <li v-for="(item, index) in tragetPointArr" :key="index" :class="{ selectedColor: index === selectedPoint }"
           @click="tragetPointClick(item.position, index)">
@@ -154,6 +161,7 @@
 import { message } from 'ant-design-vue'
 import { onMounted, onUpdated, ref } from 'vue'
 import ImageTrailMaterial from '/@/utils/cesium/ImageTrailMaterial'
+import { getPolylineLength } from '/@/utils/cesium/mapUtils'
 import {
   deleteWaylineFile,
   downloadWaylineFile,
@@ -188,6 +196,9 @@
 
 const getResource = (name: string) => {
   return new URL(`/src/assets/icons/${name}`, import.meta.url).href
+}
+const getResourceSvg = (name: string) => {
+  return new URL(`/src/assets/svg/${name}`, import.meta.url).href
 }
 
 const projectWayLine = ref<HTMLDivElement>()
@@ -226,7 +237,7 @@
 )
 const editVisible = ref<boolean>(false)
 const height = ref()
-const { removeById, addClickEvent, getEntityById, addPolyline } = cesiumOperation()
+const { removeById, addClickEvent, getEntityById, addPolyline, removeAllPoint } = cesiumOperation()
 
 const isPointListOpen = ref<boolean>(false)
 const tragetPointArr = ref<
@@ -333,8 +344,8 @@
   if (kmlDataSource) {
     global.$viewer.dataSources.remove(kmlDataSource)
   }
-  removeById('entityLine')
-  removeById('bottomLine')
+  // removeById('entityLine')
+  removeAllPoint()
   removeById('clickBox')
   store.commit('SET_WAYLINE_INFO', {
     isShow: false,
@@ -431,10 +442,8 @@
  * @param file
  */
 function initKmlFile (file: string) {
-  // const [, address] = file.split('cloud-bucket')
-  // file = import.meta.env.VITE_MEDIAPANEL_API_URL + address
-  removeById('entityLine')
-  removeById('bottomLine')
+  // removeById('entityLine')
+  removeAllPoint()
   const options = {
     camera: global.$viewer.scene.camera,
     canvas: global.$viewer.scene.canvas,
@@ -447,65 +456,131 @@
     .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()
-      // 绘制静态线
-      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, // 关闭贴地效果,保留高度
-        },
-      })
-
-      const lineEntity = getEntityById('entityLine')
-      global.$viewer.flyTo(lineEntity, {
-        offset: new Cesium.HeadingPitchRange(0, -90, 200),
-      })
-
+      createPointMarker(kmlDataSource)
       // 解析kmz文件
       readKmzFile(file)
     })
+}
+
+const waylineDetails = reactive([
+  {
+    title: '航线长度',
+    value: '0'
+  },
+  {
+    title: '预计执行时间',
+    value: '0'
+  },
+  {
+    title: '航点',
+    value: 0
+  },
+  {
+    title: '照片',
+    value: 0
+  },
+])
+function createPointMarker (dataSource: { entities: { values: { _children: any }[] }; show: boolean }) {
+  const ellipsoid = global.$viewer.scene.globe.ellipsoid
+  kmlEntity.value = dataSource.entities.values
+  dataSource.show = true
+  const kmlEntityArr = dataSource.entities.values[0]._children
+  const cartesianArr: any[] = []
+  let btmStartPoint = null
+  for (let i = 0; i < kmlEntityArr.length; i++) {
+    const entity = kmlEntityArr[i]
+    // 将cartographic3D坐标转换为正常坐标
+    const c3Position = entity.position._value
+    const c2Postion = ellipsoid.cartesianToCartographic(c3Position)
+    const longitude = Cesium.Math.toDegrees(c2Postion.longitude)
+    const latitude = Cesium.Math.toDegrees(c2Postion.latitude)
+    const height = 100
+    entity.position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
+    if (i === 0) {
+      btmStartPoint = Cesium.Cartesian3.fromDegrees(longitude, latitude, 0)
+    }
+    // 创建广告牌信息
+    const billboard = createBillboard(`${i + 1}`, '#61d396')
+    // 修改id
+    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,
+    })
+    // 创建虚线
+    addPolyline({
+      id: 'dashLine' + i,
+      polyline: {
+        positions: Cesium.Cartesian3.fromDegreesArrayHeights([
+          longitude,
+          latitude,
+          height,
+          longitude,
+          latitude,
+          0
+        ]),
+        width: 1,
+        material: new Cesium.PolylineDashMaterialProperty({
+          color: Cesium.Color.WHITE
+        })
+      }
+    })
+    cartesianArr.push(entity.position._value)
+    tragetPointArr.value[i] = {
+      position: entity.position._value,
+      eventList: [],
+    }
+  }
+  // 创建起飞位置
+  global.$viewer.entities.add({
+    id: 'dronePosition',
+    position: btmStartPoint,
+    billboard: {
+      image: getResource('dock.png'),
+      width: 36,
+      height: 36,
+    }
+  })
+  // 绘制链接线
+  addPolyline({
+    id: 'entityLine',
+    polyline: {
+      positions: [btmStartPoint, ...cartesianArr],
+      width: 7,
+      material: new ImageTrailMaterial({
+        backgroundColor: Cesium.Color.fromBytes(96, 210, 149),
+        image: getResource('arrow-right.png'),
+        imageW: 7,
+        duration: 0,
+        animation: false
+      }),
+      clampToGround: false, // 关闭贴地效果,保留高度
+    },
+  })
+  const lineEntity = getEntityById('entityLine')
+  const polylineLength = getPolylineLength(lineEntity).toFixed(1) || 0
+  waylineDetails[0].value = polylineLength + 'm'
+  waylineDetails[2].value = cartesianArr.length
+  global.$viewer.flyTo(lineEntity, {
+    offset: new Cesium.HeadingPitchRange(0, -90, 300),
+  })
+}
+
+// 返回上一页
+function backPage () {
+  isPointListOpen.value = false
+  store.commit('SET_WAYLINE_INFO', {
+    isShow: false,
+    wayline: {},
+    position: 0,
+  })
 }
 
 // 点击目标点
@@ -513,7 +588,7 @@
   selectedPoint.value = index
   store.commit('SET_WAYLINE_INFO', {
     isShow: true,
-    wayline: currentWayLine,
+    wayline: currentWayLine.value,
     position: index,
   })
   if (getEntityById('clickBox')) {
@@ -533,23 +608,6 @@
       })
     }
   )
-  // 创建盒子
-  const entity = {
-    id: 'clickBox',
-    position,
-    box: {
-      dimensions: new Cesium.Cartesian3(10.0, 10.0, 120),
-      material: Cesium.Color.MEDIUMSPRINGGREEN.withAlpha(0.1),
-      // outline: true,
-      // outlineColor: Cesium.Color.MEDIUMSPRINGGREEN.withAlpha(0.8),
-      heightReference: true,
-    },
-  }
-
-  const boxEntity = global.$viewer.entities.add(entity)
-  global.$viewer.flyTo(boxEntity, {
-    duration: 3,
-  })
 }
 
 function onScroll (e: any) {
@@ -606,7 +664,7 @@
 }
 
 // 创建广告牌
-const createBillboard = (title: string, color: string) => {
+const createBillboard = (title: string | number, color: string) => {
   // 创建canvas绘制广告牌
   const billboard = document.createElement('canvas')
   billboard.width = 30
@@ -620,35 +678,9 @@
   ctx.fill()
   ctx.font = '18px serif'
   ctx.fillStyle = '#ffffff'
-  ctx.fillText(title, 10, 15)
+  ctx.fillText(Number(title) === 1 ? 'S' : title, 10, 15)
   ctx.closePath()
   return billboard
-}
-
-// 创建条纹
-const createStripe = () => {
-  // 创建canvas绘制广告牌
-  const stripe = document.createElement('canvas')
-  stripe.width = 40
-  stripe.height = 40
-  const ctx: HTMLCanvasElement | any = stripe.getContext('2d')
-  ctx.beginPath()
-  ctx.moveTo(0, 20)
-  ctx.lineTo(0, 40)
-  ctx.lineTo(20, 20)
-  ctx.lineTo(20, 0)
-  ctx.fillStyle = '#fff'
-  ctx.fill()
-  ctx.closePath()
-  ctx.beginPath()
-  ctx.moveTo(20, 0)
-  ctx.lineTo(20, 20)
-  ctx.lineTo(40, 40)
-  ctx.lineTo(40, 20)
-  ctx.fillStyle = '#fff'
-  ctx.fill()
-  ctx.closePath()
-  return stripe
 }
 
 /**
@@ -784,6 +816,28 @@
         color: #2d8cf0;
       }
     }
+    .wayline-info {
+      display: flex;
+      height: 50px;
+      margin: 10px 0;
+      text-align: center;
+      align-items: center;
+      .info-box {
+        flex: 1;
+        border-right: 1px solid hsla(0,0%,100%,.1);
+        .title {
+          color: hsla(0,0%,100%,.65);
+          font-size: 12px;
+          font-weight: bold;
+        }
+        .info {
+          font-weight: bold;
+        }
+        &:last-child {
+          border: 0;
+        }
+      }
+    }
 
     li {
       cursor: pointer;
@@ -882,3 +936,4 @@
   background-color: #3c3c3c;
 }
 </style>
+../../../utils/cesium/polylineImageTrailMaterial

--
Gitblit v1.9.3