From 2d829de89f7e4f8d55dd5784bf9dbd91a70751ef Mon Sep 17 00:00:00 2001
From: jihongshun <1151753686@qq.com>
Date: 星期三, 13 八月 2025 13:18:57 +0800
Subject: [PATCH] 点击树飞到不同的视角

---
 src/views/system/shootPoint/components/shootPointDialog.vue |   77 ++++++++++++++++++
 src/utils/components/init-map.vue                           |  113 +++++++++++++++++++++++----
 2 files changed, 170 insertions(+), 20 deletions(-)

diff --git a/src/utils/components/init-map.vue b/src/utils/components/init-map.vue
index e77392c..824117e 100644
--- a/src/utils/components/init-map.vue
+++ b/src/utils/components/init-map.vue
@@ -30,8 +30,9 @@
       
     </div>
     <div class="zoom-info">
-      <el-tag type="success">鍊嶇巼: {{ zoomRatio.toFixed(1) }}X</el-tag>
-      <el-tag type="success">璺濈: {{ betweenDistance.toFixed(1) }}绫�</el-tag>
+        <el-tag type="success">鍊嶇巼: {{ zoomRatio.toFixed(1) }}X</el-tag><br>
+        <el-tag type="success">璺濈: {{ betweenDistance.toFixed(1) }}绫�</el-tag><br>
+        <el-tag type="success">P: {{ cameraP.toFixed(1) }}&nbsp;&nbsp;T: {{ cameraT.toFixed(1) }} </el-tag>
     </div>
     
     
@@ -174,7 +175,9 @@
           28: '28X',
           56: '56X'
         },
-        betweenDistance:0
+        betweenDistance:0,
+        cameraP:0.0,
+        cameraT:0.0
     }
   },
   mounted(){
@@ -410,8 +413,8 @@
                 setTimeout(() => {
                   viewerC.camera.changed.addEventListener(_this.onCameraChange)
                 }, 100);
-                
-
+                //宸︿晶鏍戠粨鏋勮仈鍔�
+                _this.dealTree()
                 //缁撴潫鍙抽敭鐩戝惉
                 createPinHandler.destroy();
                 //缁撴潫涓诲浘鑱斿姩楣扮溂鐩戝惉
@@ -518,6 +521,7 @@
       }
     },
     onKeyUp(event) {
+      console.log()
       //閿洏鎶捣杩涜鏇存柊宸︿晶绌轰腑鐐筽in
       //鑾峰彇鍙充晶鐩告満
       if(rightKeyMove){
@@ -545,17 +549,19 @@
         }
         //璁$畻涓や釜鐐硅窛绂�
         console.log(viewerM.entities)
-           const groupEntityGround = viewerM.entities.getById("groundPoiId"+(counter-1));
-           const groupPosition  = groupEntityGround.position.getValue(Cesium.JulianDate.now());
-           if (groupPosition) {
-              const cartographic = Cesium.Cartographic.fromCartesian(groupPosition);
-              const longitude = Cesium.Math.toDegrees(cartographic.longitude);
-              const latitude = Cesium.Math.toDegrees(cartographic.latitude);
-              const point1 = Cesium.Cartesian3.fromDegrees(lon, lat);
-              const point2 = Cesium.Cartesian3.fromDegrees(longitude, latitude);
-              const gure = Cesium.Cartesian3.distance(point1, point2)
-              this.betweenDistance  = gure
-          }
+        const groupEntityGround = viewerM.entities.getById("groundPoiId"+(counter-1));
+        const groupPosition  = groupEntityGround.position.getValue(Cesium.JulianDate.now());
+        if (groupPosition) {
+            const cartographic = Cesium.Cartographic.fromCartesian(groupPosition);
+            const longitude = Cesium.Math.toDegrees(cartographic.longitude);
+            const latitude = Cesium.Math.toDegrees(cartographic.latitude);
+            const point1 = Cesium.Cartesian3.fromDegrees(lon, lat);
+            const point2 = Cesium.Cartesian3.fromDegrees(longitude, latitude);
+            const gure = Cesium.Cartesian3.distance(point1, point2)
+            this.betweenDistance  = gure
+        }
+        
+        this.dealTree()
       }
       const key = event.key;
       const lower = key.toLowerCase();
@@ -721,6 +727,44 @@
     resetView() {
       // Fly back to the initial view (home) in 1 second
       viewerC.camera.flyHome(1.0);
+    },
+    dealTree(){
+      let allEntities = viewerM.entities.values; // 鎵�鏈夊疄浣撳璞$粍鎴愮殑鏁扮粍
+      const grouped = {};
+      //鎵�鏈夊疄浣撳璞$粍鎴愮殑鏁扮粍杞崲鎴愬乏渚ф爲闇�瑕佺殑鏍煎紡
+      allEntities.forEach(item => {
+        const match = item.id.match(/(groundPoiId|aerialPoiId)(\d+)/);
+        if (match) {
+          const type = match[1]; // groundPoiId or aerialPoiId
+          const index = match[2];
+          if (!grouped[index]) grouped[index] = {};
+          grouped[index][type] = item.position;
+        }
+      })
+      const result = Object.keys(grouped).map((key, idx) => {
+        const group = grouped[key];
+        const positionGround = group.groundPoiId.getValue(Cesium.JulianDate.now())
+        const positionAerialPo = group.aerialPoiId.getValue(Cesium.JulianDate.now())
+        const groundPos = Cesium.Cartographic.fromCartesian(positionGround);
+        const aerialPos = Cesium.Cartographic.fromCartesian(positionAerialPo);
+        return {
+          id: this.genId(),
+          label: `鍦伴潰鐐�${idx}`,
+          longitude: Cesium.Math.toDegrees(groundPos.longitude),
+          latitude: Cesium.Math.toDegrees(groundPos.latitude),
+          height: groundPos.height,
+          children: [
+            {
+              id: this.genId(),
+              label: `绌轰腑鐐�${idx}`,
+              longitude: Cesium.Math.toDegrees(aerialPos.longitude),
+              latitude: Cesium.Math.toDegrees(aerialPos.latitude),
+              height: aerialPos.height
+            }
+          ]
+        };
+      });
+      this.$emit('dealTreeData',result)
     },
     mergePoint(){
       let allEntities = viewerM.entities.values; // 鎵�鏈夊疄浣撳璞$粍鎴愮殑鏁扮粍
@@ -996,7 +1040,40 @@
     },
     onSliderInput(val) {
       this.zoomRatio = val;
-    }
+    },
+    // 璁$畻 heading锛堝亸鑸锛�
+    computeHeading(fromCartesian, toCartesian) {
+      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
+      const direction = Cesium.Cartesian3.subtract(
+        toCartesian,
+        fromCartesian,
+        new Cesium.Cartesian3()
+      );
+      const directionLocal = Cesium.Matrix4.multiplyByPointAsVector(
+        Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()),
+        direction,
+        new Cesium.Cartesian3()
+      );
+      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
+      return Math.atan2(directionLocal.x, directionLocal.y);
+    },
+
+    // 璁$畻 pitch锛堜刊浠拌锛�
+    computePitch(fromCartesian, toCartesian) {
+      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
+      const direction = Cesium.Cartesian3.subtract(
+        toCartesian,
+        fromCartesian,
+        new Cesium.Cartesian3()
+      );
+      const directionLocal = Cesium.Matrix4.multiplyByPointAsVector(
+        Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()),
+        direction,
+        new Cesium.Cartesian3()
+      );
+      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
+      return Math.asin(directionLocal.z); // z杞村悜涓�
+    },
   }
 }
 </script>
@@ -1047,7 +1124,7 @@
 }
 .moveResult{position:absolute;z-index:2;background-color:rgba(47,53,60,1);padding:0 5px;right:50%;bottom:30px;
     border:1px solid rgba(255,255,255,.1);box-sizing:content-box;width:220px;height:30px;font-size:14px;text-align:center}
-.cammoveResult{position:absolute;z-index:2;background-color:rgba(47,53,60,1);padding:0 5px;right:calc(50% - 40px);bottom:30px;
+.cammoveResult{position:absolute;z-index:2;background-color:rgba(47,53,60,1);padding:0 5px;right:calc(50% - 140px);bottom:35px;
     border:1px solid rgba(255,255,255,.1);box-sizing:content-box;width:400px;height:30px;font-size:14px;text-align:center}
 .moveResultCon{margin-top:4px}
 .cammoveResultCon{margin-top:4px;color: white;}
diff --git a/src/views/system/shootPoint/components/shootPointDialog.vue b/src/views/system/shootPoint/components/shootPointDialog.vue
index f19feac..127462d 100644
--- a/src/views/system/shootPoint/components/shootPointDialog.vue
+++ b/src/views/system/shootPoint/components/shootPointDialog.vue
@@ -33,13 +33,14 @@
                     :allow-drop="allowDrop"
                     @node-drop="handleDrop"
                     default-expand-all
+                    @node-click="handleNodeClick"
                     ref="tree">
                   </el-tree>
                 </div>
               </el-card>
           </el-col>
           <el-col :span="20">
-              <InitMap v-if="showMap" @mergePoint="mergePoint" :towerUrl="towerUrl"  :deviceData="deviceData"></InitMap>
+              <InitMap v-if="showMap" @mergePoint="mergePoint" :towerUrl="towerUrl"  :deviceData="deviceData"  @dealTreeData="dealTreeData"></InitMap>
           </el-col>
       </el-row>
       <span slot="footer" class="dialog-footer">
@@ -113,6 +114,78 @@
     }
   },  
   methods:{
+   // 璁$畻 heading锛堝亸鑸锛�
+    computeHeading(fromCartesian, toCartesian) {
+      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
+      const direction = Cesium.Cartesian3.subtract(
+        toCartesian,
+        fromCartesian,
+        new Cesium.Cartesian3()
+      );
+      const directionLocal = Cesium.Matrix4.multiplyByPointAsVector(
+        Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()),
+        direction,
+        new Cesium.Cartesian3()
+      );
+      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
+      return Math.atan2(directionLocal.x, directionLocal.y);
+    },
+
+    // 璁$畻 pitch锛堜刊浠拌锛�
+    computePitch(fromCartesian, toCartesian) {
+      const transform = Cesium.Transforms.eastNorthUpToFixedFrame(fromCartesian);
+      const direction = Cesium.Cartesian3.subtract(
+        toCartesian,
+        fromCartesian,
+        new Cesium.Cartesian3()
+      );
+      const directionLocal = Cesium.Matrix4.multiplyByPointAsVector(
+        Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4()),
+        direction,
+        new Cesium.Cartesian3()
+      );
+      Cesium.Cartesian3.normalize(directionLocal, directionLocal);
+      return Math.asin(directionLocal.z); // z杞村悜涓�
+    },
+
+    // 椋炲埌 from 鐪嬪悜 to
+    flyToAndLookAt(from, to) {
+      const fromCartesian = Cesium.Cartesian3.fromDegrees(from[0], from[1], from[2]);
+      const toCartesian = Cesium.Cartesian3.fromDegrees(to[0], to[1], to[2]);
+
+      const heading = this.computeHeading(fromCartesian, toCartesian);
+      const pitch = this.computePitch(fromCartesian, toCartesian);
+      let viewer = window.viewerM
+      viewer.camera.flyTo({
+        destination: fromCartesian,
+        orientation: {
+          heading: heading,
+          pitch: pitch,
+          roll: 0.0
+        },
+        duration: 3
+      });
+    },
+    handleNodeClick(data,node) {
+      console.log(data);
+      console.log(node)
+      if(data.children && data.children.length >0) {
+        //鐐瑰嚮鐖剁骇
+        const from = [data.children[0].longitude,data.children[0].latitude, data.children[0].height];
+        const to = [data.longitude,data.latitude, data.height];      
+        this.flyToAndLookAt(from, to);
+      } else  {
+        //鐐瑰嚮瀛愮骇
+        const from = [data.longitude,data.latitude, data.height]; 
+        const to = [node.parent?.data?.longitude,node.parent?.data?.latitude, node.parent?.data?.height]; 
+        this.flyToAndLookAt(from, to);
+      }
+      
+    },
+    dealTreeData(arrList){
+      this.treeData = arrList
+      console.log(arrList)
+    },
     convertToTree(data) {
       return data.map((item, index) => {
         const parentId = 'air_' + index;
@@ -266,7 +339,7 @@
         const ground = item
         const air = item.children[0]
 
-        // 鍦伴潰鐐瑰埌绌轰腑鐐� 鈥� 鐧借壊铏氱嚎
+        // 鍦伴潰鐐瑰埌7绌轰腑鐐� 鈥� 鐧借壊铏氱嚎
         viewer.entities.add({
           polyline: {
             positions: Cesium.Cartesian3.fromDegreesArrayHeights([

--
Gitblit v1.9.3