wuxiang 1 년 전
부모
커밋
8ca667e3e2
4개의 변경된 파일266개의 추가작업 그리고 17개의 파일을 삭제
  1. 11 3
      src/layout/Footer/index.vue
  2. 1 0
      src/store/getters.js
  3. 4 0
      src/store/modules/app.js
  4. 250 14
      src/views/map/index.vue

+ 11 - 3
src/layout/Footer/index.vue

@@ -9,13 +9,18 @@
         inactive-text="场景模拟"
         @change="modelTypeChange()">
       </el-switch>
-
+       
+       <div style="line-height: 31px;float:right;color: #ffffff;">
+        <span style="margin: auto 30px;">想定文件:{{ xdname }}</span>
+       </div>
+       
        <div style="margin-left: 300px;line-height: 31px;color: #3f96a5;">
         <span style="margin: auto 30px;">经度: {{ mouseLocation.longitude }}</span>
         <span style="margin: auto 30px;">纬度:{{ mouseLocation.latitude }}</span>
         <span style="margin: auto 30px;">层级: {{ cameraHeightAndZoom.zoom }}</span>
         <span style="margin: auto 30px;">视高:{{ cameraHeightAndZoom.height }}</span>
        </div>
+       
     </el-footer>
 </template>
 <script>
@@ -36,7 +41,8 @@ export default {
       'isCollapse',
       'mouseLocation',
       'cameraHeightAndZoom',
-      'mode'
+      'mode',
+      'xdname'
     ]),
   },
     watch: {
@@ -45,12 +51,14 @@ export default {
             this.latitude = val.latitude
         },
         mode: function(val, oldVal){
+          this.$store.commit('app/setXDname',"无");
             this.modeType = val
             this.$notify({
               title: val==true?"已切换到态势显示":"已切换到场景模拟",
               type: 'success'
             });
-        }
+        },
+
        
     },
     mounted(){

+ 1 - 0
src/store/getters.js

@@ -3,6 +3,7 @@ const getters = {
     mode: state => state.app.mode,
     isCollapse: state => state.app.isCollapse,
     dimension: state => state.app.dimension,
+    xdname: state => state.app.xdname,
     mouseLocation: state => state.app.mouseLocation,
     cameraHeightAndZoom: state => state.app.cameraHeightAndZoom,
     //userInfo

+ 4 - 0
src/store/modules/app.js

@@ -4,6 +4,7 @@ const getDefaultState = () => {
         mode: false, //false为场景模拟,true为态势显示
         isCollapse: false, //是否展开
         dimension: 5, //地图维度
+        xdname: "无", //想定文件名称
         mouseLocation: { //鼠标在地图的经纬度 
             longitude: null,
             latitude: null
@@ -29,6 +30,9 @@ const mutations = {
     setDimension(state, dimension) {
         state.dimension = dimension
     },
+    setXDname(state, xdname) {
+        state.xdname = xdname
+    },
     setMouseLocation(state, mouseLocation) {
         state.mouseLocation = mouseLocation
     },

+ 250 - 14
src/views/map/index.vue

@@ -10,11 +10,31 @@
         <div class="main-layout" v-on:mouseover="changeActive('2D')" @mousemove="getMouseLocation">
           <div id="2DcesiumContainer" class="map"></div>
         </div>
+        <!-- <div class="bottom-rightbuttons">
+          <el-tooltip placement="left" effect="light" slot="label">
+              <span slot="content" class="item">测量</span>
+              <el-button icon="el-icon-files" circle @click="measurement($data._viewer2D,handler2D)" ></el-button>
+          </el-tooltip>
+          <el-tooltip placement="left" effect="light" slot="label">
+              <span slot="content" class="item">通视</span>
+              <el-button icon="el-icon-files" circle @click="throughSight($data._viewer2D,handler2D)" ></el-button>
+          </el-tooltip>
+        </div> -->
       </el-col>
       <el-col style="height: 100%; position: relative" :span="24 - this.leftwidth">
         <div class="main-layout" v-on:mouseover="changeActive('3D')" @mousemove="getMouseLocation">
           <div id="3DcesiumContainer" class="map"></div>
         </div>
+        <!-- <div class="bottom-rightbuttons">
+          <el-tooltip placement="left" effect="light" slot="label">
+              <span slot="content" class="item">测量</span>
+              <el-button icon="el-icon-files" circle @click="measurement($data._viewer3D,handler3D)" ></el-button>
+          </el-tooltip>
+          <el-tooltip placement="left" effect="light" slot="label">
+              <span slot="content" class="item">通视</span>
+              <el-button icon="el-icon-files" circle @click="throughSight($data._viewer3D,handler3D)" ></el-button>
+          </el-tooltip>
+        </div> -->
       </el-col>
       <el-tabs type="border-card" v-model="panelName" tab-position="left" class="menu" :stretch="true"
         @tab-click="legendClick">
@@ -133,15 +153,35 @@
           </el-table>
         </el-tab-pane>
       </el-tabs>
-      <div class="topbuttons">
-        <el-button icon="el-icon-full-screen" circle @click="ismax()"></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>
-        <el-button icon="el-icon-close" circle @click="removeEntitys();"></el-button>
+      <div class="top-rightbuttons">
+        <el-tooltip placement="left" effect="light" slot="label">
+            <span slot="content" class="item">放大/缩小</span>
+            <el-button icon="el-icon-full-screen" circle @click="ismax()"></el-button>
+        </el-tooltip>
+        <el-tooltip placement="left" effect="light" slot="label">
+            <span slot="content" class="item">Home键</span>
+            <el-button icon="el-icon-house" circle @click="home()"></el-button>
+        </el-tooltip>
+        <el-tooltip placement="left" effect="light" slot="label">
+            <span slot="content" class="item">放大</span>
+            <el-button icon="el-icon-plus" circle @click="big()"></el-button>
+        </el-tooltip>
+        <el-tooltip placement="left" effect="light" slot="label">
+            <span slot="content" class="item">缩小</span>
+            <el-button icon="el-icon-minus" circle @click="small()"></el-button>
+        </el-tooltip>
+        <el-tooltip placement="left" effect="light" slot="label">
+            <span slot="content" class="item">模型移除</span>
+            <el-button icon="el-icon-close" circle @click="removeEntitys();"></el-button>
+        </el-tooltip>
+        
       </div>
-      <div class="bottombuttons">
-        <el-button icon="el-icon-download" circle @click="saveJson()" v-if="this.mode!=true"></el-button>
+      <div class="middle-rightbuttons">
+        <el-tooltip placement="left" effect="light" slot="label">
+            <span slot="content" class="item">想定保存</span>
+            <el-button icon="el-icon-download" circle @click="saveJson()" v-if="this.mode!=true"></el-button>
+        </el-tooltip>
+        
       </div>
     </el-row>
       <el-dialog title="结果" :visible.sync="dialogVisible" width="50%">
@@ -358,6 +398,14 @@ export default {
       selectMissile:{
         pos:{x:0,y:0,z:0}
       },
+
+      measurementPosition: [], // 记录位置
+      poly: null, // 记录线
+      distance: 0, // 记录距离
+      cartesian: null, // 获取鼠标与地图的交点
+      labelPt: null, // 最终位置
+      options: null, //线段
+
       redForm: {
           name: '',
           method: '',
@@ -514,6 +562,7 @@ export default {
     },
     xdName: {
       handler: function (val, oldVal) {
+        this.$store.commit('app/setXDname',val);
         this.$notify({
               title: "提示",
               message: "已选择想定文件:"+val,
@@ -649,8 +698,6 @@ export default {
         })
         .then((response) => {
           console.log('response.data :>> ', response.data);
-          // // 处理成功的响应
-          // jsonData = response.data
           this.xdName = response.data.xdname
           blueunit = response.data.blueunit
           redunit = response.data.redunit
@@ -1225,9 +1272,189 @@ export default {
         this.$store.commit("app/setMouseLocation", { longitude, latitude });
       } catch (error) {
         // console.error(error);
-      }
+      } 
+    },
+    //测距
+    measurement(viewer,handler){
+      // 鼠标左键点击事件
+      handler.setInputAction((ele) => {
+            // 创建射线并获取交点
+            let ray = viewer.camera.getPickRay(ele.position)
+            this.cartesian = viewer.scene.globe.pick(ray, viewer.scene)
+            if (!Cesium.defined(this.cartesian)) return
+            if (this.measurementPosition.length === 0) {
+                this.measurementPosition.push(this.cartesian.clone())
+            }
+            this.measurementPosition.push(this.cartesian)
+            // 记录鼠标单击时的位置,异步计算贴地距离
+            this.labelPt = this.measurementPosition[this.measurementPosition.length - 1]
+            if (this.measurementPosition.length > 2) {
+                this.getSpaceDistance(this.measurementPosition,viewer)
+            } else if (this.measurementPosition.length == 2) {
+                //在三维场景中添加圆点
+                viewer.entities.add({
+                    name: '_range',
+                    id: "range",
+                    position: this.labelPt,
+                    point: {
+                        pixelSize: 5,
+                        color: Cesium.Color.RED,
+                        outlineColor: Cesium.Color.WHITE,
+                        outlineWidth: 2,
+                    },
+                    label: {
+                        text: '起 点',
+                        font: 'normal 18px SimHei',
+                        fillColor: Cesium.Color.ORANGE, // 文本颜色
+                        backgroundColor: Cesium.Color.WHITE, // 背景色
+                        style: Cesium.LabelStyle.FILL, // 文本样式,轮廓
+                        outlineWidth: 2, // 轮廓宽度
+                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 圆点位置
+                        horizontalOrigin: Cesium.HorizontalOrigin.LEFT, // 文本的位置
+                        pixelOffset: new Cesium.Cartesian2(0, -10), // 文本偏移量,Cartesian2
+                    }
+                });
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
+      // 鼠标移动事件
+      handler.setInputAction((ele) => {
+            let ray = viewer.camera.getPickRay(ele.endPosition) 
+            this.cartesian = viewer.scene.globe.pick(ray, viewer.scene) 
+            // 判断是否定义该对象
+            if (!Cesium.defined(this.cartesian)) {
+                return
+            }
+            if (this.measurementPosition.length >= 2) {
+                if (!Cesium.defined(this.poly)) {
+                    // 移动时路径绘制
+                    this.poly = new PolyLinePrimitive(this.measurementPosition)
+                } else {
+                  this.measurementPosition.pop()
+                  this.measurementPosition.push(this.cartesian)
+                }
+            }
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
+        // 创建线
+        var PolyLinePrimitive = (() => {
+            function line (positions) {
+                this.options = {
+                    name: '_range',
+                    polyline: {
+                        show: true,
+                        positions: [],
+                        material: Cesium.Color.CORNFLOWERBLUE, 
+                        width: 3, 
+                        clampToGround: true
+                    }
+                }
+                this.positions = positions
+                function init(){};
+            }
+
+            line.prototype.init = () => {
+                var update = () => {
+                    return this.positions
+                }
+                // 实时更改线的位置,更新线
+                this.options.polyline.positions = new Cesium.CallbackProperty(update, false)
+                viewer.entities.add(this.options)
+            }
+            return line
+        })()
+        //鼠标左键双击事件
+        handler.setInputAction((ele) => {
+            // 创建射线并获取交点
+            let ray = viewer.camera.getPickRay(ele.position);
+            this.cartesian = viewer.scene.globe.pick(ray, viewer.scene);
+            if (!Cesium.defined(this.cartesian))
+                return;
+            if (this.measurementPosition.length === 0) {
+              this.measurementPosition.push(this.cartesian.clone());
+            }
+            this.measurementPosition.push(this.cartesian);
+            // 记录鼠标单击时的节点位置,异步计算贴地距离
+            this.labelPt = this.measurementPosition[this.measurementPosition.length - 1];
+            if (this.measurementPosition.length > 2) {
+                this.getSpaceDistance(this.measurementPosition,viewer);
+            } else if (this.measurementPosition.length === 2) {
+                // 在三维场景中添加Label
+                viewer.entities.add({
+                    name: '_range',
+                    position: this.labelPt,
+                    point: {
+                        pixelSize: 5,
+                        color: Cesium.Color.RED,
+                        outlineColor: Cesium.Color.MINTCREAM,
+                        outlineWidth: 2,
+                    }
+                });
+            }
+            handler.destroy(); // 删除事件
+            handler = undefined;
+        }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
 
+    },
+    //通视
+    throughSight(viewer){
       
+
+    },
+     // 两点距离计算函数
+    getSpaceDistance (positions,viewer){
+      // 只计算最后一截,与前面累加, 因鼠标移动和左键单击事件,最后两个坐标点重复
+      let i = positions.length - 3
+      // 根据经纬度获取弧度
+      let pointCartographic1 = Cesium.Cartographic.fromCartesian(positions[i]) 
+      let pointCartographic2 = Cesium.Cartographic.fromCartesian(positions[i + 1])
+      this.getTerrainDistance(pointCartographic1, pointCartographic2,viewer)
+    },
+    // 贴地距离计算函数
+    getTerrainDistance (poin1, poin2,viewer) {
+            var geodesic = new Cesium.EllipsoidGeodesic()
+            geodesic.setEndPoints(poin1, poin2)
+            var s = geodesic.surfaceDistance
+            var cartoPts = [poin1]
+            for (let i = 1000; i < s; i += 1000) {
+                var cartoPt = geodesic.interpolateUsingSurfaceDistance(i)
+                cartoPts.push(cartoPt)
+            }
+            cartoPts.push(poin2)
+            // 返回两点之间的距离
+            var promise = Cesium.sampleTerrain(viewer.terrainProvider, 2, cartoPts)
+
+            promise.then(function (updatedPositions) {
+                for (let i = 0; i < updatedPositions.length - 1; i++) {
+                    var geoD = new Cesium.EllipsoidGeodesic()
+                    geoD.setEndPoints(updatedPositions[i], updatedPositions[i + 1])
+                    var innerS = geoD.surfaceDistance
+                    innerS = Math.sqrt(Math.pow(innerS, 2) + Math.pow(updatedPositions[i + 1].height - updatedPositions[i].height, 2))
+                    distance += innerS
+                }
+
+                // 在三维场景中添加 label
+                var textDisance = distance > 10000 ? (distance / 1000.0).toFixed(2) + '公里' : distance.toFixed(2) + '里'
+                viewer.entities.add({
+                    name: '_range',
+                    position: this.labelPt,
+                    point: {
+                        poixeSize: 4,
+                        color: Cesium.Color.RED,
+                        outlineColor: Cesium.Color.MINTCREAM,
+                        outlineWidth: 2
+                    },
+                    label: {
+                        text: textDisance,
+                        font: '18px sans-serif',
+                        fillColor: Cesium.Color.GOLD,
+                        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+                        outLineWidth: 2,
+                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+                        pixelOffset: new Cesium.Cartesian2(0, -10)
+                    }
+                })
+            }).catch(function(error) {  
+                // handle error  
+            });
     },
     /*根据camera高度近似计算当前层级*/
     heightToZoom(height) {
@@ -2370,7 +2597,7 @@ export default {
   margin-right: 0px !important;
 }
 
-.topbuttons {
+.top-rightbuttons {
   display: flex;
   flex-direction: column;
   align-items: center;
@@ -2381,7 +2608,7 @@ export default {
   top: 20px;
 }
 
-.bottombuttons {
+.middle-rightbuttons {
   display: flex;
   flex-direction: column;
   align-items: center;
@@ -2391,7 +2618,16 @@ export default {
   right: 20px;
   top: 380px;
 }
-
+.bottom-rightbuttons{
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-items: center;
+  position: absolute;
+  z-index: 999;
+  right: 20px;
+  bottom: 20px;
+}
 .image-title {
   margin-top: 10px;
   text-align: center;