vue + cesium 洪水淹没分析完整示例

14 篇文章 10 订阅

目录

一、洪水淹没分析效果

二、部分核心代码

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>

完整项目示例下载

  • 5
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
骋天淹没分析系统 骋天淹没分析系统是以三维地理信息系统为基础平台,基于数字高程模型(DEM)格网模型,通过改进迭代种子蔓延算法将淹没分析结果直观在三维地理系统系统上呈现出来。 骋天淹没分析系统应用于水库的库区淹没分析时,设置好起止水位和终止水位,以三维的形式呈现库区淹没区域,根据不同是水深来计算库容量,移民数量、直接经济影响和间接经济影响。可将数据制作成柱状图、饼状图、曲线图等多种多样的统计图;能够根据业务流程和用户要求定制各类表格,进行业务报表输出;还能按某一要素生成范围图、点密度图、分级符号图等,进行专题图分析,形象直观地反映防洪要素的时空变化规律。 骋天淹没分析系统亦可应用于洪水淹没分析时,根据洪水演进过程,配合数字化地图,利用三维模型,计算洪水淹没范围和淹没水深,并动态显示淹没区域并动态显示淹没区域,计算人口、家庭财产、工商、企业、农业、林业、渔业和畜牧业等淹没信息。并可根据预报调度、实时调度和历史调度等不同洪水下泻过程,计算分析洪水淹没损失,显示淹没分布状况,从而得出最佳洪水调度预案,提供泄洪区域内人员撤退、避灾转移和救灾物资供应等最佳行动路线。 广西骋天信息科技有限公司 网站 www.gxchengtian.com
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向着太阳往前冲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值