Переглянути джерело

显示配置、飞机和编号成组、隐藏、显示编号递增、路径优化、更改鼠标事件

Rmengdi 2 місяців тому
батько
коміт
f36e4e4aa9
1 змінених файлів з 280 додано та 69 видалено
  1. 280 69
      uavps-web/src/views/uavps/parameter/index.vue

+ 280 - 69
uavps-web/src/views/uavps/parameter/index.vue

@@ -281,13 +281,15 @@
     </el-dialog>
 
     <!-- 飞行轨迹展示对话框 -->
+    <!-- @closed="destroyTrajectory" -->
     <el-dialog
       :title="title"
       :visible.sync="showTrajectory"
       @opened="initTrajectory"
-      @closed="destroyTrajectory"
+      :before-close="destroyTrajectory"
       :fullscreen="true"
       append-to-body
+      destroy-on-close
     >
       <div class="container">
         <div>
@@ -307,28 +309,59 @@
           </el-row>
         </div>
         <div class="right-board">
+          <div style="float: right">
+            <el-link type="primary" @click="showConfig">显示配置</el-link>
+          </div>
           <el-divider content-position="left">目标无人机群</el-divider>
           <li v-for="(item, index) in targetLblAry" :key="index">
-            <span>编号:&nbsp;&nbsp;</span><label>{{ item.no }}</label
-            ><br />
-            <span>经度:&nbsp;&nbsp;</span><label>{{ item.longitude }}</label
-            ><br />
-            <span>纬度:&nbsp;&nbsp;</span><label>{{ item.latitude }}</label
-            ><br />
-            <span>海拔:&nbsp;&nbsp;</span><label>{{ item.altitude }}</label
-            ><br />
-            <span>东向速度:&nbsp;&nbsp;</span
-            ><label>{{ item.eastSpeed }}</label
-            ><br />
-            <span>北向速度:&nbsp;&nbsp;</span
-            ><label>{{ item.northSpeed }}</label
-            ><br />
-            <span>天向速度:&nbsp;&nbsp;</span><label>{{ item.skySpeed }}</label
-            ><br />
+            <div @click="showSprite(item.id)" style="cursor: pointer">
+              <span>编号:&nbsp;&nbsp;</span><label>{{ item.showNo }}</label>
+              <span style="margin-left: 10px" v-if="hideList.includes(item.id)"
+                >( 隐 藏 )</span
+              >
+            </div>
+            <div v-if="configList.includes('经度')">
+              <span>经度:&nbsp;&nbsp;</span><label>{{ item.longitude }}</label>
+            </div>
+            <div v-if="configList.includes('纬度')">
+              <span>纬度:&nbsp;&nbsp;</span><label>{{ item.latitude }}</label>
+            </div>
+            <div v-if="configList.includes('海拔')">
+              <span>海拔:&nbsp;&nbsp;</span><label>{{ item.altitude }}</label>
+            </div>
+            <div v-if="configList.includes('东向速度')">
+              <span>东向速度:&nbsp;&nbsp;</span
+              ><label>{{ item.eastSpeed }}</label>
+            </div>
+            <div v-if="configList.includes('北向速度')">
+              <span>北向速度:&nbsp;&nbsp;</span
+              ><label>{{ item.northSpeed }}</label>
+            </div>
+            <div v-if="configList.includes('天向速度')">
+              <span>天向速度:&nbsp;&nbsp;</span
+              ><label>{{ item.skySpeed }}</label>
+            </div>
           </li>
         </div>
       </div>
     </el-dialog>
+
+    <!-- 显示配置对话框 -->
+    <el-dialog title="显示配置" :visible.sync="showConfigVisible" width="30%">
+      <el-checkbox-group
+        v-model="showConfigList"
+        style="display: flex; flex-direction: column"
+      >
+        <el-checkbox
+          v-for="item in configData"
+          :label="item.label"
+        ></el-checkbox>
+      </el-checkbox-group>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="showConfigVisible = false">取 消</el-button>
+        <el-button type="primary" @click="selectConfigSubmit">确 定</el-button>
+      </span>
+    </el-dialog>
   </div>
 </template>
 
@@ -365,6 +398,7 @@ export default {
       title: "",
       // 是否显示弹出层
       open: false,
+      showConfigVisible: false,
       // 查询参数
       queryParams: {
         pageNum: 1,
@@ -422,6 +456,7 @@ export default {
       // 是否显示轨迹
       showTrajectory: false,
       pixiApp: null,
+      container: null,
       parameterId: null,
       webSocket: null,
       curLongitude: null,
@@ -437,6 +472,24 @@ export default {
       targetUavCircle: [],
       targetUavCircleNum: [],
       targetUavPath: [],
+      showConfigList: [], // 选择要显示的值
+      configList: ["经度", "纬度", "海拔", "东向速度", "北向速度", "天向速度"], // 显示的值
+      configData: [
+        // 可选择的值
+        { key: "longitude", label: "经度" },
+        { key: "latitude", label: "纬度" },
+        { key: "altitude", label: "海拔" },
+        { key: "eastSpeed", label: "东向速度" },
+        { key: "northSpeed", label: "北向速度" },
+        { key: "skySpeed", label: "天向速度" },
+      ],
+      hideList: [], // 当下隐藏的飞机数组
+      allId: [], // 所有飞机的id
+      changeShowNoList: [], // 需要改变的飞机编号,放有id和应该显示的编号
+      lastPosition: {
+        x: null,
+        y: null,
+      },
     };
   },
   created() {
@@ -559,31 +612,40 @@ export default {
         `parameter_${new Date().getTime()}.xlsx`
       );
     },
+    showConfig() {
+      this.showConfigList = this.configList;
+      this.showConfigVisible = true;
+    },
+    selectConfigSubmit() {
+      this.configList = this.showConfigList;
+      this.showConfigVisible = false;
+    },
     initTrajectory() {
       this.clearAllAry();
       this.initPixi();
       this.initWebSocket();
     },
     initPixi() {
-      const container = this.$refs.pixiContainer;
-      if (!container) return;
+      this.container = this.$refs.pixiContainer;
+      if (!this.container) return;
 
       // 创建Pixi应用
       this.pixiApp = new PIXI.Application({
-        width: container.clientWidth,
-        height: container.clientHeight,
+        width: this.container.clientWidth,
+        height: this.container.clientHeight,
         antialias: true,
         transparent: false,
         resolution: 1,
         backgroundAlpha: 0,
       });
       this.pixiApp.renderer.backgroundColor = 0x66ccff;
-      container.appendChild(this.pixiApp.view);
+      this.container.appendChild(this.pixiApp.view);
 
       //this.createPlane();
 
       // 初始化路径绘制对象
       this.pathGraphics = new PIXI.Graphics();
+      // this.pathGraphics.stroke({ pixelLine: true });
       this.pixiApp.stage.addChild(this.pathGraphics);
 
       // 添加视窗控制
@@ -623,12 +685,19 @@ export default {
       // 集群无人机总数
       // this.targetTotal = 2;
       this.targetTotal = data.targetAircraft[0].aircrafts.length;
+      // console.log("data.targetAircraft[0]", data.targetAircraft[0]);
+      // debugger;
       // 创建无人机,红色圆圈编号
       if (this.targetUavAry.length === 0) {
         this.targetTexture = new PIXI.Texture.from(
           "../../textures/uav-tar.png"
         );
         for (let i = 0; i < this.targetTotal; i++) {
+          this.allId.push(data.targetAircraft[0].aircrafts[i].aircraftNumber);
+          const group = new PIXI.Container();
+          group.id = data.targetAircraft[0].aircrafts[i].aircraftNumber;
+          group.buttonMode = true; // 鼠标悬停时显示手型
+          group.interactive = true;
           // 创建无人机
           const dude = new PIXI.Sprite(this.targetTexture);
           dude.anchor.set(0.5);
@@ -637,8 +706,11 @@ export default {
           dude.y = data.targetAircraft[0].aircrafts[i].coordinateY;
           dude.rotation = Math.atan2(dude.y, dude.x) + Math.PI / 2;
 
+          dude.id = data.targetAircraft[0].aircrafts[i].aircraftNumber; // 分配唯一编号
+
           this.targetUavAry.push(dude);
-          this.pixiApp.stage.addChild(dude);
+          group.addChild(dude);
+          // this.pixiApp.stage.addChild(group);
 
           // 创建圆圈
           // 圆圈相对于飞机的位置
@@ -653,7 +725,8 @@ export default {
           circle.x = cx;
           circle.y = cy;
           this.targetUavCircle.push(circle);
-          this.pixiApp.stage.addChild(circle);
+          group.addChild(circle);
+          // this.pixiApp.stage.addChild(circle);
 
           //编号-数字
           const text = new PIXI.Text(
@@ -670,8 +743,12 @@ export default {
           text.x = cx;
           text.y = cy;
           this.targetUavCircleNum.push(text);
-          this.pixiApp.stage.addChild(text);
-
+          group.addChild(text);
+          // 绑定鼠标事件,飞机隐藏
+          group.on("pointerdown", () => {
+            this.hideSprite(group);
+          });
+          this.pixiApp.stage.addChild(group);
           if (data.targetAircraft[0].aircrafts[i].piloted) {
             const point = { x: dude.x, y: dude.y };
             this.targetUavPath.push(point);
@@ -683,6 +760,7 @@ export default {
       } else {
         for (let i = 0; i < this.targetUavAry.length; i++) {
           const targetUav = this.targetUavAry[i];
+
           targetUav.x = data.targetAircraft[0].aircrafts[i].coordinateX;
           targetUav.y = data.targetAircraft[0].aircrafts[i].coordinateY;
           targetUav.rotation =
@@ -700,7 +778,16 @@ export default {
           text.y = cy;
 
           if (data.targetAircraft[0].aircrafts[i].piloted) {
+            // console.log(
+            //   "coordinateX",
+            //   data.targetAircraft[0].aircrafts[i].coordinateX
+            // );
+            // console.log(
+            //   "coordinateY",
+            //   data.targetAircraft[0].aircrafts[i].coordinateY
+            // );
             const point = { x: targetUav.x, y: targetUav.y };
+            // console.log("point", point);
             this.targetUavPath.push(point);
             this.curLongitude = data.targetAircraft[0].aircrafts[i].longitude;
             this.curLatitude = data.targetAircraft[0].aircrafts[i].latitude;
@@ -710,9 +797,14 @@ export default {
       }
       if (data.targetAircraft != null) {
         for (let i = 0; i < this.targetTotal; i++) {
+          const id = data.targetAircraft[0].aircrafts[i].aircraftNumber;
+          let findItem = this.changeShowNoList.find((item) => item.id == id);
           // 多目标集群信息显示
           const lbl = {
-            no: data.targetAircraft[0].aircrafts[i].aircraftNumber,
+            id: id,
+            showNo: findItem
+              ? findItem.showNo
+              : data.targetAircraft[0].aircrafts[i].aircraftNumber,
             longitude: data.targetAircraft[0].aircrafts[i].longitude.toFixed(7),
             latitude: data.targetAircraft[0].aircrafts[i].latitude.toFixed(7),
             altitude: data.targetAircraft[0].aircrafts[i].altitude + " m",
@@ -737,6 +829,51 @@ export default {
       // 更新位置
       //this.updatePosition();
     },
+    // 飞机的显示与隐藏
+    hideSprite(group) {
+      this.hideList.push(group.id);
+      this.changeShowNoList.push({ id: group.id, showNo: group.id });
+      group.visible = false;
+    },
+    showSprite(id) {
+      let group;
+      this.pixiApp.stage.children.forEach((child) => {
+        // 检查 child 是否是 Container 类型
+        if (child instanceof PIXI.Container) {
+          if (child.id == id) {
+            group = child;
+          }
+        }
+      });
+      if (this.hideList.includes(id)) {
+        const maxNum = Math.max(...this.allId);
+        // 更改画布飞机的编号
+        group.children.forEach((item) => {
+          if (item instanceof PIXI.Text) {
+            item.text = maxNum + 1;
+          }
+        });
+        // 更改右侧信息展示编号
+        for (let i = 0; i < this.changeShowNoList.length; i++) {
+          if (this.changeShowNoList[i].id == id) {
+            this.$set(this.changeShowNoList[i], "showNo", maxNum + 1);
+            break;
+          }
+        }
+        // 已经隐藏了,要显示
+        group.visible = true;
+        let index = this.hideList.indexOf(id);
+        if (index > -1) {
+          this.hideList.splice(index, 1);
+        }
+        this.allId.push(maxNum + 1);
+      } else {
+        // 隐藏
+        group.visible = false;
+        this.hideList.push(group.id);
+        this.changeShowNoList.push({ id: group.id, showNo: group.id });
+      }
+    },
     // 创建飞机精灵
     createPlane() {
       this.texture = new PIXI.Texture.from("../../textures/uav.png");
@@ -748,28 +885,42 @@ export default {
     },
     // 更新飞行路径
     updatePath() {
-      this.pathGraphics.clear();
+      // console.log("this.targetUavPath", this.targetUavPath);
+      // this.pathGraphics.clear();
       this.pathGraphics.lineStyle(1, 0xeeee00, 1);
+      // debugger;
+      // const simplifiedPath = douglasPeucker(this.targetUavPath, 5);
+      if (this.targetUavPath.length <= 1) {
+        const firstData = this.targetUavPath[this.targetUavPath.length - 1];
+        this.lastPosition = firstData;
+        this.pathGraphics.moveTo(firstData.x, firstData.y);
+      } else {
+        this.pathGraphics.moveTo(this.lastPosition.x, this.lastPosition.y);
+        const nextPos = this.targetUavPath[this.targetUavPath.length - 1];
+        this.pathGraphics.lineTo(nextPos.x, nextPos.y);
+        this.lastPosition = nextPos;
+      }
 
-      if (this.targetUavPath.length > 1) {
-        this.pathGraphics.moveTo(
-          this.targetUavPath[0].x,
-          this.targetUavPath[0].y
-        );
+      // 之前的
+      // if (this.targetUavPath.length > 1) {
+      //   this.pathGraphics.moveTo(
+      //     this.targetUavPath[0].x,
+      //     this.targetUavPath[0].y
+      //   );
 
-        // 使用曲线平滑路径
-        this.targetUavPath.forEach((point, index) => {
-          if (index > 0) {
-            const prev = this.targetUavPath[index - 1];
-            this.pathGraphics.quadraticCurveTo(
-              prev.x,
-              prev.y,
-              (prev.x + point.x) / 2,
-              (prev.y + point.y) / 2
-            );
-          }
-        });
-      }
+      //   // 使用曲线平滑路径
+      //   this.targetUavPath.forEach((point, index) => {
+      //     if (index > 0) {
+      //       const prev = this.targetUavPath[index - 1];
+      //       this.pathGraphics.quadraticCurveTo(
+      //         prev.x,
+      //         prev.y,
+      //         (prev.x + point.x) / 2,
+      //         (prev.y + point.y) / 2
+      //       );
+      //     }
+      //   });
+      // }
     },
     // 更新位置
     updatePosition() {
@@ -805,6 +956,7 @@ export default {
         // }
       });
     },
+
     // 添加视窗控制
     enableViewControl() {
       this.pixiApp.stage.interactive = true;
@@ -813,30 +965,37 @@ export default {
       let offsetX = 0;
       let offsetY = 0;
 
-      // 鼠标拖曳
-      this.pixiApp.stage
-        .on("pointerdown", (e) => {
-          dragging = true;
-          offsetX = this.pixiApp.stage.position.x - e.data.global.x;
-          offsetY = this.pixiApp.stage.position.y - e.data.global.y;
-        })
-        .on("pointermove", (e) => {
-          if (dragging) {
-            this.pixiApp.stage.position.x = e.data.global.x + offsetX;
-            this.pixiApp.stage.position.y = e.data.global.y + offsetY;
-          }
-        })
-        .on("pointerup", () => {
-          dragging = false;
-        });
-
-      // 使用 mouseup 事件
-      this.pixiApp.renderer.view.addEventListener("mouseup", (event) => {
+      let lastPosition = null; // 上一次鼠标的位置
+      // 鼠标按下事件
+      this.pixiApp.view.addEventListener("mousedown", (event) => {
+        dragging = true;
+        lastPosition = { x: event.clientX, y: event.clientY };
+      });
+      // 鼠标移出画布时停止拖动
+      this.pixiApp.view.addEventListener("mouseleave", () => {
         dragging = false;
       });
 
-      // 或者使用 pointerup 事件
-      this.pixiApp.renderer.view.addEventListener("pointerup", (event) => {
+      // 鼠标移动事件
+      this.pixiApp.view.addEventListener("mousemove", (event) => {
+        if (dragging) {
+          const currentPosition = { x: event.clientX, y: event.clientY };
+
+          // 计算鼠标移动的距离
+          const dx = currentPosition.x - lastPosition.x;
+          const dy = currentPosition.y - lastPosition.y;
+
+          // 更新舞台的位置
+          this.pixiApp.stage.x += dx;
+          this.pixiApp.stage.y += dy;
+
+          // 更新上一次鼠标的位置
+          lastPosition = currentPosition;
+        }
+      });
+
+      // 鼠标松开事件
+      this.pixiApp.view.addEventListener("mouseup", () => {
         dragging = false;
       });
 
@@ -852,14 +1011,42 @@ export default {
       if (this.webSocket) {
         this.webSocket.close();
       }
+      if (this.pathGraphics) {
+        if (this.pathGraphics.parent) {
+          this.pathGraphics.parent.removeChild(this.pathGraphics);
+        }
+        // debugger;
+        this.pathGraphics.clear();
+        this.pathGraphics.destroy(true);
+        this.pathGraphics = null;
+      }
       if (this.pixiApp) {
+        // console.log("this.pixiApp", this.pixiApp);
+        // 移除并销毁所有子对象
+        const removedChildren = this.pixiApp.stage.removeChildren(
+          0,
+          this.pixiApp.stage.children.length
+        );
+        removedChildren.forEach((child) => {
+          child.destroy({
+            children: true,
+            texture: false,
+            baseTexture: false,
+          });
+        });
+        this.pixiApp.stage.removeChildren();
+
+        // debugger;
+        this.pixiApp.renderer.clear();
         this.pixiApp.destroy(true);
         this.pixiApp = null;
       }
+
       this.clearAllAry();
+      this.showTrajectory = false;
     },
     transFormation() {
-      debugger;
+      // debugger;
       let msg =
         "TRANSFORMATION:" +
         this.parameterId +
@@ -880,6 +1067,25 @@ export default {
       this.targetUavCircle = [];
       this.targetUavCircleNum = [];
       this.targetUavPath = [];
+      this.configList = [
+        "经度",
+        "纬度",
+        "海拔",
+        "东向速度",
+        "北向速度",
+        "天向速度",
+      ];
+      this.lastPosition = {
+        x: null,
+        y: null,
+      };
+      this.hideList = [];
+      this.allId = [];
+      this.changeShowNoList = [];
+      this.curLongitude = null;
+      this.curLatitude = null;
+      this.curAltitude = null;
+      this.pathGraphics = null;
     },
     // 经度转X坐标(示例转换函数)
     lonToX(longitude) {
@@ -901,9 +1107,14 @@ export default {
 </script>
 
 <style>
+.el-dialog__body {
+  /* padding: 0 !important; */
+  padding-top: 10px !important;
+}
 .pixi-container {
   width: 100%;
-  height: 750px;
+  /* height: 750px; */
+  height: calc(100vh - 140px);
   position: relative;
 }