Browse Source

多无人机飞行、航路预警特效

zhiyuan-007 3 months ago
parent
commit
4452a882c1

BIN
public/imgs/serviceBackground.png


+ 237 - 5
src/components/mapJK.vue

@@ -54,6 +54,7 @@ import {
   getRiverPointInterface,
   getRoadPointInterface
 } from "../service/http.js";
+import FeaturePointsPlottingEvent from "../units/map/FeaturePointsPlottingEvent.js";
 
 export default {
   name: "mapJK",
@@ -83,6 +84,7 @@ export default {
     let draw_GeometryMeshPrismEffectEvent = null;
     let symbolPathPipeEvent = null;
     let symbolPointCubeEvent = null;
+    let featurePointsPlottingEvent = null;
     onMounted(() =>{
       bus.on('CreateMap',() =>{
         MapReady = $.Deferred();
@@ -184,12 +186,21 @@ export default {
           case "ShowNoFlyThreeCubeByInterface":
             showNoFlyThreeCubeByInterface(params);
             break;
+          case "ShowNoFlyThreeCubeDetailByInterface":
+            showNoFlyThreeCubeDetailByInterface(params);
+            break;
           case "ShowRoadThreeCubeByInterface":
             showRoadThreeCubeByInterface(params);
             break;
+          case "ShowRoadThreeCubeDetailByInterface":
+            showRoadThreeCubeDetailByInterface(params);
+            break;
           case "ShowRiverThreeCubeByInterface":
             showRiverThreeCubeByInterface(params);
             break;
+          case "ShowRiverThreeCubeDetailByInterface":
+            showRiverThreeCubeDetailByInterface(params);
+            break;
           case "ShowThreeNet":
             showThreeNet(params);
             break;
@@ -220,8 +231,8 @@ export default {
           case "SymbolPointCube":
             symbolPointCube(params);
             break;
-          case "PathPlan":
-            pathPlan(params);
+          case "FeaturePointsPlotting":
+            featurePointsPlotting(params);
             break;
         }
       }
@@ -513,6 +524,14 @@ export default {
           return
         }
         let size = params.size;
+        debugger
+        // addThreeCubeDetailEvent = new AddThreeCubeDetailEvent({
+        //   view: m_view,
+        //   points:params.points,
+        //   size,
+        // });
+        // addThreeCubeDetailEvent.start();
+
         size = {
           x:52.892217808770056,
           y:61.6164010837756,
@@ -525,6 +544,9 @@ export default {
           scrollId: "",
         }).then(res =>{
           debugger
+          res.data.data.list.forEach(item =>{
+            item.color = [0,0,1]
+          })
           // 初始化 AddThreeCubeEvent,暂时不启动
           addThreeCubeDetailEvent = new AddThreeCubeDetailEvent({
             view: m_view,
@@ -557,6 +579,36 @@ export default {
         getAllBuildingPoints(level);
       }
 
+      function showNoFlyThreeCubeDetailByInterface(params){
+        let status = params.status;
+        let size = params.size;
+        if(addThreeCubeEvent){
+          addThreeCubeEvent.clear();
+          addThreeCubeEvent = null;
+        }
+        if(status == "hide"){
+          return
+        }
+        let level = params.level;
+        getNoFlyPointInterface({
+          x: m_view.camera.position.x,
+          y: m_view.camera.position.y,
+          level: level,
+          scrollId: "",
+        }).then(res =>{
+          res.data.data.list.forEach(item =>{
+            item.color = [1,0,0]
+          })
+          // 初始化 AddThreeCubeEvent,暂时不启动
+          addThreeCubeDetailEvent = new AddThreeCubeDetailEvent({
+            view: m_view,
+            points:res.data.data.list,
+            size,
+          });
+          addThreeCubeDetailEvent.start();
+        })
+      }
+
       function showNoFlyThreeCubeByInterface(params){
         let status = params.status;
         let size = params.size;
@@ -599,6 +651,37 @@ export default {
         getRoadPoint(level);
       }
 
+      function showRoadThreeCubeDetailByInterface(params){
+        let status = params.status;
+        let size = params.size;
+        if(addThreeCubeEvent){
+          addThreeCubeEvent.clear();
+          addThreeCubeEvent = null;
+        }
+        if(status == "hide"){
+          return
+        }
+        let level = params.level;
+        getRoadPointInterface({
+          x: m_view.camera.position.x,
+          y: m_view.camera.position.y,
+          level: level,
+          scrollId: "",
+        }).then(res =>{
+          res.data.data.list.forEach(item =>{
+            item.color = [0,0,1]
+          })
+          // 初始化 AddThreeCubeEvent,暂时不启动
+          addThreeCubeDetailEvent = new AddThreeCubeDetailEvent({
+            view: m_view,
+            points:res.data.data.list,
+            size,
+          });
+          addThreeCubeDetailEvent.start();
+        })
+      }
+
+
       function showRiverThreeCubeByInterface(params){
         let status = params.status;
         let size = params.size;
@@ -620,6 +703,37 @@ export default {
         getRiverPoint(level);
       }
 
+      function showRiverThreeCubeDetailByInterface(params){
+        let status = params.status;
+        let size = params.size;
+        if(addThreeCubeEvent){
+          addThreeCubeEvent.clear();
+          addThreeCubeEvent = null;
+        }
+        if(status == "hide"){
+          return
+        }
+        let level = params.level;
+        getRiverPointInterface({
+          x: m_view.camera.position.x,
+          y: m_view.camera.position.y,
+          level: level,
+          scrollId: "",
+        }).then(res =>{
+          res.data.data.list.forEach(item =>{
+            item.color = [1,1,0]
+          })
+          // 初始化 AddThreeCubeEvent,暂时不启动
+          addThreeCubeDetailEvent = new AddThreeCubeDetailEvent({
+            view: m_view,
+            points:res.data.data.list,
+            size,
+          });
+          addThreeCubeDetailEvent.start();
+        })
+      }
+
+
       function showThreeNet(params){
         let status = params.status;
         debugger
@@ -1043,7 +1157,7 @@ export default {
         let flyGLTFEvent = new FlyGLTFEvent({
           view:m_view,
           path:params.paths,
-          speed:0.0001
+          speed:params.speed
         })
         flyGLTFEvent.start();
         if(params.isFollow){
@@ -1051,6 +1165,112 @@ export default {
         }
         // 保存实例
         flyGLTFInstances[id] = flyGLTFEvent;
+        flyCollision()
+      }
+
+      function flyCollision(){
+        // 每秒检查一次所有飞行实例的碰撞
+        setInterval(monitorUAVsCollision, 1000);
+      }
+
+      function monitorUAVsCollision() {
+        const threshold = 100;  // 设置预警阈值,单位为米(或其他合适的单位)
+        const keys = Object.keys(flyGLTFInstances);  // 获取所有飞行实例的 ID
+
+        // 遍历所有飞行实例
+        for (let i = 0; i < keys.length; i++) {
+          for (let j = i + 1; j < keys.length; j++) {
+            const instance1 = flyGLTFInstances[keys[i]];
+            const instance2 = flyGLTFInstances[keys[j]];
+
+            // 调用 checkForCollision 判断两个无人机之间的距离
+            checkForCollision(instance1, instance2, threshold);
+          }
+        }
+      }
+
+      // 计算两个无人机之间的距离,并返回是否需要预警
+      function checkForCollision(instance1, instance2, threshold) {
+        const position1 = instance1.flyGLTFEvent.getCurrentPositionAndDirection()?.position;
+        const position2 = instance2.flyGLTFEvent.getCurrentPositionAndDirection()?.position;
+        if (position1 && position2) {
+          // 计算两个位置之间的距离
+          const distance = position1.distanceTo(position2);
+          // 如果距离小于预设的阈值,进行预警
+          if (distance < threshold) {
+            console.warn(`Collision warning! Distance between UAVs is too small: ${distance}`);
+            // 控制悬停
+            if(instance1.speed >= instance2.speed){
+              if (!instance1.flyGLTFEvent.isHovering) {
+                instance1.flyGLTFEvent.setHovering(true);
+                instance1.flyGLTFEvent.setPanelType("warning_conflict");
+                pathPipe({
+                  "id":"warning_conflict",
+                  "status":"show",
+                  "paths": [
+                    [
+                      instance1.flyGLTFEvent.getCurrentPositionAndDirection().currentSegment.start,
+                      instance1.flyGLTFEvent.getCurrentPositionAndDirection().currentSegment.end
+                    ],
+                    [
+                      instance2.flyGLTFEvent.getCurrentPositionAndDirection().currentSegment.start,
+                      instance2.flyGLTFEvent.getCurrentPositionAndDirection().currentSegment.end
+                    ],
+                  ],
+                  "color": "#ff0000",
+                  "intensity": 2,
+                  "pipeRadius": 8
+                })
+
+                console.log(`Instance ${instance1.id} is now hovering.`);
+              }
+            }else{
+              if (!instance2.flyGLTFEvent.isHovering) {
+                instance2.flyGLTFEvent.setHovering(true);
+                instance2.flyGLTFEvent.setPanelType("warning_conflict");
+                pathPipe({
+                  "id":"warning_conflict",
+                  "status":"show",
+                  "paths": [
+                    [
+                      instance1.flyGLTFEvent.getCurrentPositionAndDirection().currentSegment.start,
+                      instance1.flyGLTFEvent.getCurrentPositionAndDirection().currentSegment.end
+                    ],
+                    [
+                      instance2.flyGLTFEvent.getCurrentPositionAndDirection().currentSegment.start,
+                      instance2.flyGLTFEvent.getCurrentPositionAndDirection().currentSegment.end
+                    ]
+                  ],
+                  "color": "#ff0000",
+                  "intensity": 2,
+                  "pipeRadius": 8
+                })
+                console.log(`Instance ${instance2.id} is now hovering.`);
+              }
+            }
+            return true;  // 需要预警
+          }else {
+            // 如果距离恢复到安全范围,恢复飞行
+            if (instance1.flyGLTFEvent.isHovering) {
+              instance1.flyGLTFEvent.setHovering(false);
+              instance1.flyGLTFEvent.setPanelType("");
+              pathPipe({
+                "id":"warning_conflict",
+                "status":"hide"
+              })
+            }
+
+            if (instance2.flyGLTFEvent.isHovering) {
+              instance2.flyGLTFEvent.setHovering(false);
+              instance2.flyGLTFEvent.setPanelType("");
+              pathPipe({
+                "id":"warning_conflict",
+                "status":"hide"
+              })
+            }
+            return false;
+          }
+        }
       }
 
       //需要添加初始路径(手动绘制和自动绘制)结果
@@ -1185,8 +1405,20 @@ export default {
         })
         m_map.add(symbolPointCubeEvent.graphicsLayer);
       }
-      function pathPlan(params){
-
+      function featurePointsPlotting(params){
+        let status = params.status;
+        let f_layer = m_map.layers.find(item => item.id === "featurePointsPlottingEvent");
+        if (f_layer) {
+          m_map.remove(f_layer);
+        }
+        if(status == "hide"){
+          return
+        }
+        featurePointsPlottingEvent = new FeaturePointsPlottingEvent({
+          view:m_view,
+          data:params.data
+        })
+        m_map.add(featurePointsPlottingEvent.featureLayer);
       }
     })
   }

+ 168 - 108
src/config/basicTool.json

@@ -647,117 +647,113 @@
             "status": "show",
             "paths": [
               [
-                [4399.5433631362393, 7370.3376136757433,0],
-                [4399.5433631362393, 7370.3376136757433,100],
-                [4307.0713031925261, 7251.5063864272088,100],
-                [4207.5877708923072, 7308.6565007288009,100],
-                [4050.9541242914274, 7308.6565007288009,100],
-                [3661.4866786887869, 7162.6062086299062,100],
-                [2960.8686107881367, 6910.7223715279251,100],
-                [2910.0685091875494, 6045.003973422572,100],
-                [2793.651609685272, 5721.1533257234842,100],
-                [2793.651609685272, 5721.1533257234842,0]
-              ],
-              [
-                [4399.5433631362393, 7370.3376136757433,0],
-                [4399.5433631362393, 7370.3376136757433,100],
-                [4307.0713031925261, 7251.5063864272088,100],
-                [4207.5877708923072, 7308.6565007288009,100],
-                [4050.9541242914274, 7308.6565007288009,100],
-                [3661.4866786887869, 7162.6062086299062,100],
-                [3113.2689155880362, 7162.6062086299062,100],
-                [3113.2689155880362, 7162.6062086299062,0]
-              ],
-              [
-                [4399.5433631362393, 7370.3376136757433,0],
-                [4399.5433631362393, 7370.3376136757433,100],
-                [4307.0713031925261, 7251.5063864272088,100],
-                [4207.5877708923072, 7308.6565007288009,100],
-                [4050.9541242914274, 7308.6565007288009,100],
-                [3661.4866786887869, 7162.6062086299062,100],
-                [3542.9531082902104, 7171.0728922281414,100],
-                [3352.6202267482877, 7543.2479691505432,100],
-                [2515.309386334382, 7247.2730446271598,100],
-                [2481.4426519349217, 7477.9901727326214,100],
-                [2481.4426519349217, 7477.9901727326214,0]
-              ],
-              [
-                [4399.5433631362393, 7370.3376136757433,0],
-                [4399.5433631362393, 7370.3376136757433,100],
-                [4307.0713031925261, 7251.5063864272088,100],
-                [4207.5877708923072, 7308.6565007288009,100],
-                [4050.9541242914274, 7308.6565007288009,100],
-                [3661.4866786887869, 7162.6062086299062,100],
-                [3542.9531082902104, 7171.0728922281414,100],
-                [3352.6202267482877, 7543.2479691505432,100],
-                [3084.568078446202, 8067.3945490997285,100],
-                [2648.6596530349925, 8013.507910432294,100],
-                [2648.6596530349925, 8013.507910432294,0]
-              ],
-              [
-                [4399.5433631362393, 7370.3376136757433,0],
-                [4399.5433631362393, 7370.3376136757433,100],
-                [4307.0713031925261, 7251.5063864272088,100],
-                [4207.5877708923072, 7308.6565007288009,100],
-                [4050.9541242914274, 7308.6565007288009,100],
-                [3661.4866786887869, 7162.6062086299062,100],
-                [3542.9531082902104, 7171.0728922281414,100],
-                [2973.5686361864209, 8284.441785633564,100],
-                [3316.469321988523, 8288.6751274317503,100],
-                [3316.469321988523, 8417.7920523341745,100],
-                [3316.469321988523, 8417.7920523341745,0]
-              ],
-              [
-                [4399.5433631362393, 7370.3376136757433,0],
-                [4399.5433631362393, 7370.3376136757433,100],
-                [4673.2553688948974, 7064.3463766910136,100],
-                [4946.3059149952605, 5978.4942049868405,100],
-                [5183.24076386448, 5030.0933498516679,100],
-                [5095.9280892377719, 4891.1868220418692,100],
-                [5508.6789147406816, 4220.4667305964977,100],
-                [5508.6789147406816, 4220.4667305964977,0]
+                [
+                  1769.8633262562475,
+                  6572.564675574498,
+                  20
+                ],
+                [
+                  2756.9351097344656,
+                  6887.815844159343,
+                  20
+                ],
+                [
+                  3553.4220013809545,
+                  7144.302605554526,
+                  20
+                ],
+                [
+                  4195.333062471143,
+                  7282.346450536933,
+                  20
+                ],
+                [
+                  4418.0873970261955,
+                  7366.562145019624,
+                  20
+                ]
               ],
+
               [
-                [4399.5433631362393, 7370.3376136757433,0],
-                [4399.5433631362393, 7370.3376136757433,100],
-                [4645.6063552629203, 7362.4000978022814,100],
-                [5751.5669005159289, 7709.0049576759338,100],
-                [6475.7329321820289, 7954.5387820750475,100],
-                [6469.3829194819555, 8229.7059990745038,100],
-                [7199.6343799848109, 8585.3067102786154,100],
-                [7504.4349895855412, 9167.3912077825516,100],
-                [7280.0678741866723, 9861.6592629849911,100],
-                [7280.0678741866723, 9861.6592629849911,0]
+                [
+                  4418.0873970261955,
+                  7366.562145019624,
+                  20
+                ],
+                [
+                  4216.2063372552475,
+                  7476.772779201592,
+                  20
+                ],
+                [
+                  4000.1051314666856,
+                  7862.190076553913,
+                  20
+                ],
+                [
+                  4550.636695788306,
+                  8027.788532685085,
+                  20
+                ],
+                [
+                  5329.235851407364,
+                  8224.316966379089,
+                  20
+                ]
               ],
+
               [
-                [5533.4394958499997, 6674.1814939699998,0],
-                [5533.4394958499997, 6674.1814939699998,100],
-                [5565.1395865100003, 6664.3312929399999,100],
-                [5771.0319604699998, 7084.9363842700004,100],
-                [5747.4897482899996, 7181.6602556999997,100],
-                [5775.4378630900001, 7452.3969179300002,100],
-                [5773.1627494000004, 7551.3616085399999,100],
-                [5756.9613519900004, 7714.4921131499996,100],
-                [5090.5727929900004, 7511.65297938,100],
-                [4777.61920852, 7378.2719266800004,100],
-                [4445.5372873599999, 7295.6718325900001,100],
-                [4413.6341138199996, 7361.9600904199997,100],
-                [4413.6341138199996, 7361.9600904199997,0]
+                [
+                  4418.0873970261955,
+                  7366.562145019624,
+                  20
+                ],
+                [
+                  4771.708118894013,
+                  7462.639779987219,
+                  20
+                ],
+                [
+                  5764.530516218645,
+                  7702.099502136613,
+                  20
+                ],
+                [
+                  6432.013986271386,
+                  7944.898603135224,
+                  20
+                ]
               ],
+
               [
-                [4419.4892839994282, 7361.3196348026395,0],
-                [4419.4892839994282, 7361.3196348026395,100],
-                [4722.4523340091109, 7353.5317879915237,100],
-                [5082.947024250403, 7512.1369348522276,100],
-                [5757.1514683701098, 7714.9800673611462,100],
-                [5775.1619675792754, 7551.3184095919132,100],
-                [5774.801678430289, 7449.5138318110257,100],
-                [5737.2197882905602, 7127.4370903726667,100],
-                [5591.3118801191449, 6784.3444970101118,100],
-                [5542.6769579108804, 6669.9844871591777,100],
-                [5533.4394958522171, 6674.1814939714968,100],
-                [5533.4394958522171, 6674.1814939714968,0]
+                [
+                  4418.0873970261955,
+                  7366.562145019624,
+                  20
+                ],
+                [
+                  4336.414376322606,
+                  7217.395252181261,
+                  20
+                ],
+                [
+                  4693.4407023310205,
+                  7217.395252181261,
+                  20
+                ],
+                [
+                  5091.982163883947,
+                  5243.920635745127,
+                  20
+                ],
+                [
+                  5513.141935058761,
+                  4203.903681498108,
+                  20
+                ]
               ]
+
+
             ],
             "color": "#438EDB",
             "intensity": 1.2,
@@ -1140,13 +1136,77 @@
       },
       {
         "code": "1-27",
-        "title": "航线规划",
+        "title": "要素三维标绘展示",
         "data": {
-          "ActionName": "pathPlan",
+          "ActionName": "FeaturePointsPlotting",
           "Parameters": {
             "status":"show",
-            "start": [4761.0851582425681,7580.2866520466015,22.27126711830264],
-            "end": [4452.8073415461002,6785.643477679952,19.200584820232107],
+            "data": [
+              {
+                "geometry": { "type": "point", "x": 1769.8633262562475, "y": 6572.564675574498, "z": 100 },
+                "attributes": { "name": "邯郸路50弄小区" }
+              },
+              {
+                "geometry": { "type": "point", "x": 2756.9351097344656, "y": 6887.815844159343, "z": 100 },
+                "attributes": { "name": "复旦大学地铁站" }
+              },
+              {
+                "geometry": { "type": "point", "x": 3553.4220013809545, "y": 7144.302605554526, "z": 100 },
+                "attributes": { "name": "复旦大学邯郸校区新闻学院" }
+              },
+              {
+                "geometry": { "type": "point", "x": 4195.333062471143, "y": 7282.346450536933, "z": 100 },
+                "attributes": { "name": "五角场广场" }
+              },
+              {
+                "geometry": { "type": "point", "x": 4216.2063372552475, "y": 7476.772779201592, "z": 100 },
+                "attributes": { "name": "百联又一城" }
+              },
+              {
+                "geometry": { "type": "point", "x": 4418.0873970261955, "y": 7366.562145019624, "z": 100 },
+                "attributes": { "name": "合生汇" }
+              },
+              {
+                "geometry": { "type": "point", "x": 4771.708118894013,   "y": 7462.639779987219, "z": 100 },
+                "attributes": { "name": "创智汇" }
+              },
+              {
+                "geometry": { "type": "point", "x": 4336.414376322606,   "y": 7217.395252181261, "z": 100 },
+                "attributes": { "name": "上海蓝天宾馆" }
+              },
+              {
+                "geometry": { "type": "point", "x": 4693.4407023310205, "y": 6334.889815920942, "z": 100 },
+                "attributes": { "name": "东方蓝海国际市场" }
+              },
+              {
+                "geometry": { "type": "point", "x": 5091.982163883947, "y": 5243.920635745127, "z": 100 },
+                "attributes": { "name": "东方名园" }
+              },
+              {
+                "geometry": { "type": "point", "x": 5513.141935058761,  "y":  4203.903681498108, "z": 100 },
+                "attributes": { "name": "互联宝地" }
+              },
+              {
+                "geometry": { "type": "point", "x": 4000.1051314666856,  "y":  7862.190076553913, "z": 100 },
+                "attributes": { "name": "江湾体育场" }
+              },
+              {
+                "geometry": { "type": "point", "x": 4550.636695788306,  "y": 8027.788532685085, "z": 100 },
+                "attributes": { "name": "国和路111弄" }
+              },
+              {
+                "geometry": { "type": "point", "x": 5329.235851407364, "y": 8224.316966379089, "z": 100 },
+                "attributes": { "name": "长海医院" }
+              },
+              {
+                "geometry": { "type": "point", "x": 5764.530516218645,  "y":  7702.099502136613, "z": 100 },
+                "attributes": { "name": "翔殷路地铁站" }
+              },
+              {
+                "geometry": { "type": "point", "x": 6432.013986271386,   "y":  7944.898603135224, "z": 100 },
+                "attributes": { "name": "上海市杨浦区翔殷路小学" }
+              }
+            ],
             "token": ""
           }
         }

+ 35 - 11
src/config/path_wjc.json

@@ -1,6 +1,7 @@
 {
   "paths": [
     [
+      [4419.489318848587573, 7361.319702150300145,0],
       [4419.489318848587573, 7361.319702150300145,100],
       [4704.115814720280468, 7354.00326712988317,100],
       [4711.547131120068116, 7354.09625567812509,100],
@@ -60,10 +61,12 @@
       [5540.817572981998637, 6671.046502827093718,100],
       [5540.31996950933717, 6671.120897745196999,100],
       [5539.840452029369771, 6671.27323554828763,100],
-      [5533.439514162018895, 6674.181518556550145,100]
+      [5533.439514162018895, 6674.181518556550145,100],
+      [5533.439514162018895, 6674.181518556550145,0]
     ],
     [
-      [4413.634094239212573, 7361.9600830078125,100],
+      [4419.489318848587573, 7361.319702150300145,0],
+      [4419.489318848587573, 7361.319702150300145,100],
       [4440.628520872443914, 7305.871281059458852,100],
       [4441.587364636549864, 7303.981341094533491,100],
       [4442.836056168890536, 7302.26902573454754,100],
@@ -154,9 +157,12 @@
       [5562.837753988529585, 6665.33377076096258,100],
       [5562.040285940494869, 6665.373988832970099,100],
       [5561.258674209006131, 6665.537255125120282,100],
-      [5533.439514162018895, 6674.181518556550145,100]
+      [5533.439514162018895, 6674.181518556550145,100],
+      [5533.439514162018895, 6674.181518556550145,0]
     ],
     [
+      [4419.489318848587573, 7361.319702150300145,0],
+      [4419.489318848587573, 7361.319702150300145,100],
       [4399.543273926712573, 7370.33770751953125,100],
       [4316.211759079247713, 7263.252496955916286,100],
       [4313.843196840844939, 7261.098550887661986,100],
@@ -221,10 +227,12 @@
       [3312.519946857574723, 8305.015433667740581,100],
       [3314.847587716082671, 8309.642801559793952,100],
       [3316.469299318268895, 8314.562201630324125,100],
-      [3316.469299318268895, 8417.7921142578125,100]
+      [3316.469299318268895, 8417.7921142578125,100],
+      [3316.469299318268895, 8417.7921142578125,0]
     ],
     [
-      [4399.543273926712573, 7370.33770751953125,100],
+      [4419.489318848587573, 7361.319702150300145,0],
+      [4419.489318848587573, 7361.319702150300145,100],
       [4316.211759079247713, 7263.252496955916286,100],
       [4313.843196840844939, 7261.098550887661986,100],
       [4311.146941152790532, 7259.372348116615285,100],
@@ -282,9 +290,12 @@
       [2514.502198761084401, 7275.467839036521582,100],
       [2511.769026707299417, 7280.132271038943145,100],
       [2509.74997640773654, 7285.147307556122541,100],
-      [2481.442687989212573, 7477.99029541015625,100]
+      [2481.442687989212573, 7477.99029541015625,100],
+      [2481.442687989212573, 7477.99029541015625,0]
     ],
     [
+      [4419.489318848587573, 7361.319702150300145,0],
+      [4419.489318848587573, 7361.319702150300145,100],
       [4399.543273926712573, 7370.33770751953125,100],
       [4316.211759079247713, 7263.252496955916286,100],
       [4313.843196840844939, 7261.098550887661986,100],
@@ -329,9 +340,12 @@
       [3081.088601509524324, 8065.500029994547731,100],
       [3078.546986584031401, 8066.122770212048636,100],
       [3075.938225262798369, 8066.327651096507907,100],
-      [2648.65972900390625, 8013.50787353888154,100]
+      [2648.65972900390625, 8013.50787353888154,100],
+      [2648.65972900390625, 8013.50787353888154,0]
     ],
     [
+      [4419.489318848587573, 7361.319702150300145,0],
+      [4419.489318848587573, 7361.319702150300145,100],
       [4399.543273926712573, 7370.33770751953125,100],
       [4316.211759079247713, 7263.252496955916286,100],
       [4313.843196840844939, 7261.098550887661986,100],
@@ -361,9 +375,12 @@
       [3656.81304232403636, 7162.542566860094666,100],
       [3648.68920649215579, 7162.6063232421875,100],
       [3565.252685451880097, 7162.6063232421875,100],
-      [3113.2689208984375, 7162.6063232421875,100]
+      [3113.2689208984375, 7162.6063232421875,100],
+      [3113.2689208984375, 7162.6063232421875,0]
     ],
     [
+      [4419.489318848587573, 7361.319702150300145,0],
+      [4419.489318848587573, 7361.319702150300145,100],
       [4399.543273926712573, 7370.33770751953125,100],
       [4316.211759079247713, 7263.252496955916286,100],
       [4313.843196840844939, 7261.098550887661986,100],
@@ -404,9 +421,12 @@
       [2909.360137603164731, 6044.712665068498609,100],
       [2907.906521337412414, 6039.060592910912419,100],
       [2905.954818332567811, 6033.560613337904215,100],
-      [2793.651672364212573, 5721.1533203125,100]
+      [2793.651672364212573, 5721.1533203125,100],
+      [2793.651672364212573, 5721.1533203125,0]
     ],
     [
+      [4419.489318848587573, 7361.319702150300145,0],
+      [4419.489318848587573, 7361.319702150300145,100],
       [4399.543273926712573, 7370.33770751953125,100],
       [4670.371411686763167, 7067.570698944851756,100],
       [4672.054418364539742, 7065.689214615151286,100],
@@ -432,9 +452,12 @@
       [5098.939820901202438, 4888.29471562636536,100],
       [5099.582769022455977, 4885.883918648804865,100],
       [5100.594886223785579, 4883.603361014276743,100],
-      [5508.678894043900073, 4220.46667480841279,100]
+      [5508.678894043900073, 4220.46667480841279,100],
+      [5508.678894043900073, 4220.46667480841279,0]
     ],
     [
+      [4419.489318848587573, 7361.319702150300145,0],
+      [4419.489318848587573, 7361.319702150300145,100],
       [4399.543273926712573, 7370.33770751953125,100],
       [4630.909630109556019, 7362.874184112995863,100],
       [4637.891792459201497, 7362.897450161080087,100],
@@ -475,7 +498,8 @@
       [7497.457411866615075, 9181.290383171020949,100],
       [7496.556498814165025, 9189.085724982456668,100],
       [7494.942344881594181, 9196.765145882964134,100],
-      [7280.067871094681323, 9861.6593017578125,100]
+      [7280.067871094681323, 9861.6593017578125,100],
+      [7280.067871094681323, 9861.6593017578125,0]
     ]
   ]
 }

+ 87 - 0
src/units/map/FeaturePointsPlottingEvent.js

@@ -0,0 +1,87 @@
+import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
+import Graphic from "@arcgis/core/Graphic.js";
+import levelFrIcon from "../../assets/三维_点.png";
+import Point from "@arcgis/core/geometry/Point.js";
+
+class FeaturePointsPlottingEvent {
+    constructor(options) {
+        this.view = options.view;
+        this.data = options.data;
+        this.featureLayer = null;
+        this.add();
+    }
+    add(){
+        let resultPointGraphics = [];
+        this.data.forEach((item) =>{
+            debugger
+            let point = new Point({
+                type: "point", // autocasts as new Point()
+                x: item.geometry.x,
+                y: item.geometry.y,
+                z: item.geometry.z,
+                spatialReference: this.view.spatialReference
+            })
+            let graphic = new Graphic({
+                geometry: point,
+                attributes: item.attributes
+            });
+            resultPointGraphics.push(graphic);
+        })
+        this.featureLayer = new FeatureLayer({
+            id: "featurePointsPlottingEvent",
+            title: "点位标绘",
+            source: resultPointGraphics, // 数据源
+            objectIdField: "ObjectID", // 必须字段,定义唯一标识
+            fields: [
+                { name: "ObjectID", type: "oid" },
+                { name: "name", type: "string" }
+            ],
+            renderer:{
+                type: "simple", // autocasts as new ClassBreaksRenderer()
+                symbol: {
+                    type: "point-3d",
+                    symbolLayers: [
+                        {
+                            type: "icon",
+                            resource: {
+                                href: levelFrIcon
+                            },
+                            size: 100,
+                            outline: {
+                                color: "white",
+                                size: 2
+                            }
+                        }
+                    ]
+                },
+            },
+            elevationInfo: { mode: "relative-to-ground" }, // 相对于地面高度
+            labelingInfo: [{
+                labelExpressionInfo: {
+                    value: "{name}"
+                },
+                labelPlacement: "always-horizontal", //"always-horizontal"center-center
+                symbol: {
+                    type: "label-3d", // autocasts as new LabelSymbol3D()
+                    symbolLayers: [
+                        {
+                            type: "text", // autocasts as new TextSymbol3DLayer()
+                            material: {
+                                color: "#ff6a00" //[0, 240, 255,1]
+                            },
+                            font: {  // autocasts as new Font()
+                                size: 12,
+                                //family: "Josefin Slab",
+                                weight: "bold"
+                            },
+                        }
+                    ]
+                }
+            }]
+        });
+    }
+    clear(){
+        this.featureLayer.removeAll();
+    }
+}
+export default FeaturePointsPlottingEvent;

+ 4 - 0
src/units/map/FlyGLTFEvent.js

@@ -30,6 +30,10 @@ class FlyGLTFEvent{
             _camera : null
         })
     }
+    pause(){
+
+    }
+
     clear(){
         if(this.flyGLTFEvent){
             this.flyGLTFEvent.destroy();

+ 176 - 10
src/units/threejs/flyGLTF.js

@@ -61,16 +61,117 @@ export const FlyGLTFClass = {
     loadGLTF(){
         const loader = new GLTFLoader();
         let that = this;
-        loader.load('public/gltf/wrj.glb',function (gltf){
-            gltf.scene.scale.set(0.2,0.2,0.2);
+        loader.load('public/gltf/wrj.glb', function (gltf) {
+            gltf.scene.scale.set(0.2, 0.2, 0.2);
             that.scene.add(gltf.scene);
             that.targetObject = gltf.scene;
 
+            // 添加动画
             that.mixer = new THREE.AnimationMixer(gltf.scene);
             const AnimationAction = that.mixer.clipAction(gltf.animations[0]);
             AnimationAction.play();
-        })
+
+            // 创建信息面板
+            const panelGeometry = new THREE.PlaneGeometry(150, 160); // 面板大小
+            const canvas = document.createElement('canvas');
+            const context = canvas.getContext('2d');
+            // 加载背景图片
+            const backgroundImage = new Image();
+            backgroundImage.src = 'public/imgs/serviceBackground.png'; // 替换为你的图片路径
+            backgroundImage.onload = () => {
+                // 确保背景透明
+                context.clearRect(0, 0, canvas.width, canvas.height); // 清除所有内容,包含黑色
+                context.fillStyle = 'rgba(0, 0, 0, 0)'; // 设置透明背景
+                context.fillRect(0, 0, canvas.width, canvas.height); // 填充透明背景
+
+                context.save();
+                context.scale(-1, 1);
+                context.translate(-canvas.width, 0);
+                // 绘制背景图片,填满整个 canvas
+                context.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
+
+                // 绘制文字信息
+                context.fillStyle = '#fff';
+                context.font = '15px Arial';
+                context.fillText('无人机信息:',40, 25);
+                context.fillText('无人机名称: 无人机1号', 40, 50);
+                context.fillText('所属企业: 美团', 40, 70);
+                context.fillText('速度: 100km/h', 40, 90);
+                context.fillText('高度: 200m', 40, 110);
+                context.fillText('状态: 正常',40, 130);
+                // 标记纹理需要更新
+                texture.needsUpdate = true;
+            };
+
+            const texture = new THREE.CanvasTexture(canvas);
+            const panelMaterial = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide,  transparent: true });
+            const panelMesh = new THREE.Mesh(panelGeometry, panelMaterial);
+
+            // 将面板附加到无人机模型
+            panelMesh.position.set(0, 100, 0); // 调整面板位置到无人机上方
+            gltf.scene.add(panelMesh);
+
+            // 保存信息面板,以便更新
+            that.infoPanel = { canvas, context, texture, mesh: panelMesh };
+        });
+
+    },
+
+    // 设置悬停状态
+    setPanelType(panelType) {
+        this.panelType = panelType;
     },
+    // 更新面板信息
+    updateInfoPanel() {
+        if (this.infoPanel) {
+            const { canvas, context, texture } = this.infoPanel;
+            // 加载背景图片
+            const backgroundImage = new Image();
+            let typeInfo = "";
+            switch (this.panelType){
+                case "warning_conflict":
+                    backgroundImage.src = 'public/imgs/warningBackground.png'; // 替换为你的图片路径
+                    typeInfo = "碰撞检测"
+                    break;
+                case "warning_lowbattery":
+                    backgroundImage.src = 'public/imgs/warningBackground.png'; // 替换为你的图片路径
+                    typeInfo = "电池电量低"
+                    break;
+                case "warning_outofrange":
+                    backgroundImage.src = 'public/imgs/warningBackground.png'; // 替换为你的图片路径
+                    typeInfo = "偏移航线"
+                    break;
+                default:
+                    backgroundImage.src = 'public/imgs/serviceBackground.png'; // 替换为你的图片路径
+                    typeInfo = "正常"
+                    break;
+            }
+
+            // backgroundImage.src = 'public/imgs/serviceBackground.png'; // 替换为你的图片路径
+            backgroundImage.onload = () => {
+                // 确保背景透明
+                context.clearRect(0, 0, canvas.width, canvas.height); // 清除所有内容,包含黑色
+                context.fillStyle = 'rgba(0, 0, 0, 0)'; // 设置透明背景
+                context.fillRect(0, 0, canvas.width, canvas.height); // 填充透明背景
+
+                // 绘制背景图片,填满整个 canvas
+                context.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
+
+                // 绘制文字信息
+                context.fillStyle = '#fff';
+                context.font = '15x Arial';
+                context.fillText('无人机信息:',40, 25);
+                context.fillText('无人机名称: 无人机1号', 40, 50);
+                context.fillText('所属企业: 美团', 40, 70);
+                context.fillText('速度: 100km/h', 40, 90);
+                context.fillText('高度: 200m', 40, 110);
+                context.fillText(`状态: ${typeInfo}`,40, 130);
+                // 标记纹理需要更新
+                texture.needsUpdate = true;
+            };
+        }
+    },
+
 
     initPathCurve(){
       if(this.path.length > 1){
@@ -103,7 +204,75 @@ export const FlyGLTFClass = {
       }
     },
 
+    // 获取当前位置和方向信息
+    getCurrentPositionAndDirection() {
+        if (this.pathCurve && this.targetObject) {
+            // 获取当前位置
+            const position = this.pathCurve.getPointAt(this.pathProgress);
+            // 获取切线方向
+            const tangent = this.pathCurve.getTangentAt(this.pathProgress);
+            // 计算目标朝向(四元数)
+            this.targetObject.quaternion.setFromUnitVectors(new THREE.Vector3(0, 0, 1), tangent);
+
+            // 获取路径进度对应的点
+            const pathProgress = this.pathProgress;
+            // 计算路径的总长度和每条线段的长度
+            let totalLength = 0;
+            const segmentLengths = [];
+            const segments = [];
+
+            for (let i = 0; i < this.path.length - 1; i++) {
+                const startPoint = this.path[i];
+                const endPoint = this.path[i + 1];
 
+                const segmentLength = Math.sqrt(
+                    Math.pow(endPoint[0] - startPoint[0], 2) +
+                    Math.pow(endPoint[1] - startPoint[1], 2) +
+                    Math.pow(endPoint[2] - startPoint[2], 2)
+                );
+                segmentLengths.push(segmentLength);
+                totalLength += segmentLength;
+
+                // 存储当前线段的起点和终点
+                segments.push({ start: startPoint, end: endPoint });
+            }
+
+            // 计算当前位置对应的进度在整个路径的比例
+            let progress = pathProgress * totalLength;
+            let currentSegmentIndex = 0;
+            let accumulatedLength = 0;
+
+            // 判断当前进度所在的线段
+            for (let i = 0; i < segmentLengths.length; i++) {
+                accumulatedLength += segmentLengths[i];
+                if (progress <= accumulatedLength) {
+                    currentSegmentIndex = i;
+                    break;
+                }
+            }
+
+            // 获取当前所在的线段
+            const currentSegment = segments[currentSegmentIndex];
+            const segmentStart = currentSegment.start;
+            const segmentEnd = currentSegment.end;
+
+
+
+            return {
+                position: position, // 当前坐标
+                tangent: tangent,   // 当前切线方向
+                rotation: this.targetObject.rotation, // 当前旋转信息(朝向)
+                pathProgress: this.pathProgress, // 当前路径进度
+                currentSegment: { start: segmentStart, end: segmentEnd } // 当前所在的线段
+            };
+        }
+        return null;
+    },
+
+    // 设置悬停状态
+    setHovering(isHovering) {
+        this.isHovering = isHovering;
+    },
 
 
     render(){
@@ -115,6 +284,8 @@ export const FlyGLTFClass = {
         // Projection matrix can be copied directly
         this._camera.projectionMatrix.fromArray(cam.projectionMatrix);
 
+        this.updateInfoPanel(); // 更新面板信息
+
         if (this.mixer) {
             this.mixer.update(this.clock.getDelta());
         }
@@ -123,8 +294,7 @@ export const FlyGLTFClass = {
             this.airCraftMixer.update(this.airCraftClock.getDelta());
         }
 
-        if (this.pathCurve && this.targetObject) {
-            debugger
+        if (this.pathCurve && this.targetObject && !this.isHovering) {
             this.pathProgress += this.speed;
             if (this.pathProgress > 1) this.pathProgress = 0;
 
@@ -138,12 +308,8 @@ export const FlyGLTFClass = {
             }catch(e){
                 console.log("this.pathProgress",this.pathProgress)
             }
-
-
-
-            this.targetObject.rotation.z = -Math.PI/2;
         }
-
+        this.targetObject.rotation.z = -Math.PI/2;
 
         this.renderer.state.reset();
 

+ 13 - 9
src/units/threejs/threeCubeDetail.js

@@ -56,10 +56,10 @@ export const ThreeCubeDetailClass = {
         // 主体材质
         const material = new THREE.MeshPhongMaterial({
             transparent: true,
-            opacity: 0.1,
-            depthTest: true,
-            side: THREE.DoubleSide,
-            depthWrite: false, // 关闭深度写入
+            opacity: 0.05,
+            depthTest:false,
+            side:THREE.DoubleSide,
+            depthWrite: true // 关闭深度写入
         });
 
         // 修改材质支持 instanceColor
@@ -98,7 +98,7 @@ export const ThreeCubeDetailClass = {
 
         const dummy = new THREE.Object3D(); // 用于设置实例位置、旋转和缩放
         const instanceColors = new Float32Array(this.points.length * 3); // 用于存储每个实例的颜色
-
+        debugger
         // 遍历点信息,生成网格和边框
         for (let i = 0; i < this.points.length; i++) {
             const worldX = this.points[i].x;
@@ -126,15 +126,19 @@ export const ThreeCubeDetailClass = {
 
             // 设置每个实例的颜色
             const color = this.points[i].color; // 假设 color 是 [r, g, b]
-            instanceColors[i * 3] = 1;
-            instanceColors[i * 3 + 1] = 0;
-            instanceColors[i * 3 + 2] = 0;
+            instanceColors[i * 3] = color[0];
+            instanceColors[i * 3 + 1] = color[1];
+            instanceColors[i * 3 + 2] = color[2];
 
             // 创建边框材质,颜色与网格一致
             const glowMaterial = new THREE.LineBasicMaterial({
-                color: new THREE.Color(1, 0, 0),
+                color: new THREE.Color(color[0], color[1],  color[2]),
+                opacity:0.7,
                 linewidth: 2,      // 线条宽度
                 transparent: true, // 支持透明度
+                depthTest:false,
+                side:THREE.DoubleSide,
+                depthWrite: true // 关闭深度写入
             });
 
             // 创建并添加边框实例