目录

一、洪水淹没分析效果

二、部分核心代码

1、绘制多边形范围

2、处理多边形区域的最大和最小高程 

三、JS完整代码


一、洪水淹没分析效果

二、部分核心代码

1、绘制多边形范围

     /**
      * @author: 
      * @Date: 2022-04-11 16:44:02
      * @note: 注意事项
      * @description: 绘制范围
      */    
     drawExtent () {
      // 开启深度检测
      window.viewer.scene.globe.depthTestAgainstTerrain = true
      handler = new Cesium.ScreenSpaceEventHandler(window.viewer.canvas)

      handler.setInputAction((event) => {
        const earthPosition = viewer.scene.pickPosition(event.position);
        if (Cesium.defined(earthPosition)) {
          if (activeShapePoints.length === 0) {
            floatingPoint = this.createPoint(earthPosition);
            activeShapePoints.push(earthPosition);
            const dynamicPositions = new Cesium.CallbackProperty(function () {
              return new Cesium.PolygonHierarchy(activeShapePoints);
            }, false);
            activeShape = this.drawShape(dynamicPositions, Cesium.Color.fromBytes(64, 157, 253, 50));
          }
          activeShapePoints.push(earthPosition);
          this.tempEntities.push(this.createPoint(earthPosition))
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      handler.setInputAction((event) => {
        if (Cesium.defined(floatingPoint)) {
          const newPosition = viewer.scene.pickPosition(event.endPosition);
          if (Cesium.defined(newPosition)) {
            floatingPoint.position.setValue(newPosition);
            activeShapePoints.pop();
            activeShapePoints.push(newPosition);
          }
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      handler.setInputAction((event) => {
        activeShapePoints.pop()
        if(activeShapePoints.length < 3) return
        
        this.tempEntities.push(this.drawPolyline(activeShapePoints))
        let ploy = this.drawShape(activeShapePoints, Cesium.Color.fromBytes(64, 157, 253, 20))
        this.tempEntities.push(ploy)
        this.getAreaHeight(activeShapePoints)
        
        window.viewer.entities.remove(floatingPoint);
        window.viewer.entities.remove(activeShape);
        floatingPoint = undefined;
        activeShape = undefined;
        handler.destroy()// 关闭事件句柄
        handler = null
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    },

2、处理多边形区域的最大和最小高程 

    /**
     * @author: 
     * @Date: 2022-04-11 16:48:43
     * @note: 注意事项
     * @description: 获取区域内最大和最小高程
     * @param {*} positions
     */    
    getAreaHeight (positions) {
      let startP = positions[0]
      let endP = positions[positions.length -1]
      if(startP.x != endP.x && startP.y != endP.y && startP.z != endP.z) positions.push(positions[0])

      const tempPoints = []
      for (let i = 0; i < positions.length; i++) {
        var ellipsoid = window.viewer.scene.globe.ellipsoid
        var cartographic = ellipsoid.cartesianToCartographic(positions[i])
        var lat = Cesium.Math.toDegrees(cartographic.latitude)
        var lng = Cesium.Math.toDegrees(cartographic.longitude)
        tempPoints.push([lng, lat])
      }
      var line = turf.lineString(tempPoints)
      var chunk = turf.lineChunk(line, 10, {units: 'meters'});

      const tempArray = []
      chunk.features.forEach(f => {
        f.geometry.coordinates.forEach(c => {
          tempArray.push(Cesium.Cartographic.fromDegrees(c[0], c[1]))
        })
      })

      var promise = Cesium.sampleTerrainMostDetailed(window.viewer.terrainProvider, tempArray)
      Cesium.when(promise, (updatedPositions) => {
        const max = Math.max.apply(Math, updatedPositions.map(item => { return item.height }))
        const min = Math.min.apply(Math, updatedPositions.map(item => { return item.height }))
        this.waterHeight = Math.ceil(min)
        this.minWaterHeight = Math.ceil(min)
        this.maxWaterHeight = Math.ceil(max)
        // 禁用绘制按钮
        this.isDraw = !this.isDraw
      })
    },

三、JS完整代码

<script>
import * as turf from '@turf/turf'

let activeShapePoints = []
let floatingPoint = undefined
let activeShape = undefined
let handler = undefined

export default {
  data() {
    return {
      isDraw: false,
      maxWaterHeight: 2000,
      minWaterHeight: 0,
      warningWaterHeight: 0, // 预警高度
      waterHeight: 0,
      waterHeightShow: false,
      speed: '1',
      waterHeightTimeer: 0,
      waterPrimitive: undefined,
      tempEntities: []
    }
  },
  beforeDestroy() {
    // 关闭当前组件之前清除所有数据
    this.clearAllEntities()
  },
  methods: {
     /**
      * @author: 
      * @Date: 2022-04-11 16:44:02
      * @note: 注意事项
      * @description: 绘制范围
      */    
     drawExtent () {
      // 开启深度检测
      window.viewer.scene.globe.depthTestAgainstTerrain = true
      handler = new Cesium.ScreenSpaceEventHandler(window.viewer.canvas)

      handler.setInputAction((event) => {
        const earthPosition = viewer.scene.pickPosition(event.position);
        if (Cesium.defined(earthPosition)) {
          if (activeShapePoints.length === 0) {
            floatingPoint = this.createPoint(earthPosition);
            activeShapePoints.push(earthPosition);
            const dynamicPositions = new Cesium.CallbackProperty(function () {
              return new Cesium.PolygonHierarchy(activeShapePoints);
            }, false);
            activeShape = this.drawShape(dynamicPositions, Cesium.Color.fromBytes(64, 157, 253, 50));
          }
          activeShapePoints.push(earthPosition);
          this.tempEntities.push(this.createPoint(earthPosition))
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

      handler.setInputAction((event) => {
        if (Cesium.defined(floatingPoint)) {
          const newPosition = viewer.scene.pickPosition(event.endPosition);
          if (Cesium.defined(newPosition)) {
            floatingPoint.position.setValue(newPosition);
            activeShapePoints.pop();
            activeShapePoints.push(newPosition);
          }
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      handler.setInputAction((event) => {
        activeShapePoints.pop()
        if(activeShapePoints.length < 3) return
        
        this.tempEntities.push(this.drawPolyline(activeShapePoints))
        let ploy = this.drawShape(activeShapePoints, Cesium.Color.fromBytes(64, 157, 253, 20))
        this.tempEntities.push(ploy)
        this.getAreaHeight(activeShapePoints)
        
        window.viewer.entities.remove(floatingPoint);
        window.viewer.entities.remove(activeShape);
        floatingPoint = undefined;
        activeShape = undefined;
        handler.destroy()// 关闭事件句柄
        handler = null
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    },
    
    /**
     * @author: 
     * @Date: 2022-04-11 16:48:43
     * @note: 注意事项
     * @description: 获取区域内最大最小高程
     * @param {*} positions
     */    
    getAreaHeight (positions) {
      let startP = positions[0]
      let endP = positions[positions.length -1]
      if(startP.x != endP.x && startP.y != endP.y && startP.z != endP.z) positions.push(positions[0])

      const tempPoints = []
      for (let i = 0; i < positions.length; i++) {
        var ellipsoid = window.viewer.scene.globe.ellipsoid
        var cartographic = ellipsoid.cartesianToCartographic(positions[i])
        var lat = Cesium.Math.toDegrees(cartographic.latitude)
        var lng = Cesium.Math.toDegrees(cartographic.longitude)
        tempPoints.push([lng, lat])
      }
      var line = turf.lineString(tempPoints)
      var chunk = turf.lineChunk(line, 10, {units: 'meters'});

      const tempArray = []
      chunk.features.forEach(f => {
        f.geometry.coordinates.forEach(c => {
          tempArray.push(Cesium.Cartographic.fromDegrees(c[0], c[1]))
        })
      })

      var promise = Cesium.sampleTerrainMostDetailed(window.viewer.terrainProvider, tempArray)
      Cesium.when(promise, (updatedPositions) => {
        const max = Math.max.apply(Math, updatedPositions.map(item => { return item.height }))
        const min = Math.min.apply(Math, updatedPositions.map(item => { return item.height }))
        this.waterHeight = Math.ceil(min)
        this.minWaterHeight = Math.ceil(min)
        this.maxWaterHeight = Math.ceil(max)
        // 禁用绘制按钮
        this.isDraw = !this.isDraw
      })
    },

    /**
     * @author: 
     * @Date: 2022-04-11 16:46:47
     * @note: 注意事项
     * @description: 创建点
     * @param {*} worldPosition
     */
    createPoint(worldPosition) {
      const point = window.viewer.entities.add({
        position: worldPosition,
        point: {
          color: Cesium.Color.SKYBLUE,
          pixelSize: 5,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        },
      });
      return point;
    },

    /**
     * @author: 
     * @Date: 2022-04-11 16:46:37
     * @note: 注意事项
     * @description: 绘制多边形
     * @param {*} positionData
     * @param {*} mat
     */
    drawShape(positionData, mat) {
      let shape = window.viewer.entities.add({
        polygon: {
          hierarchy: positionData,
          material: mat,
          outline: true,
          outlineColor: Cesium.Color.SKYBLUE,
          outlineWidth: 4,
        }
      });
      return shape;
    },

    /**
     * @author: 
     * @Date: 2022-04-11 16:46:11
     * @note: 注意事项
     * @description: 绘制线
     * @param {*} positions
     */
    drawPolyline (positions) {
      if (positions.length < 1) return

      let startP = positions[0]
      let endP = positions[positions.length -1]
      if(startP.x != endP.x && startP.y != endP.y && startP.z != endP.z) positions.push(positions[0])

      return window.viewer.entities.add({
        name: 'polyline',
        polyline: {
          positions: positions,
          width: 2.0,
          material: Cesium.Color.SKYBLUE,
          clampToGround: true
        }
      })
    },

    /**
     * @author: 
     * @Date: 2022-04-11 16:45:05
     * @note: 注意事项
     * @description: 淹没分析
     */
    induationAnalysis () {
      if(Number(this.warningWaterHeight) < Number(this.minWaterHeight) || Number(this.warningWaterHeight) > Number(this.maxWaterHeight)){
        this.$message({
          message: '预警高度必须在最小高度和最小高度之间',
          type: 'warning'
        });
        return
      }
      
      let shape = window.viewer.entities.add({
        polygon: {
          hierarchy: activeShapePoints,
          material: Cesium.Color.fromBytes(64, 157, 253, 20),
          extrudedHeight: Number(this.warningWaterHeight),
          outline: true,
          outlineColor: Cesium.Color.RED,
          outlineWidth: 4,
          // perPositionHeight: true
        }
      });
      this.tempEntities.push(shape)

      this.waterHeightShow = true
      this.waterHeight = Number(this.minWaterHeight)
      const en = window.viewer.entities.add({
        polygon: {
          hierarchy: activeShapePoints,
          extrudedHeight: new Cesium.CallbackProperty(() =>{
            return this.waterHeight
          }, false),
          material: Cesium.Color.fromBytes(64, 157, 253, 150),
        }
      })
      this.tempEntities.push(en)

      this.waterHeightTimeer = setInterval(() => {
        this.waterHeight += Number(this.speed)

        let l = this.speed.split('.').length > 1 ? this.speed.split('.')[1].length : 0
        this.waterHeight = Number(this.waterHeight.toFixed(l))
        this.maxWaterHeight = Number(this.maxWaterHeight)
        this.minWaterHeight = Number(this.minWaterHeight)
        if (this.waterHeight > this.maxWaterHeight || this.waterHeight < this.minWaterHeight) {
          clearInterval(this.waterHeightTimeer)
          this.waterHeight = this.waterHeight > this.maxWaterHeight ? this.maxWaterHeight : this.minWaterHeight
        }

      }, 1000)
    },

    /**
     * @author: 
     * @Date: 2022-04-11 16:44:42
     * @note: 注意事项
     * @description: 清除当前页面所有数据
     */
    clearAllEntities () {
      if (this.waterHeightTimeer) {
        clearInterval(this.waterHeightTimeer)
      }
      this.positions = []
      const length = this.tempEntities.length
      for (let f = 0; f < length; f++) {
        window.viewer.entities.remove(this.tempEntities[f])
      }
      this.tempEntities = []
      this.waterHeightShow = false
      activeShapePoints = [];
      this.warningWaterHeight = 0
      this.isDraw = !this.isDraw
      floatingPoint = undefined
      activeShape = undefined
      if(handler){
        handler.destroy()// 关闭事件句柄
        handler = undefined
      }
    }
  }
}
</script>

完整项目示例下载

GitHub 加速计划 / vu / vue
207.55 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐