Просмотр исходного кода

孙浩博,fixed:新增2D和3D标点功能

seamew 2 лет назад
Родитель
Сommit
1d67f052ca
2 измененных файлов с 127 добавлено и 124 удалено
  1. 33 14
      src/views/situation/Model.vue
  2. 94 110
      src/views/situation/index.vue

+ 33 - 14
src/views/situation/Model.vue

@@ -7,7 +7,7 @@
             :src="image.url"
             fit="fill"
             :class="{ 'highlighted-red': activeImage === image.name }"
-            @click="paneClick(image.name)"
+            @click="paneClick(image)"
           ></el-image>
           <div class="image-name">{{ image.name }}</div>
         </div>
@@ -20,7 +20,7 @@
             :src="image.url"
             fit="fill"
             :class="{ 'highlighted-blue': activeImage === image.name }"
-            @click="paneClick(image.name)"
+            @click="paneClick(image)"
           ></el-image>
           <div class="image-name">{{ image.name }}</div>
         </div>
@@ -35,55 +35,74 @@ export default {
     return {
       activeName: "red",
       activeImage: "",
-      isShow: false,
       imagesRed: [
         {
           url: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
           isClicked: false,
-          name: "Thad拦截导弹"
+          name: "Thad拦截导弹",
+          color: "Red"
         },
         {
           url: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
           isClicked: false,
-          name: "拦截雷达"
+          name: "拦截雷达",
+          color: "Red"
         },
         {
           url: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
           isClicked: false,
-          name: "拦截卫星"
+          name: "拦截卫星",
+          color: "Red"
         }
       ],
       imagesBlue: [
         {
           url: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
           isClicked: false,
-          name: "弹道导弹"
+          name: "弹道导弹",
+          color: "Blue"
         },
         {
           url: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
           isClicked: false,
-          name: "雷达诱饵"
+          name: "雷达诱饵",
+          color: "Blue"
         },
         {
           url: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
           isClicked: false,
-          name: "干扰雷达"
+          name: "干扰雷达",
+          color: "Blue"
         }
       ]
     };
   },
+  props: {
+    isShow: {
+      type: Boolean,
+      required: true
+    }
+  },
+  watch: {
+    isShow: {
+      handler(newObj, oldObj) {
+        if (!newObj) {
+          this.activeImage = "";
+        }
+      }
+    }
+  },
   methods: {
     tabClick(tab, event) {
       this.cancelHighlight();
-      console.log("123 :>> ");
     },
-    paneClick(name) {
-      if (name === this.activeImage) {
+    paneClick(image) {
+      if (image.name === this.activeImage) {
         this.cancelHighlight();
         return;
       }
-      this.$emit("selectModel", "pointer");
-      this.activeImage = name;
+      this.$emit("selectModel", "pointer", image);
+      this.activeImage = image.name;
     },
     cancelHighlight() {
       this.activeImage = "";

+ 94 - 110
src/views/situation/index.vue

@@ -11,13 +11,13 @@
     </el-row>
     <el-row id="earth" style="height: 790px; width: 100%; display: flex; position: relative">
       <el-col style="height: 100%; position: relative" :span="this.leftwidth">
-        <div class="main-layout" v-on:mouseover="changeActive('3D')">
-          <div id="3DcesiumContainer" class="map"></div>
+        <div class="main-layout" v-on:mouseover="changeActive('2D')">
+          <div id="2DcesiumContainer" class="map" @click="onMapClick"></div>
         </div>
       </el-col>
       <el-col style="height: 100%; position: relative" :span="24 - this.leftwidth">
-        <div class="main-layout" v-on:mouseover="changeActive('2D')">
-          <div id="2DcesiumContainer" class="map"></div>
+        <div class="main-layout" v-on:mouseover="changeActive('3D')">
+          <div id="3DcesiumContainer" class="map" @click="onMapClick"></div>
         </div>
       </el-col>
       <el-tabs
@@ -39,39 +39,7 @@
             <span slot="content" class="item">模型</span>
             <span><i class="el-icon-receiving"></i></span>
           </el-tooltip>
-          <Model @selectModel="selectModel"></Model>
-          <!-- <el-radio-group v-model="whosmodel" style="margin: 0 auto" size="mini">
-            <el-radio-button label="red">红方</el-radio-button>
-            <el-radio-button label="blue">蓝方</el-radio-button>
-          </el-radio-group>
-          <div v-if="whosmodel == 'blue'" class="model">
-            <div :class="{ active: this.modelType == 'ThadRocket' }" @click="selectmodel('ThadRocket')">
-              <el-image style="width: 100px; height: 80px; margin: 0 auto" :src="url" fit="fill"></el-image>
-              <div style="text-align: center">Thad拦截导弹</div>
-            </div>
-            <div :class="{ active: this.modelType == 'interceptRadar' }" @click="selectmodel('interceptRadar')">
-              <el-image style="width: 100px; height: 80px; margin: 0 auto" :src="url" fit="fill"></el-image>
-              <div style="text-align: center">拦截雷达</div>
-            </div>
-            <div :class="{ active: this.modelType == 'interceptSatellite' }" @click="selectmodel('interceptSatellite')">
-              <el-image style="width: 100px; height: 80px; margin: 0 auto" :src="url" fit="fill"></el-image>
-              <div style="text-align: center">拦截卫星</div>
-            </div>
-          </div>
-          <div v-else class="model">
-            <div :class="{ active: this.modelType == 'rocket' }" @click="selectmodel('rocket')">
-              <el-image style="width: 100px; height: 80px; margin: 0 auto" :src="url" fit="fill"></el-image>
-              <div style="text-align: center">弹道导弹</div>
-            </div>
-            <div :class="{ active: this.modelType == 'radarTrap' }" @click="selectmodel('radarTrap')">
-              <el-image style="width: 100px; height: 80px; margin: 0 auto" :src="url" fit="fill"></el-image>
-              <div style="text-align: center">雷达诱饵</div>
-            </div>
-            <div :class="{ active: this.modelType == 'GRradar' }" @click="selectmodel('GRradar')">
-              <el-image style="width: 100px; height: 80px; margin: 0 auto" :src="url" fit="fill"></el-image>
-              <div style="text-align: center">干扰雷达</div>
-            </div>
-          </div> -->
+          <Model @selectModel="selectModel" :isShow="isShow"></Model>
         </el-tab-pane>
         <el-tab-pane name="third">
           <el-tooltip placement="right" effect="light" slot="label">
@@ -97,8 +65,6 @@
       </el-tabs>
       <div class="buttons">
         <el-button icon="el-icon-full-screen" circle @click="ismax()"></el-button>
-        <!-- <el-button icon="el-icon-coin" circle></el-button> -->
-        <!-- <el-button icon="el-icon-bangzhu" @click="Fly()" circle></el-button> -->
         <el-button icon="el-icon-house" circle @click="home()"></el-button>
         <el-button icon="el-icon-plus" circle @click="big()"></el-button>
         <el-button icon="el-icon-minus" circle @click="small()"></el-button>
@@ -114,10 +80,20 @@ import { getToken } from "@/utils";
 import axios from "axios";
 import Model from "@/views/situation/Model";
 export default {
-  computed: {},
   components: {
     Model
   },
+  computed: {
+    leftwidth() {
+      if (this.dimension === 2) {
+        return 24;
+      } else if (this.dimension === 3) {
+        return 0;
+      } else if (this.dimension === 5) {
+        return 12;
+      }
+    }
+  },
   data() {
     return {
       situation: [],
@@ -126,8 +102,7 @@ export default {
       center: [],
       viewer2D: null,
       viewer3D: null,
-      dimension: 3,
-      leftwidth: 24,
+      dimension: 5,
       mousevalue: null,
       shouldAnimate: false,
       activeName: null,
@@ -138,7 +113,10 @@ export default {
       whosmodel: "red",
       modelType: null,
       url: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
-      isShow: false
+      isShow: false,
+      handler3D: null,
+      handler2D: null,
+      image: null
     };
   },
   created() {
@@ -430,9 +408,8 @@ export default {
       this.viewer2D.camera.changed.addEventListener(this.sync);
       this.viewer3D.camera.percentageChanged = 0.01;
       this.viewer3D.camera.changed.addEventListener(this.sync);
-    },
-    removeAllModel() {
-      this.viewer.entities.removeAll(); // 移除全部模型
+      this.handler2D = new this.Cesium.ScreenSpaceEventHandler(this.viewer2D.scene.canvas);
+      this.handler3D = new this.Cesium.ScreenSpaceEventHandler(this.viewer3D.scene.canvas);
     },
     sync() {
       if (this.mousevalue == "3D") {
@@ -441,10 +418,8 @@ export default {
           Math.floor(this.viewer3D.canvas.clientWidth / 2),
           Math.floor(this.viewer3D.canvas.clientHeight / 2)
         );
-
         // 转为世界坐标系
         let position = this.viewer3D.scene.camera.pickEllipsoid(center);
-        console.log(position);
         // 判断中心点是否在椭球体上
         if (this.Cesium.defined(position)) {
           // 获取三维地图中心点与相机之间的距离
@@ -454,7 +429,6 @@ export default {
           this.viewer2D.scene.camera.setView({
             destination: new this.Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, distance)
           });
-          console.log(distance);
         }
       }
       if (this.mousevalue == "2D") {
@@ -465,18 +439,15 @@ export default {
         );
         // 转为世界坐标系
         let position = this.viewer2D.scene.camera.pickEllipsoid(center);
-        console.log(position);
         // 判断中心点是否在椭球体上
         if (this.Cesium.defined(position)) {
           // 获取三维地图中心点与相机之间的距离
           let distance = this.viewer2D.scene.camera.positionCartographic.height;
-
           position = this.convertWorldToCartographic(position);
           // 更新三维地图
           this.viewer3D.scene.camera.setView({
             destination: new this.Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, distance)
           });
-          console.log(this.viewer2D.scene.camera.positionWC);
         }
       }
     },
@@ -492,17 +463,10 @@ export default {
     // 监听地图变化
     changeActive(value) {
       this.mousevalue = value;
-      console.log(value);
     },
     dimensionswitch(value) {
       this.dimension = value;
-      if (value == 3) {
-        this.leftwidth = 24;
-      } else if (value == 2) {
-        this.leftwidth = 0;
-      } else {
-        this.leftwidth = 12;
-      }
+      this.selectModel();
     },
     // 全屏缩小
     ismax() {
@@ -555,74 +519,94 @@ export default {
         duration: 2.0
       });
     },
-    Fly() {
-      this.shouldAnimate = !this.shouldAnimate;
-      this.viewer2D.clock.shouldAnimate = true;
-      this.viewer3D.clock.shouldAnimate = true;
-      if (this.shouldAnimate == true) {
-        this.startRun({ multiplier: 2000 });
-      } else {
-        this.stopRun();
-      }
-    },
-    startRun(option = { multiplier: 1 }) {
-      // 监听每次渲染前执行矩阵求解
-      this.viewer3D.scene.postUpdate.addEventListener(this.rotateSetting);
-      // 根据option修改一些参数
-      if (this.viewer3D.clock) {
-        const keys = Object.keys(option);
-        for (let k of keys) {
-          this.viewer3D.clock[k] = option[k];
-        }
-      }
-    },
-    stopRun() {
-      let viewer = this.viewer3D;
-      viewer.clock.multiplier = 1;
-      viewer.scene.postUpdate.removeEventListener(this.rotateSetting);
-    },
-    rotateSetting() {
-      let Cesium = this.Cesium;
-      let viewer = this.viewer3D;
-      if (!viewer || viewer.scene.mode !== Cesium.SceneMode.SCENE3D) {
-        return;
-      }
-      const icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(viewer.clock.currentTime);
-      // icrfToFixed 在上面的方法中,若没加载好所需的计算资源会返回undefined,判断下
-      if (Cesium.defined(icrfToFixed)) {
-        const camera = viewer.camera;
-        const offset = Cesium.Cartesian3.clone(camera.position);
-        const transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
-        camera.lookAtTransform(transform, offset);
-      }
-    },
-    /// / tabs 切换点击
-    legendClick(tab, event) {
-      var tab_content = document.querySelectorAll(".menu .el-tabs__content");
-      if (this.currentLab.index == tab.index) {
+    // tabs 切换点击
+    legendClick({ index }) {
+      this.selectModel();
+      let tab_content = document.querySelectorAll(".menu .el-tabs__content");
+      if (this.currentLab.index == index) {
         tab_content[0].style.display == "none" || ""
           ? (tab_content[0].style.display = "block")
           : (tab_content[0].style.display = "none");
       }
-      if (this.currentLab.index != tab.index) {
-        this.currentLab.index = tab.index;
+      if (this.currentLab.index != index) {
+        this.currentLab.index = index;
         tab_content[0].style.display = "block";
       }
     },
     mouseMove(event) {
-      this.$refs.modeltooltip.style.left = event.pageX - 220 + "px";
-      this.$refs.modeltooltip.style.top = event.pageY - 110 + "px";
+      if (this.$refs.modeltooltip) {
+        this.$refs.modeltooltip.style.left = event.pageX - 240 + "px";
+        this.$refs.modeltooltip.style.top = event.pageY - 115 + "px";
+      }
     },
-    selectModel(cursorStyle) {
+    selectModel(cursorStyle, image) {
       let earthMap = document.getElementById("earth");
       earthMap.style.cursor = cursorStyle || "auto";
       if (cursorStyle) {
         document.addEventListener("mousemove", this.mouseMove);
         this.isShow = true;
+        this.image = image;
       } else {
         document.removeEventListener("mousemove", this.mouseMove);
         this.isShow = false;
+        this.image = null;
+      }
+    },
+    onMapClick(event) {
+      if (this.isShow) {
+        const { latitude, longitude } = this.getCoordinatesFromEvent(event);
+        this.markLocation(latitude, longitude);
+      }
+    },
+    // 同时在2D和3D地图上标记坐标
+    markLocation(latitude, longitude) {
+      const position = this.Cesium.Cartesian3.fromDegrees(longitude, latitude);
+      this.viewer2D.entities.add({
+        position: position,
+        point: {
+          pixelSize: 12, // 调整点的大小,可以增大点的像素大小
+          color: this.Cesium.Color.fromCssColorString(this.image.color)
+        },
+        label: {
+          text: this.image.name,
+          show: true,
+          font: "18px Helvetica", // 调整标签的字体样式和大小
+          pixelOffset: new this.Cesium.Cartesian2(0, 20) // 调整标签的像素偏移,向下偏移20像素
+        }
+      });
+      console.log("position :>> ", position);
+      this.viewer3D.entities.add({
+        position: position,
+        point: {
+          pixelSize: 12, // 调整点的大小,可以增大点的像素大小
+          color: this.Cesium.Color.fromCssColorString(this.image.color)
+        },
+        label: {
+          text: this.image.name,
+          show: true,
+          font: "18px Helvetica", // 调整标签的字体样式和大小
+          pixelOffset: new this.Cesium.Cartesian2(0, 20) // 调整标签的像素偏移,向下偏移20像素
+        }
+      });
+    },
+    // 从鼠标点击事件获取坐标
+    getCoordinatesFromEvent(event) {
+      let viewer = this.mousevalue === "2D" ? this.viewer2D : this.viewer3D;
+      let clickPosition;
+      if (this.dimension === 5 && this.mousevalue === "3D") {
+        clickPosition = new this.Cesium.Cartesian2(event.clientX - 1080, event.clientY - 160);
+      } else {
+        clickPosition = new this.Cesium.Cartesian2(event.clientX - 280, event.clientY - 160);
       }
+      // 获取地图上的经纬度
+      const viewerPosition = viewer.scene.camera.pickEllipsoid(clickPosition);
+      const cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(viewerPosition);
+      const latitude = this.Cesium.Math.toDegrees(cartographic.latitude);
+      const longitude = this.Cesium.Math.toDegrees(cartographic.longitude);
+      return {
+        latitude,
+        longitude
+      };
     }
   }
 };