Przeglądaj źródła

Merge remote-tracking branch 'origin/zpf'

zpf 1 rok temu
rodzic
commit
e3abfffb65

+ 38 - 19
src/components/Combinations/terrainCombination/TerrainCombination.vue

@@ -1,20 +1,25 @@
 <template>
-    <div id="terrainAnalysis" class="sm-panel" v-if="terrainShow" v-drag>
-      <div class="sm-content">
-        <div class="sm-panel-header">
-          <span :class="{titleColor:OperationShow}" class="title-txt" @click="choose(0)">{{Resource.TerrainOperation}}</span>
-          <span :class="{titleColor:floodShow}" class="title-txt" @click="choose(1)">{{Resource.FloodAnalysis}}</span>
-          <span :class="{titleColor:slopeShow}" class="title-txt" @click="choose(2)">{{Resource.terrainSlope}}</span>
-          <span :class="{titleColor:isolineShow}" class="title-txt" @click="choose(3)">{{Resource.isoline}}</span>
-          <span class="closeBtn" @click="toggleVisibility">&times;</span>
-        </div>
-        <!-- 调用子组件 -->
-        <sm3d-terrain-operation></sm3d-terrain-operation>
-        <sm3d-terrain-flood></sm3d-terrain-flood>
-        <sm3d-terrain-slope></sm3d-terrain-slope>
-        <sm3d-terrain-isoline></sm3d-terrain-isoline>
+  <div id="terrainAnalysis" class="sm-panel" v-if="terrainShow" v-drag>
+    <div class="sm-content">
+      <div class="sm-panel-header">
+        <span :class="{ titleColor: OperationShow }" class="title-txt" @click="choose(0)">{{ Resource.TerrainOperation
+        }}</span>
+        <span :class="{ titleColor: floodShow }" class="title-txt" @click="choose(1)">{{ Resource.FloodAnalysis }}</span>
+        <span :class="{ titleColor: slopeShow }" class="title-txt" @click="choose(2)">{{ Resource.terrainSlope }}</span>
+        <span :class="{ titleColor: isolineShow }" class="title-txt" @click="choose(3)">{{ Resource.isoline }}</span>
+        <span :class="{ titleColor: isCutFillShow }" class="title-txt" @click="choose(4)">地形平整估算</span>
+
+        <span class="closeBtn" @click="toggleVisibility">&times;</span>
       </div>
+      <!-- 调用子组件 -->
+      <sm3d-terrain-operation></sm3d-terrain-operation>
+      <sm3d-terrain-flood></sm3d-terrain-flood>
+      <sm3d-terrain-slope></sm3d-terrain-slope>
+      <sm3d-terrain-isoline></sm3d-terrain-isoline>
+
+      <TerrainCutFillAnalysis></TerrainCutFillAnalysis>
     </div>
+  </div>
 </template>
 
 <script>
@@ -43,6 +48,11 @@ export default {
     terrainShow: function () {
       return this.sharedState.toolBar[5];
     },
+    isCutFillShow: function () {
+
+      return this.sharedState.terrain[4];
+
+    },
   },
 
   methods: {
@@ -60,19 +70,22 @@ export default {
       }
       switch (i) {
         case 0:
-          store.setTerrainAction([1, 0, 0, 0]);
+          store.setTerrainAction([1, 0, 0, 0, 0]);
           break;
         case 1:
-          store.setTerrainAction([0, 1, 0, 0]);
+          store.setTerrainAction([0, 1, 0, 0, 0]);
           break;
         case 2:
-          store.setTerrainAction([0, 0, 1, 0]);
+          store.setTerrainAction([0, 0, 1, 0, 0]);
           break;
         case 3:
-          store.setTerrainAction([0, 0, 0, 1]);
+          store.setTerrainAction([0, 0, 0, 1, 0]);
+          break;
+        case 4://填挖方
+          store.setTerrainAction([0, 0, 0, 0, 1]);
           break;
         default:
-          store.setTerrainAction([1, 0, 0, 0]);
+          store.setTerrainAction([1, 0, 0, 0, 0]);
       }
     },
   },
@@ -83,4 +96,10 @@ export default {
   },
 };
 </script>
+<style lang="scss" scoped>
+#terrainAnalysis {
+  width: 400px;
+  max-width: 420px;
+}
+</style>
 

+ 150 - 0
src/components/TerrainAnalysis/TerrainCutFillAnalysis/CutFillAnalysis.js

@@ -0,0 +1,150 @@
+
+export default class CutFillAnalysis {
+  constructor(viewer, precision) {
+    if (!viewer) throw new Error("no viewer object!");
+    this.viewer = viewer;
+    this.maxHeigh = -1000000;
+    this.eName = "三角面";
+
+  }
+  createPolygonGeo(points) {
+    //计算网格粒度-精度
+    let granularity = Math.PI / Math.pow(2, 11);
+    granularity = granularity / this.precision;
+
+    let polygonGeometry = new Cesium.PolygonGeometry.fromPositions({
+      positions: points,
+      vertexFormat: Cesium.PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
+      granularity: granularity,
+    });
+    //创建自定义平面几何体
+    this.geom = new Cesium.PolygonGeometry.createGeometry(polygonGeometry);
+  }
+  VolumeAnalysis(points, height, extrudedHeight) {
+    this.createPolygonGeo(points);
+
+    let cutArea = 0,
+      cutVolume = 0,
+      fillArea = 0,
+      fillVolume = 0,
+      noArea = 0;
+    const indices = this.geom.indices; //获取顶点索引数据
+    const positions = this.geom.attributes.position.values;
+    for (let index = 0; index < indices.length; index += 3) {
+
+      const pos0 = this.returnPosition(positions, indices[index]);
+      const pos1 = this.returnPosition(positions, indices[index + 1]);
+      const pos2 = this.returnPosition(positions, indices[index + 2]);
+      // this.viewer.entities.add({
+      //   name: this.eName,
+      //   polygon: {
+      //     show:false,
+      //     hierarchy: [pos0.heightPos, pos1.heightPos, pos2.heightPos],
+      //     // perPositionHeight:
+      //     //为true时,height将失去作用,extrudedHeight则从地表计算高度作为多边形的高;
+      //     // 为false时,height将从地表计算高度,多边形就会有离地高度,extrudedHeight = height+你想要的多边形高度。例:假如你想创建一个距离地表500米的多边形,它的高度为100,height:500,extrudedHeight:500+100
+      //     perPositionHeight: true,
+      //     material: Cesium.Color.fromRandom({
+      //       alpha: 0.8
+      //     }),
+      //     // height: this.height,
+      //     extrudedHeight: this.extrudedHeight,
+      //     outline: true,
+      //     outlineColor: Cesium.Color.BLACK,
+      //   },
+      // });
+      //水平状态下三角形面积
+      const area = this.computeArea4Triangle(
+        pos0.noHeightPos,
+        pos1.noHeightPos,
+        pos2.noHeightPos
+      );
+      //计算三个点的均高
+      const height = (pos0.height + pos1.height + pos2.height) / 3;
+      if (height < extrudedHeight) {
+        // 需要填方的部分
+        fillArea += area;
+        const volume = area * (extrudedHeight - height);
+        fillVolume += volume;
+      } else if (height == extrudedHeight) {
+        noArea += area;
+      } else {
+        // 需要挖方的部分
+        cutArea += area;
+        const volume = area * (height - extrudedHeight);
+        cutVolume += volume;
+      }
+    }
+    const allArea = cutArea + fillArea + noArea;
+    this.result = {
+      allArea,
+      cutArea,
+      cutVolume,
+      fillArea,
+      fillVolume,
+      noArea,
+    };
+    return cutVolume;
+  }
+
+  computeCentroid4Polygon(positions) {
+    let x = [],
+      y = [];
+    let allX = 0,
+      allY = 0;
+    for (let i = 0; i < positions.length; i++) {
+      let cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
+      allX += cartographic.longitude;
+      allY += cartographic.latitude;
+      x.push(cartographic.longitude);
+      y.push(cartographic.latitude);
+    }
+    let centroidx = allX / positions.length;
+    let centroidy = allY / positions.length;
+    const Cartographic = new Cesium.Cartographic(centroidx, centroidy);
+    return Cesium.Cartesian3.fromRadians(
+      Cartographic.longitude,
+      Cartographic.latitude,
+      this.maxHeigh + 30
+    );
+  }
+  /**
+   * 海伦公式求取三角形面积
+   * @param {*} pos1
+   * @param {*} pos2
+   * @param {*} pos3
+   * @returns 三角形面积㎡
+   */
+  computeArea4Triangle(pos1, pos2, pos3) {
+    let a = Cesium.Cartesian3.distance(pos1, pos2);
+    let b = Cesium.Cartesian3.distance(pos2, pos3);
+    let c = Cesium.Cartesian3.distance(pos3, pos1);
+    let S = (a + b + c) / 2;
+    return Math.sqrt(S * (S - a) * (S - b) * (S - c));
+  }
+  returnPosition(positions, index) {
+    let cartesian = new Cesium.Cartesian3(
+      positions[index * 3],
+      positions[index * 3 + 1],
+      positions[index * 3 + 2]
+    );
+    let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
+    let height = this.viewer.scene.globe.getHeight(cartographic);
+    if (height > this.maxHeigh) {
+      this.maxHeigh = height;
+    }
+    return {
+      heightPos: Cesium.Cartesian3.fromRadians(
+        cartographic.longitude,
+        cartographic.latitude,
+        height
+      ),
+      noHeightPos: Cesium.Cartesian3.fromRadians(
+        cartographic.longitude,
+        cartographic.latitude,
+        0
+      ),
+      height: height,
+    };
+  }
+}

+ 176 - 0
src/components/TerrainAnalysis/TerrainCutFillAnalysis/TerrainCutFillAnalysis.vue

@@ -0,0 +1,176 @@
+<template>
+  <div v-show="isCutFill" class="cut_fill_box">
+    <div class="cut_fill_centent1">
+      设计高度(米):
+      <el-input class="cut_fill_input" v-model="height" placeholder=""></el-input>
+      <br>
+      土石方量(立方米):
+      <el-input class="cut_fill_input" v-model="result" placeholder=""></el-input>
+
+    </div>
+    <div class="cut_fill_Buttons">
+      <el-button size="mini" type="primary" @click="draw">绘制</el-button>
+      <el-button size="mini" type="primary" @click="clear">清楚</el-button>
+
+    </div>
+  </div>
+</template>
+
+<script>
+//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+import CutFillAnalysis from "./CutFillAnalysis.js"
+let cutFillAnalysis = null;
+export default {
+  name: "TerrainCutFillAnalysis",
+  components: {},
+  data() {
+
+    return {
+      input: '', sharedState: store.state,
+      height: 300,
+      result: null,
+      handler_Cut_fill: new Cesium.DrawHandler(viewer, Cesium.DrawMode.Polygon, 0)
+    };
+  },
+  //监听属性 类似于data概念
+  computed: {
+
+    isCutFill: function () {
+      return this.sharedState.terrain[4];
+    },
+  },
+  //监控data中的数据变化
+  watch: {},
+  //方法集合
+  methods: {
+    draw() {
+      //绘制多边形
+      const that = this;
+      that.handler_Cut_fill.clear();
+      viewer.scene.globe.removeAllExcavationRegion();
+
+      that.handler_Cut_fill.activeEvt.addEventListener(function (isActive) {
+        if (isActive == true) {
+          viewer.enableCursorStyle = false;
+          viewer._element.style.cursor = '';
+          // $('body').removeClass('drawCur').addClass('drawCur');
+        }
+        else {
+          viewer.enableCursorStyle = true;
+          // $('body').removeClass('drawCur');
+        }
+      });
+      that.handler_Cut_fill.movingEvt.addEventListener(function (windowPosition) {
+        if (windowPosition.x < 200 && windowPosition.y < 150) {
+          tooltip.setVisible(false);
+          return;
+        }
+        if (that.handler_Cut_fill.isDrawing) {
+          tooltip.showAt(windowPosition, '<p>点击确定开挖区域中间点</p><p>右键单击结束绘制,进行开挖</p>');
+        }
+        else {
+          tooltip.showAt(windowPosition, '<p>点击绘制开挖区域第一个点</p>');
+        }
+      });
+      that.handler_Cut_fill.drawEvt.addEventListener(function (result) {
+        if (!result.object.positions) {
+          tooltip.showAt(result, '<p>请绘制正确的多边形</p>');
+          that.handler_Cut_fill.polygon.show = false;
+          that.handler_Cut_fill.polyline.show = false;
+          that.handler_Cut_fill.deactivate();
+          that.handler_Cut_fill.activate();
+          return;
+        };
+        var array = [].concat(result.object.positions);
+
+        let cutVolume = cutFillAnalysis.VolumeAnalysis(array, that.height, that.height);
+        that.result = cutVolume;
+        tooltip.setVisible(false);
+        var positions = [];
+        for (var i = 0, len = array.length; i < len; i++) {
+          var cartographic = Cesium.Cartographic.fromCartesian(array[i]);
+          var longitude = Cesium.Math.toDegrees(cartographic.longitude);
+          var latitude = Cesium.Math.toDegrees(cartographic.latitude);
+          var h = cartographic.height;
+
+          if (positions.indexOf(longitude) == -1 && positions.indexOf(latitude) == -1) {
+            positions.push(longitude);
+            positions.push(latitude);
+            positions.push(h);
+          }
+        }
+        viewer.scene.globe.removeAllExcavationRegion();
+        viewer.scene.globe.addExcavationRegion({
+          name: 'ggg',
+          position: positions,
+          height: that.height,
+          transparent: false
+        });
+
+        that.handler_Cut_fill.polygon.show = false;
+        that.handler_Cut_fill.polyline.show = false;
+        that.handler_Cut_fill.deactivate();
+        // that.handler_Cut_fill.activate();
+      });
+      that.handler_Cut_fill.activate();
+    },
+    clear() {
+      const that = this;
+      that.handler_Cut_fill.clear();
+      viewer.scene.globe.removeAllExcavationRegion();
+
+    }
+  },
+  beforeCreate() { }, //生命周期 - 创建之前
+  created() {
+
+    const terrainP = new Cesium.CesiumTerrainProvider({
+      url: 'http://192.168.60.3:8099/iserver/services/3D-local3DCache-SanYaDSMHuanCun/rest/realspace/datas/dsm@dsm',
+      isSct: true//地形服务源自SuperMap iServer发布时需设置isSct为true
+    });
+    viewer.terrainProvider = terrainP;
+
+    viewer.scene.globe.depthTestAgainstTerrain = false;
+
+
+  }, //生命周期 - 创建完成(可以访问当前this实例)
+  beforeMount() { }, //生命周期 - 挂载之前
+  mounted() {
+
+    cutFillAnalysis = new CutFillAnalysis(
+      viewer,
+      80,
+    );
+  }, //生命周期 - 挂在完成
+  beforeUpdate() { }, //生命周期 - 更新之前
+  updated() { }, //生命周期 - 更新之后
+  beforeDestroy() { }, //生命周期 - 销毁之前
+  destroy() { },//生命周期 - 销毁完成
+  activated() { }, //若组件实例是 <KeepAlive> 缓存树的一部分,当组件被插入到 DOM 中时调用。
+  deactivated() { } //若组件实例是 <KeepAlive> 缓存树的一部分,当组件从 DOM 中被移除时调用。
+};
+</script>
+<style lang="scss" scoped>
+.cut_fill_centent1 {
+  width: 100%;
+  text-align: left;
+  margin-left: 10%;
+  margin-top: 5%;
+  margin-bottom: 6%;
+}
+
+.cut_fill_input {
+  display: inline-block;
+  width: 50%
+}
+
+.cut_fill_input:first-child {
+  margin-left: 7%;
+  margin-bottom: 5%;
+}
+
+.cut_fill_Buttons {
+  margin-bottom: 5%;
+
+}
+</style>

+ 2 - 0
src/components/TerrainAnalysis/TerrainCutFillAnalysis/index.js

@@ -0,0 +1,2 @@
+import TerrainCutFillAnalysis from './TerrainCutFillAnalysis';
+export default TerrainCutFillAnalysis;

+ 3 - 0
src/components/index.js

@@ -45,6 +45,8 @@ import TerrainOperation from "./TerrainAnalysis/TerrainOperation/index.js";
 import TerrainFlood from "./TerrainAnalysis/TerrainFlood/index.js";
 import TerrainSlope from "./TerrainAnalysis/TerrainSlope/index.js";
 import TerrainIsoLine from "./TerrainAnalysis/TerrainIsoLine/index.js";
+import TerrainCutFill from "./TerrainAnalysis/TerrainCutFillAnalysis/index.js";
+
 
 // 编辑部分组件
 import addPonit from "./OnlineEdit/addPonit/index.js";
@@ -124,6 +126,7 @@ const components = [
     TerrainFlood,
     TerrainSlope,
     TerrainIsoLine,
+    TerrainCutFill,
     //编辑
     addPonit,
     addPolyline,

+ 3 - 3
src/store/store.js

@@ -9,7 +9,7 @@ var store2 = {
         toolBar: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         addLayer: [1, 0, 0],
         sceneAtttribute: [1, 0, 0, 0, 0],
-        terrain: [1, 0, 0, 0],
+        terrain: [1, 0, 0, 0, 0],
         clip: [1, 0, 0, 0],
         analysis: [1, 0, 0, 0, 0, 0],
         cityPlan: [1, 0, 0, 0, 0],
@@ -29,7 +29,7 @@ var store2 = {
         isEditZ: false,
         vectorlayerlist: [],
         modellayerlist: [],
-        chooseLayer:[]
+        chooseLayer: []
     },
     setisInitViewer(newValue) {
         this.state.isInitViewer = newValue;
@@ -63,7 +63,7 @@ var store2 = {
     },
     // 设置导航工具显隐
     setToolBarAction(newValue) {
-        if (typeof(newValue) != "undefined") {
+        if (typeof (newValue) != "undefined") {
             if (this.state.toolBarActive != newValue) {
                 this.hideToolBar();
             }

+ 1 - 1
src/views/cockpitNew/gdbh.vue

@@ -85,7 +85,7 @@ export default {
             data.forEach(function (value, index, obj) {
                 value.pm = pm[index]
             })
-            console.log('ssss', data)
+            // console.log('ssss', data)
             const colors = ['rgb(96,149,239)', 'rgb(239,157,147)', 'rgb(232,191,72)', 'rgb(189,147,227)']
             const chartData = data.map((item, index) => ({
                 value: item.value,