From aec00ecc093be803860c8675cbe1c4c776a7cb4e Mon Sep 17 00:00:00 2001
From: GuLiMmo <2820890765@qq.com>
Date: Tue, 19 Mar 2024 17:49:21 +0800
Subject: [PATCH] update: 新建航线、事件编辑、kmz文件问题修改

---
 src/pages/page-web/projects/components/route-edit/index.vue |  743 +++++++++++++++++++++-----------------------------------
 1 files changed, 279 insertions(+), 464 deletions(-)

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 0d6b76a..b9955d6 100644
--- a/src/pages/page-web/projects/components/route-edit/index.vue
+++ b/src/pages/page-web/projects/components/route-edit/index.vue
@@ -1,20 +1,34 @@
 <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>
-      <setting>
+        <a-button type="text" @click="backPage">
+          <template #icon>
+            <ArrowLeftOutlined />
+          </template>
+          返回
+        </a-button>
+      </a-popover>
+      <div class="save-button" @click="saveWaylineFile">
+        <SaveOutlined />
+      </div>
+      <setting v-model:loadCompleted="loadCompleted">
         <template #show>
           <a-button type="text" class="setting-btn">
             <div class="router-setting">
-              <img
-                class="wayline-icon"
-                :src="getResource('wayline.png')"
-                alt="icon" />
+              <img class="wayline-icon" :src="getResource('wayline.png')" alt="icon" />
               <span class="text">航线设置</span>
               <CaretDownOutlined />
             </div>
@@ -23,10 +37,7 @@
       </setting>
     </div>
     <div class="wayline-info">
-      <div
-        class="info-box"
-        v-for="(item, index) in waylineDetails"
-        :key="index">
+      <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>
@@ -37,50 +48,51 @@
         :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>
-        <div class="graph-right">
-          <div
-            v-for="(event, index) in item.eventList"
-            :key="index"
-            class="s-event-icon">
-            <a-tooltip placement="top">
-              <template #title>
-                {{ event.name }}
-              </template>
-              <img :src="event.icon" alt="icon" />
-            </a-tooltip>
+        <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>
-        </div>
+        </a-tooltip>
+        <contextMenu :menu="[{ title: '删除航点', value: { index, item } }]">
+          <div class="graph-right">
+            <div v-for="(event, index) in item.eventList" :key="index" class="s-event-icon">
+              <a-tooltip placement="top">
+                <template #title>
+                  {{ event.name }}
+                </template>
+                <img :src="event.icon" alt="icon" />
+              </a-tooltip>
+            </div>
+          </div>
+        </contextMenu>
       </li>
     </ul>
   </div>
 </template>
 
 <script setup lang="ts">
-import _, { divide } from 'lodash'
+import _ from 'lodash'
 import * as Cesium from 'cesium'
 import setting from './components/setting.vue'
-import { ref, reactive, defineEmits, defineProps, watch, onMounted } from 'vue'
-import { ArrowLeftOutlined, CaretDownOutlined } from '@ant-design/icons-vue'
+import useKmzTsa, { kmlStr, template as xmlTemplate } from '/@/utils/cesium/use-kmz-tsa'
+import { ref, defineEmits, defineProps, watch, onMounted } from 'vue'
+import { ArrowLeftOutlined, CaretDownOutlined, SaveOutlined } from '@ant-design/icons-vue'
 import { cesiumOperation } from '/@/hooks/use-cesium-tsa'
 import { useMyStore } from '/@/store'
-import { analyzeKmzFile, getKmlParams } from '/@/utils/cesium/kmz'
-import ImageTrailMaterial from '/@/utils/cesium/ImageTrailMaterial'
-import { getPolylineLength } from '/@/utils/cesium/mapUtils'
+import useMapDraw, { kmlEntities as globalEntities, selectPointIndex as pointIdx } from '/@/utils/cesium/use-map-draw'
+import contextMenu from './components/content-menu.vue'
 const store = useMyStore()
 const { appContext }: any = getCurrentInstance()
 const global = appContext.config.globalProperties
 
-const {
-  removeAllPoint,
-  getEntityById,
-  addPolyline,
-  addRightClick,
-  removeRightClickEvent,
-} = cesiumOperation()
+const kmzUtils = useKmzTsa()
+
+const { removeAllPoint, getEntityById, addPolyline, removeAllDataSource, addRightClick, removeRightClickEvent } =
+  cesiumOperation()
 
 interface waylineDetails {
   title: string
@@ -95,6 +107,7 @@
 
 interface tragetPoint {
   position: Cesium.Cartesian3
+  isUseGlobalHeight: boolean
   eventList: eventParmas[]
 }
 
@@ -102,160 +115,31 @@
   return new URL(`/src/assets/icons/${name}`, import.meta.url).href
 }
 
+const ellipsoid = global.$viewer.scene.globe.ellipsoid
+
 const emits = defineEmits(['backFn'])
 const props = defineProps<{
-  details: any
+  isCreateWayline: boolean
 }>()
 
 const filePath = computed(() => store.state.waylineTool.kmzPath)
 
-// 对应事件
-const eventList = reactive<eventParmas[]>([
-  {
-    key: 'takePhoto',
-    name: '单拍',
-    icon: getResource('waylinetool/camera.png'),
-  },
-  {
-    key: 'startRecord',
-    name: '开始录像',
-    icon: getResource('waylinetool/camera-on.png'),
-  },
-  {
-    key: 'stopRecord',
-    name: '结束录像',
-    icon: getResource('waylinetool/camera-off.png'),
-  },
-  {
-    key: 'time',
-    name: '开始等时间隔拍照',
-    icon: getResource('waylinetool/shoot1.png'),
-  },
-  {
-    key: 'distance',
-    name: '开始等距间隔拍照',
-    icon: getResource('waylinetool/shoot2.png'),
-  },
-  {
-    key: 'zoom',
-    name: '变焦',
-    icon: getResource('waylinetool/fd.png'),
-  },
-  {
-    key: 'customDirName',
-    name: '创建新文件夹',
-    icon: getResource('waylinetool/create-file.png'),
-  },
-  {
-    key: 'gimbalRotate',
-    distinguish: 'Yaw',
-    name: '云台俯仰角',
-    icon: getResource('waylinetool/holderyaw.png'),
-  },
-  {
-    key: 'gimbalYawRotate',
-    name: '云台偏航角',
-    distinguish: 'pitch',
-    icon: getResource('waylinetool/holdertilt.png'),
-  },
-  {
-    key: 'rotateYaw',
-    name: '飞行器偏航',
-    icon: getResource('waylinetool/droneyaw.png'),
-  },
-  {
-    key: 'hover',
-    name: '悬停等待',
-    icon: getResource('waylinetool/xt.png'),
-  },
-])
-
 const tragetPointArr = ref<tragetPoint[]>([])
 
-let kmlDataSource:
-  | { entities: { values: { _children: any }[] }; show: boolean }
-  | null
-  | any = null
+let kmlDataSource: { entities: { values: { _children: any }[] }; show: boolean } | null | any = null
 
 let mouseRightClickEvent: any = null
 
-// 初始化KML,判断当中存在多少事件
-const initKML = () => {
-  analyzeKmzFile(filePath.value).then((kmlRes) => {
-    // 所有航点
-    const points = getKmlParams(kmlRes, false, {
-      name: 'Placemark',
-      findRegx: '([\\s\\S]*?)',
-      mode: 'g',
-    })
-    points?.forEach((point: string, index: number) => {
-      // 当前点位事件
-      const pointActions = getKmlParams(point, true, {
-        name: 'actionGroup',
-        findRegx: '([\\s\\S]*?)',
-        mode: 'g',
-      })
-      const eventArr: eventParmas[] = []
-      if (pointActions) {
-        const actions =
-          getKmlParams(pointActions[0], true, {
-            name: 'action',
-            findRegx: '([\\s\\S]*?)',
-            mode: 'g',
-          }) || []
-        actions?.forEach((action) => {
-          eventList.forEach((event: any) => {
-            if (!event.distinguish) {
-              action.includes(event.key) && eventArr.push(event)
-            } else {
-              const pitchAngle =
-                getKmlParams(action, true, {
-                  name: 'gimbalPitchRotateAngle',
-                  findRegx: '([\\s\\S]*?)',
-                }) || []
-              const yawAngle =
-                getKmlParams(action, true, {
-                  name: 'gimbalYawRotateAngle',
-                  findRegx: '([\\s\\S]*?)',
-                }) || []
-              if (!!Number(pitchAngle[1]) && event.distinguish === 'pitch') {
-                eventArr.push(event)
-              }
-              if (!!Number(yawAngle[1]) && event.distinguish === 'yaw') {
-                eventArr.push(event)
-              }
-            }
-          })
-          // 判断一共有多少个拍照模式
-          const actionFunc = getKmlParams(point, true, {
-            name: 'actionActuatorFunc',
-            findRegx: 'takePhoto',
-            mode: 'g',
-          })
-          if (actionFunc) {
-            ;(waylineDetails[3] as any).value++
-          }
-        })
-        tragetPointArr.value[index].eventList = eventArr
-      }
-      // 获取当前是否存在拍照模式
-      const pointShootMode = getKmlParams(point, true, {
-        name: 'shootType',
-        findRegx: '([\\s\\S]*?)',
-        mode: 'g',
-      })
-      if (pointShootMode) {
-        pointShootMode.forEach((type: string) => {
-          eventList.forEach((item: any) => {
-            type.includes(item.key) && eventArr.push(item)
-          })
-        })
-      }
-    })
-  })
-}
-
 // 绘制地图上的东西
+let mapDraw: any = null
+// 航线详情
+const waylineDetails = ref<waylineDetails[]>([])
+// 样式
+const kmlEntities = ref<Cesium.Entity[]>([])
+
+const loadCompleted = ref<boolean>(false)
+
+// 编辑时初始化
 const initDrawRoute = () => {
   const options = {
     camera: global.$viewer.scene.camera,
@@ -265,200 +149,46 @@
   if (kmlDataSource) {
     global.$viewer.dataSources.remove(kmlDataSource)
   }
-  global.$viewer.dataSources
-    .add(Cesium.KmlDataSource.load(filePath.value, options))
-    .then((res: any) => {
-      kmlDataSource = res
-      createMapMarker(kmlDataSource)
-      initKML()
-      if (!mouseRightClickEvent) {
-        // 添加右键事件
-        addMapPointEvent()
-      }
+  global.$viewer.dataSources.add(Cesium.KmlDataSource.load(filePath.value, options)).then((res: any) => {
+    kmlDataSource = res
+    mapDraw = useMapDraw(kmlDataSource, [], filePath.value, global)
+    const {
+      drawWayline,
+      waylineDetails: details,
+      waylinePointsEvent,
+      kmlEntities: entities,
+      clearWaylineData,
+    } = mapDraw
+    clearWaylineData()
+    drawWayline()
+    kmzUtils.init(filePath.value).then((kmlRes) => {
+      loadCompleted.value = true
     })
-}
-
-const kmlEntity = ref<any>([])
-const waylineDetails = reactive<
-  {
-    title: string
-    value: string | number
-  }[]
->([
-  {
-    title: '航线长度',
-    value: '0',
-  },
-  {
-    title: '预计执行时间',
-    value: '0',
-  },
-  {
-    title: '航点',
-    value: 0,
-  },
-  {
-    title: '照片',
-    value: 0,
-  },
-])
-// 样式
-const kmlEntities = ref<Cesium.Entity[]>([])
-const ellipsoid = global.$viewer.scene.globe.ellipsoid
-const createMapMarker = async (
-  dataSource:
-    | {
-        entities: { values: { _children: any }[] }
-        show: boolean
-      }
-    | any,
-  entitiesList: Cesium.Entity[] = [],
-) => {
-  dataSource.show = false
-  let kmlEntityArr = [...entitiesList]
-  // kmlEntity.value = dataSource.entities.values
-  if (dataSource) {
-    kmlEntityArr = dataSource.entities.values[0]._children
-    kmlEntities.value = kmlEntityArr
-  }
-  const cartesianArr: any[] = []
-  let btmStartPoint = null
-  // 获取所有的点位
-  const kmlRes = await analyzeKmzFile(filePath.value)
-  // 所有航点
-  const points: string[] | any = getKmlParams(kmlRes, false, {
-    name: 'Placemark',
-    findRegx: '([\\s\\S]*?)',
-    mode: 'g',
-  })
-  // 获取当前航线全局速度
-  const getGlobalSpeed: any = getKmlParams(kmlRes, true, {
-    name: 'autoFlightSpeed',
-    findRegx: '([\\s\\S]*?)',
-  })
-  const speed = Number(getGlobalSpeed[1])
-  // 修改点位样式信息等
-  for (let i = 0; i < kmlEntityArr.length; i++) {
-    const entity: any = 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 point = points[i]
-    const getPointHeight: any = getKmlParams(point, true, {
-      name: 'ellipsoidHeight',
-      findRegx: '([\\s\\S]*?)',
-    })
-    const getHaeHeight: any = getKmlParams(point, true, {
-      name: 'height',
-      findRegx: '([\\s\\S]*?)',
-    })
-    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 billboard = createBillboard(`${i + 1}`, '#61d396')
-    // 修改id
-    entity._id = 'tragetPoint' + i
-    // 修改广告牌样式
-    entity.billboard = new Cesium.BillboardGraphics({
-      image: billboard,
-      pixelOffset: new Cesium.Cartesian2(0, -20),
-    })
-    entity.label = new Cesium.LabelGraphics({
-      text: `ASL:${Math.round(AslHeight)}m\nHAE:${Math.round(HeaHeight)}m`,
-      font: '13px monospace',
-      showBackground: true,
-      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
-      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
-      disableDepthTestDistance: Number.POSITIVE_INFINITY,
-      pixelOffset: new Cesium.Cartesian2(0, -40),
-    })
-    // 修改点的信息
-    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,
-          AslHeight,
-          longitude,
-          latitude,
-          0,
-        ]),
-        width: 1,
-        material: new Cesium.PolylineDashMaterialProperty({
-          color: Cesium.Color.WHITE,
-        }),
+    waylineDetails.value = details
+    tragetPointArr.value = waylinePointsEvent.value
+    watch(
+      () => waylinePointsEvent.value,
+      (val) => {
+        tragetPointArr.value = val
       },
-    })
-    // 获取虚线中心点
-    cartesianArr.push(entity.position._value)
-    tragetPointArr.value[i] = {
-      position: entity.position._value,
-      eventList: [],
+      {
+        deep: true,
+      },
+    )
+
+    kmlEntities.value = entities.value
+    if (!mouseRightClickEvent) {
+      // 添加右键事件
+      addMapPointEvent()
     }
-  }
-  // 创建起飞位置
-  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, // 关闭贴地效果,保留高度
-    },
-  })
-  dataSource.show = true
-  const lineEntity = getEntityById('entityLine')
-  // 获取距离
-  const polylineLength: any = getPolylineLength(lineEntity).toFixed(1) || 0
-  waylineDetails[0].value = polylineLength + 'm'
-  // 航点数
-  waylineDetails[2].value = cartesianArr.length
-  // 计算时间
-  const sportTime = polylineLength / speed
-  // 判断有没有超过一分钟
-  const time = sportTime / 60
-  waylineDetails[1].value =
-    Math.trunc(time) + ' m ' + Math.round((time % 1) * 60) + ' s'
-  global.$viewer.flyTo(lineEntity, {
-    offset: new Cesium.HeadingPitchRange(0, -90, 300),
   })
 }
-
-// const createPointOrPolyline = () => {}
+// 新建航线初始化
+const initCreateRoute = () => {
+  mapDraw = useMapDraw('', [], '', global)
+  const xml = kmzUtils.generateXML(xmlTemplate.value)
+  mapDraw.drawWayline([], xml)
+}
 
 // 创建广告牌
 const createBillboard = (title: string | number, color: string) => {
@@ -492,8 +222,10 @@
     global.$viewer.entities.remove(nextPointEntity)
     kmlEntities.value.forEach((entity: Cesium.Entity | any, i: number) => {
       entity.billboard.image = createBillboard(i + 1, '#61d396')
+      entity.label.show = false
     })
     selectPointIndex.value = null
+    pointIdx.value = null
     return
   }
   if (prevPointEntity) {
@@ -509,12 +241,7 @@
   const nextPoint = points[index + 1]?.position
   if (prevPoint) {
     // 获取中心点
-    const centerPoint = Cesium.Cartesian3.lerp(
-      currentPoint,
-      prevPoint,
-      0.5,
-      new Cesium.Cartesian3(),
-    )
+    const centerPoint = Cesium.Cartesian3.lerp(currentPoint, prevPoint, 0.5, new Cesium.Cartesian3())
     // 获取两个点之间的距离
     let distance = Cesium.Cartesian3.distance(currentPoint, prevPoint)
     distance = Math.round(distance)
@@ -522,12 +249,7 @@
   }
   if (nextPoint) {
     // 获取中心点
-    const centerPoint = Cesium.Cartesian3.lerp(
-      currentPoint,
-      nextPoint,
-      0.5,
-      new Cesium.Cartesian3(),
-    )
+    const centerPoint = Cesium.Cartesian3.lerp(currentPoint, nextPoint, 0.5, new Cesium.Cartesian3())
     // 获取两个点之间的距离
     let distance = Cesium.Cartesian3.distance(currentPoint, nextPoint)
     distance = Math.round(distance)
@@ -537,11 +259,22 @@
   kmlEntities.value.forEach((entity: Cesium.Entity | any, i: number) => {
     if (i === index) {
       entity.billboard.image = createBillboard(index + 1, '#f3be4f')
+      const dashLineEntity: Cesium.Entity | any = getEntityById(`dashLine${i}`)
+      dashLineEntity.polyline.material = new Cesium.PolylineDashMaterialProperty({
+        color: Cesium.Color.fromBytes(235, 192, 99),
+      })
+      entity.label.show = true
     } else {
       entity.billboard.image = createBillboard(i + 1, '#61d396')
+      const dashLineEntity: Cesium.Entity | any = getEntityById(`dashLine${i}`)
+      dashLineEntity.polyline.material = new Cesium.PolylineDashMaterialProperty({
+        color: Cesium.Color.WHITE,
+      })
+      entity.label.show = false
     }
   })
   selectPointIndex.value = index
+  pointIdx.value = index
 }
 
 // 添加右键事件,弹出窗口
@@ -561,16 +294,11 @@
       },
       {
         class: 'add-next-point',
-        title: `在${Number(selectPointIndex.value) + 1}号航点前插入`,
+        title: `在${Number(selectPointIndex.value) + 1}号航点后插入`,
       },
     ]
-    const defaultEvents = [
-      { class: 'finally-point', title: '在最后航点新增航点' },
-    ]
-    const events =
-      selectPointIndex.value !== null
-        ? [...defaultEvents, ...pointEvents]
-        : defaultEvents
+    const defaultEvents = [{ class: 'finally-point', title: '在最后航点新增航点' }]
+    const events = selectPointIndex.value !== null ? [...defaultEvents, ...pointEvents] : defaultEvents
     popupDom = createPointPopupDom(events)
     global.$viewer.container.appendChild(popupDom)
     popupDom.style.transform = `translate3d(${x}px, ${y}px, 0)`
@@ -620,87 +348,90 @@
   `
   return pointPopup
 }
+
 // 给DOM添加点击事件
 const addMenuEvent = (dom: HTMLElement, position: Cesium.Cartesian2) => {
   dom.addEventListener('click', (e: any) => {
     removeCesiumChildDom(popupDom)
     const className = e.target.className
-    const c3Position = global.$viewer.scene.globe.pick(
-      global.$viewer.camera.getPickRay(position),
-      global.$viewer.scene,
-    )
+    const c3Position = global.$viewer.scene.globe.pick(global.$viewer.camera.getPickRay(position), global.$viewer.scene)
     const c2Postion = ellipsoid.cartesianToCartographic(c3Position)
     const longitude = Cesium.Math.toDegrees(c2Postion.longitude)
     const latitude = Cesium.Math.toDegrees(c2Postion.latitude)
-    const height = 70
-    const createPointPosition = Cesium.Cartesian3.fromDegrees(
-      longitude,
-      latitude,
-      height,
-    )
-    let entity: Cesium.Entity | any = null
+    // 获取全局高度
+    const globalHeight: string = xmlTemplate.value.Folder.globalHeight['#text']
+    const height = Number(globalHeight)
+    // 右键点击的位置
+    const createPointPosition = Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
+    const entity: Cesium.Entity = global.$viewer.entities.add({
+      position: createPointPosition,
+    })
+    // 起飞点海拔
+    const takeOffRefPointAGLHeight = xmlTemplate.value.missionConfig.takeOffRefPointAGLHeight
+    const posterHeight = Number(takeOffRefPointAGLHeight['#text'])
+    // 当前点位个数
+    const points = xmlTemplate.value.Folder.Placemark
+    // 加入到解析的JSON对象中
+    const setting = {
+      Point: {
+        coordinates: { '#text': `${longitude},${latitude}` },
+      },
+      index: { '#text': points.length },
+      ellipsoidHeight: { '#text': height - posterHeight },
+      height: { '#text': height },
+      useGlobalHeadingParam: { '#text': 1 },
+      useGlobalHeight: { '#text': 1 },
+      useGlobalSpeed: { '#text': 1 },
+      useGlobalTurnParam: { '#text': 1 },
+      useStraightLine: { '#text': 1 },
+      waypointHeadingParam: {
+        waypointHeadingAngle: { '#text': 0 },
+        waypointHeadingMode: { '#text': 'followWayline' },
+        waypointHeadingPathMode: { '#text': 'followBadArc' },
+        waypointHeadingPoiIndex: { '#text': 0 },
+        waypointPoiPoint: { '#text': '0.000000,0.000000,0.000000' },
+      },
+      waypointSpeed: { '#text': 10 },
+      waypointTurnParam: {
+        waypointTurnDampingDist: { '#text': 0.2 },
+        waypointTurnMode: { '#text': 'toPointAndStopWithDiscontinuityCurvature' },
+      },
+      isRisky: { '#text': 0 },
+    }
     if (className === 'finally-point') {
-      entity = global.$viewer.entities.add({
-        position: createPointPosition,
-        label: {
-          text: 'ASL:70m',
-          font: '13px monospace',
-          showBackground: true,
-          horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
-          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
-          disableDepthTestDistance: Number.POSITIVE_INFINITY,
-          pixelOffset: new Cesium.Cartesian2(0, -40),
-        },
-        billboard: {
-          image: createBillboard(tragetPointArr.value.length + 1, '#61d396'),
-          pixelOffset: new Cesium.Cartesian2(0, -20),
-        },
-        point: {
-          pixelSize: 20,
-          color: Cesium.Color.GHOSTWHITE,
-          outlineColor: Cesium.Color.BLACK,
-        },
-      })
-      const prePostion =
-        tragetPointArr.value[tragetPointArr.value.length - 1].position
-      const polylinePositions = [prePostion, createPointPosition]
-      addPolyline({
-        polyline: {
-          positions: polylinePositions,
-          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, // 关闭贴地效果,保留高度
-        },
-      })
-      addPolyline({
-        polyline: {
-          positions: Cesium.Cartesian3.fromDegreesArrayHeights([
-            longitude,
-            latitude,
-            height,
-            longitude,
-            latitude,
-            0,
-          ]),
-          width: 1,
-          material: new Cesium.PolylineDashMaterialProperty({
-            color: Cesium.Color.WHITE,
-          }),
-        },
-      })
+      globalEntities.value.push(entity)
+      xmlTemplate.value.Folder.Placemark.push(setting)
       tragetPointArr.value.push({
         position: createPointPosition,
         eventList: [],
+        isUseGlobalHeight: Boolean(setting.useGlobalHeight['#text']),
       })
     }
-    // clearCesiumMap()
-    // createMapMarker(undefined, [...kmlEntities.value, entity])
+    if (className === 'add-prev-point') {
+      globalEntities.value.splice(selectPointIndex.value, 0, entity)
+      xmlTemplate.value.Folder.Placemark.splice(selectPointIndex.value, 0, setting)
+      tragetPointArr.value.splice(selectPointIndex.value, 0, {
+        position: createPointPosition,
+        eventList: [],
+        isUseGlobalHeight: Boolean(setting.useGlobalHeight['#text']),
+      })
+    }
+    if (className === 'add-next-point') {
+      const index = _.cloneDeep(selectPointIndex.value + 1)
+      globalEntities.value.splice(index, 0, entity)
+      xmlTemplate.value.Folder.Placemark.splice(index, 0, setting)
+      tragetPointArr.value.splice(index, 0, {
+        position: createPointPosition,
+        eventList: [],
+        isUseGlobalHeight: Boolean(setting.useGlobalHeight['#text']),
+      })
+    }
+    // 更新点位序号
+    xmlTemplate.value.Folder.Placemark.forEach((placemark: { index: { [x: string]: number } }, index: number) => {
+      placemark.index['#text'] = index
+    })
+    const xmlStr = kmzUtils.generateXML(xmlTemplate.value)
+    mapDraw.drawWayline(globalEntities.value, xmlStr)
   })
 }
 
@@ -712,8 +443,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 = () => {
@@ -727,10 +475,35 @@
   }
 }
 
+// 保存文件
+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(() => {
   // 清空画布
   clearCesiumMap()
-  initDrawRoute()
+  console.log(!!filePath.value)
+  if (filePath.value) {
+    initDrawRoute()
+  } else {
+    initCreateRoute()
+  }
 })
 
 onUnmounted(() => {
@@ -756,9 +529,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;
@@ -810,6 +622,7 @@
     padding: 0;
     height: calc(100vh - 180px);
     overflow: auto;
+
     li {
       cursor: pointer;
       padding: 10px 0;
@@ -835,7 +648,7 @@
       }
 
       .graph-right {
-        width: calc(100% - 40px);
+        width: 100%;
         height: 30px;
         border-bottom: 1px solid #4f4f4f;
         display: flex;
@@ -860,8 +673,10 @@
     }
   }
 }
+
 .active-point {
   background-color: #3c3c3c;
+
   .graph {
     .left {
       border-top-color: #f3bf4e !important;

--
Gitblit v1.9.3