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/utils/cesium/use-kmz-tsa.ts |  370 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 269 insertions(+), 101 deletions(-)

diff --git a/src/utils/cesium/use-kmz-tsa.ts b/src/utils/cesium/use-kmz-tsa.ts
index 2f49acf..d7ff54c 100644
--- a/src/utils/cesium/use-kmz-tsa.ts
+++ b/src/utils/cesium/use-kmz-tsa.ts
@@ -1,140 +1,308 @@
-import { ref, getCurrentInstance } from 'vue'
-import { analyzeKmzFile, getKmlParams, generateKmlFormat } from '/@/utils/cesium/kmz'
-import { getLngLatAltitude } from './mapUtils'
+import { ref } from 'vue'
+import { analyzeKmzFile, XMLToJSON, JSONToXML } from '/@/utils/cesium/kmz'
+import _ from 'lodash'
 import JSZIP from 'jszip'
 import { saveAs } from 'file-saver'
 
-const JsZip = new JSZIP()
-
+const fileAuthor = reactive({
+  name: '',
+  author: '',
+})
 const kmlStr = ref('')
 const kmzFile = ref<any>(null)
 
-// 点位参数
-const placemark: any = {
-  Point: {
-    coordinates: '',
+const template = ref<any>({
+  author: '',
+  createTime: '',
+  updateTime: '',
+  missionConfig: {
+    flyToWaylineMode: 'safely',
+    finishAction: 'goHome',
+    exitOnRCLost: 'goContinue',
+    executeRCLostAction: 'goBack',
+    takeOffSecurityHeight: 20,
+    takeOffRefPoint: '0.000000,0.000000,0.000000',
+    takeOffRefPointAGLHeight: 0,
+    globalTransitionalSpeed: 15,
+    globalRTHHeight: 80,
+    droneInfo: {
+      droneEnumValue: 0,
+      droneSubEnumValue: 0,
+    },
+    payloadInfo: {
+      payloadEnumValue: 0,
+      payloadSubEnumValue: 0,
+      payloadPositionIndex: 0,
+    },
   },
-  index: 0,
-  executeHeight: 80,
-  height: 80,
-  waypointSpeed: 10,
-  waypointHeadingParam: {
-    waypointHeadingMode: 'followWayline',
-    waypointHeadingAngle: 0,
-    waypointPoiPoint: '0.000000,0.000000,0.000000',
-    waypointHeadingPathMode: 'followBadArc',
-    waypointHeadingPoiIndex: 0,
+  Folder: {
+    templateType: 'waypoint',
+    useGlobalTransitionalSpeed: 0,
+    templateId: 0,
+    waylineCoordinateSysParam: {
+      coordinateMode: 'WGS84',
+      heightMode: 'EGM96',
+      globalShootHeight: 50,
+      positioningType: 'GPS',
+      surfaceFollowModeEnable: 1,
+      surfaceRelativeHeight: 100,
+    },
+    autoFlightSpeed: 7,
+    gimbalPitchMode: 'usePointSetting',
+    globalWaypointHeadingParam: {
+      waypointHeadingMode: 'followWayline',
+      waypointHeadingAngle: 0,
+      waypointPoiPoint: '0.000000,0.000000,0.000000',
+      waypointHeadingPathMode: 'followBadArc',
+    },
+    globalWaypointTurnMode: 'toPointAndStopWithDiscontinuityCurvature',
+    globalUseStraightLine: 0,
+    Placemark: [
+      {
+        Point: {
+          coordinates: '',
+        },
+        index: 0,
+        ellipsoidHeight: 0,
+        height: 0,
+        useGlobalHeight: 0,
+        useGlobalSpeed: 0,
+        useGlobalHeadingParam: 1,
+        useGlobalTurnParam: 0,
+        gimbalPitchAngle: 0,
+        actionGroup: {
+          actionGroupId: 0,
+          actionGroupStartIndex: 1,
+          actionGroupEndIndex: 1,
+          actionGroupMode: 'sequence',
+          actionTrigger: {
+            actionTriggerType: 'reachPoint',
+          },
+          action: [],
+        },
+      },
+    ],
   },
-  waypointTurnParam: {
-    waypointTurnMode: 'toPointAndStopWithDiscontinuityCurvature',
-    waypointTurnDampingDist: 0.2,
+})
+const waylines = ref<any>({
+  missionConfig: {
+    flyToWaylineMode: 'safely',
+    finishAction: 'goHome',
+    exitOnRCLost: 'goContinue',
+    executeRCLostAction: 'hover',
+    takeOffSecurityHeight: 20,
+    globalTransitionalSpeed: 10,
+    distance: 0,
+    duration: 0,
+    droneInfo: {
+      droneEnumValue: 67,
+      droneSubEnumValue: 0,
+    },
+    payloadInfo: {
+      payloadEnumValue: 52,
+      payloadSubEnumValue: 0,
+      payloadPositionIndex: 0,
+    },
   },
-  useGlobalHeight: 1,
-  useGlobalSpeed: 1,
-  useGlobalHeadingParam: 1,
-  useGlobalTurnParam: 1,
-  useStraightLine: 1,
-  actionGroup: {},
-}
+  Folder: {
+    templateId: 0,
+    executeHeightMode: 'WGS84',
+    waylineId: 0,
+    autoFlightSpeed: 10,
+    Placemark: [
+      {
+        Point: {
+          coordinates: '0.000000, 0.000000',
+        },
+        index: 0,
+        executeHeight: 116.57,
+        waypointSpeed: 10,
+        waypointHeadingParam: {
+          waypointHeadingMode: 'followWayline',
+        },
+        waypointTurnParam: {
+          waypointTurnMode: 'toPointAndStopWithDiscontinuityCurvature',
+          waypointTurnDampingDist: 0,
+        },
+        useStraightLine: 1,
+        actionGroup: [],
+      },
+    ],
+  },
+})
 
 const useKmzTsa = () => {
   const init = async (fileUrl: string, fileContent?: string) => {
     const fileRes = await analyzeKmzFile(fileUrl)
-    kmzFile.value = fileRes.file
-    const kmzRes = await fileRes.content
+    kmzFile.value = fileRes.zip
+    const kmzRes = await fileRes.fileInfoObj['wpmz/template.kml']
     if (fileContent) {
       kmlStr.value = fileContent
       return false
     }
     kmlStr.value = kmzRes
+    const tplXmlJson = XMLToJSON(kmzRes)
+    template.value = tplXmlJson.Document
     return kmzRes
   }
-
-  const create = () => {
-    const nowTime = new Date().getTime()
-    const str = `
-    <?xml version="1.0" encoding="UTF-8"?>
-    <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.5">
-      <Document>
-        <wpml:author>17304076412</wpml:author>
-        <wpml:createTime>${nowTime}</wpml:createTime>
-        <wpml:updateTime>${nowTime}</wpml:updateTime>
-        <wpml:missionConfig>
-        </wpml:missionConfig>
-        <Folder>
-        </Folder>
-      </Document>
-    </kml>
-    `
-    kmlStr.value = str
+  const create = async (waylineBasicInfo: { fileName: string; droneEnumValue: string; payloadEnumValue: string }) => {
+    try {
+      const { fileName, droneEnumValue, payloadEnumValue } = waylineBasicInfo
+      const author = window.localStorage.getItem('username') || ''
+      const createTime = new Date().getTime()
+      // 模板
+      const droneModel: { [key: string]: string } = {
+        52: '0',
+        53: '1',
+        66: '0',
+        67: '1',
+        80: '0',
+        81: '1',
+      } as const
+      const templateJson = {
+        author,
+        createTime,
+        updateTime: createTime,
+        missionConfig: {
+          flyToWaylineMode: 'safely',
+          finishAction: 'goHome',
+          exitOnRCLost: 'goContinue',
+          executeRCLostAction: 'goBack',
+          takeOffSecurityHeight: 20,
+          takeOffRefPoint: '0.000000,0.000000,0.000000',
+          takeOffRefPointAGLHeight: 0,
+          globalTransitionalSpeed: 15,
+          globalRTHHeight: 80,
+          droneInfo: {
+            droneEnumValue,
+            droneSubEnumValue: droneModel[payloadEnumValue],
+          },
+          payloadInfo: {
+            payloadEnumValue,
+            payloadSubEnumValue: droneModel[payloadEnumValue],
+            payloadPositionIndex: 0,
+          },
+        },
+        Folder: {
+          templateType: 'waypoint',
+          useGlobalTransitionalSpeed: 0,
+          templateId: 0,
+          waylineCoordinateSysParam: {
+            coordinateMode: 'WGS84',
+            heightMode: 'EGM96',
+            globalShootHeight: 50,
+            positioningType: 'GPS',
+            surfaceFollowModeEnable: 1,
+            surfaceRelativeHeight: 100,
+          },
+          autoFlightSpeed: 7,
+          gimbalPitchMode: 'usePointSetting',
+          globalWaypointHeadingParam: {
+            waypointHeadingMode: 'followWayline',
+            waypointHeadingAngle: 0,
+            waypointPoiPoint: '0.000000,0.000000,0.000000',
+            waypointHeadingPathMode: 'followBadArc',
+          },
+          globalWaypointTurnMode: 'toPointAndStopWithDiscontinuityCurvature',
+          globalUseStraightLine: 0,
+          Placemark: [],
+        },
+      }
+      template.value = templateJson
+      return true
+    } catch (error) {
+      return error
+    }
   }
-
-  // const write = (settingParmas: any = {}, name: string) => {
-  // }
-  const writePoint = (settingParmas: any = {}) => {
-    Object.keys(settingParmas).forEach((key: string) => {
-      placemark[key] = settingParmas[key]
+  const save = () => {
+    const JsZip = new JSZIP()
+    const waylines = waylinesContext(template.value)
+    const templateXml = JSONToXML(template.value, '', true)
+    const waylinesWpml = JSONToXML(waylines, '', true)
+    JsZip.file('wpmz/template.kml', templateXml)
+    JsZip.file('wpmz/waylines.wpml', waylinesWpml)
+    JsZip.generateAsync({ type: 'blob' }).then((blob) => {
+      saveAs(blob, '新建航线.kmz')
     })
-    const Placemark = `<Placemark>${generateKmlFormat(placemark)}</Placemark>`
-    const points: RegExpMatchArray = getKmlParams(kmlStr.value, false, {
-      name: 'Placemark',
-      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
   }
 
-  const del = () => {}
+  const generateXML = <T>(xmlJson: T) => {
+    return JSONToXML(xmlJson)
+  }
 
-  const edit = (settingParmas: any = {}, keyName?: string, isKeyWpml: boolean = false) => {
-    Object.keys(settingParmas).forEach((key: string) => {
-      const regxVal: any = getKmlParams(kmlStr.value, true, {
-        name: key,
-        findRegx: '([\\s\\S]*?)',
-      })
-      const str = regxVal[1]
-      if (str) {
-        if (key === 'globalHeight') {
-          const regxVal: any = getKmlParams(kmlStr.value, true, {
-            name: 'height',
-            findRegx: '([\\s\\S]*?)',
-            mode: 'g',
-          })
-          regxVal.forEach((heightStr: string) => {
-            const rstr = generateKmlFormat({ height: settingParmas[key] })
-            kmlStr.value = kmlStr.value.replace(heightStr, rstr)
-          })
-        }
-        const replaceStr = generateKmlFormat({ [key]: settingParmas[key] })
-        kmlStr.value = kmlStr.value.replace(regxVal[0], replaceStr)
+  const waylinesContext = (templateJson: any) => {
+    const waylinesObj: { [key: string]: any } = {
+      missionConfig: {
+        flyToWaylineMode: null,
+        finishAction: null,
+        exitOnRCLost: null,
+        executeRCLostAction: null,
+        takeOffSecurityHeight: null,
+        globalTransitionalSpeed: null,
+        globalRTHHeight: null,
+        droneInfo: null,
+        payloadInfo: null,
+      },
+      Folder: {
+        templateId: null,
+        executeHeightMode: null,
+        waylineId: null,
+        autoFlightSpeed: null,
+        Placemark: null,
+      },
+    }
+    Object.keys(waylinesObj).forEach((key: string) => {
+      if (Object.prototype.toString.call(waylinesObj[key]) === '[object Object]') {
+        Object.keys(waylinesObj[key]).forEach((item) => {
+          waylinesObj[key][item] = templateJson[key][item]
+          if (item === 'executeHeightMode') {
+            waylinesObj[key][item] = templateJson[key].waylineCoordinateSysParam.heightMode
+          }
+          if (item === 'waylineId') {
+            waylinesObj[key][item] = templateJson[key].templateId
+          }
+          if (item === 'Placemark') {
+            const placemarks = _.cloneDeep(templateJson[key][item])
+            placemarks.forEach(
+              (placemark: {
+                executeHeight: { '#text': string }
+                ellipsoidHeight?: { [x: string]: string }
+                height?: { [x: string]: string }
+              }) => {
+                placemark.executeHeight = { '#text': placemark.ellipsoidHeight?.['#text'] || '' }
+                delete placemark.ellipsoidHeight
+                delete placemark.height
+              },
+            )
+            waylinesObj[key][item] = placemarks
+          }
+        })
       } else {
-        console.warn('没有找到对应的属性')
+        waylinesObj[key] = templateJson[key]
       }
     })
+    return waylinesObj
   }
 
-  const save = () => {
-    JsZip.file('wpmz/template.kml', kmlStr.value)
-    kmzFile.value.file('wpmz/template.kml', kmlStr.value)
-    JsZip.generateAsync({ type: 'blob' }).then((content) => {
-      saveAs(content, '新建航线-' + new Date().toLocaleString() + '.kmz')
-    })
-  }
+  // 将wpmz/template.kml解析传来json转换回去,重新复制以便于后续绘制
+  watch(
+    () => template.value,
+    (newobj) => {
+      const xmlString = JSONToXML(newobj)
+      kmlStr.value = xmlString
+    },
+    {
+      deep: true,
+    },
+  )
 
   return {
     init,
     create,
-    // write,
-    writePoint,
-    del,
-    edit,
     save,
+    generateXML,
   }
 }
 
-export { kmlStr }
+export { kmlStr, fileAuthor, template, waylines }
 export default useKmzTsa

--
Gitblit v1.9.3