Cesium洪水淹没分析 洪水淹没高度的上涨与下降

最近在基于cesium做水利项目的淹没分析 因为真实的洪水情况下,对于不同的地势来说 每个淹没区间的不同时刻水位高度肯定是不一样的 所以要求对多河段的高度做一个动态的水位上涨与下降的效果 不同河段水位高要以不一样的颜色显示  以下是其中一个河段的实现的代码参考

先看看效果吧

cesium淹没分析

初始化地图

<template>
  <div class="water-page">
    <div id="cesiumContainer"></div>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import FloodAnalysis from "./FloodAnalysis.js";
const initMap = () => {
  CesiumMap = new Cesium.Viewer("cesiumContainer", {
    geocoder: false,
    animation: false,
    timeline: false,
    infoBox: false,
    baseLayerPicker: false,
    fullscreenButton: false,
    homeButton: false,
    sceneModePicker: false,
    navigationHelpButton: false,
    imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
      url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
    }),
    CreditsDisplay: false,
    selectionIndicator: false,
    scene3DOnly: true,
    requestRenderMode: true,
    terrainProvider: Cesium.createWorldTerrain({
      requestVertexNormals: true,
      requestWaterMask: true,
    }),
    terrainProvider: new Cesium.ArcGISTiledElevationTerrainProvider({
      url: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer",
    }),
  });
  // CesiumMap.timeline.container.style.visibility = "hidden";
  CesiumMap._cesiumWidget._creditContainer.style.display = "none"; //LOGO显示
  CesiumMap.scene.globe.depthTestAgainstTerrain = true;
  CesiumMap.camera.setView({
    destination :  Cesium.Cartesian3.fromDegrees(105.5793, 30.5305127, 1000),
    orientation: {
        heading :0, // 相机方向指向当地东向
        pitch : Cesium.Math.toRadians(-15),    // 再将相机方向转向地心,此时Up方向指向当地东向
        roll : 0.0                             
    }
});
  createWater();
};
/**
 * 获取数据创建水面
 */
const waterColor = ref("rgba(183, 149, 75, 0.91)");
const createWater = () => {
  let data = require("./flood_data.json");
  let waterEntity = new FloodAnalysis(CesiumMap, {
    ...data,
    waterColor: waterColor.value,
    show: true,
  });
};

onMounted(() => {
  initMap();
});
</script>
<style lang="scss" scoped>
.water-page {
  width: 100vw;
  height: 100vh;
  #cesiumContainer {
    width: 100%;
    height: 100%;
  }
}
</style>

关键代码

/**
 * @description 淹没分析函数,通过拉伸面的高度来进行分析
 */
class FloodAnalysis {
  constructor(viewer, options) {
    if (!viewer) throw new Error("no viewer object!");
    this.viewer = viewer;
    this.positions = this.CoorsFormt(options.polygon);
    this.times_height = options.times_height;
    this.currentIndex = 0;
    this.initialHeight = this.times_height[this.currentIndex];
    this.targertHeight = this.times_height[this.currentIndex + 1];
    this.increaseHeight = this.targertHeight - this.initialHeight;
    this.waterColor = options.waterColor;
    this.show = options.show;
    this.start = null;
    this.init();
    this.getNowHeight();
  }
  CoorsFormt(coors) {
    let Arr = [];
    coors.forEach((coor) => {
      Arr.push(coor[0]);
      Arr.push(coor[1]);
    });
    return Arr;
  }
  async init() {
    this.viewerSET();
    // this.start = Cesium.JulianDate.now(new Date());
    const self = this;
    this.property = this.computeFlight(this.times_height);
    this.viewer.scene.globe.depthTestAgainstTerrain = true;
  
    this.entity = this.viewer.entities.add({
      show: this.show,
      availability: new Cesium.TimeIntervalCollection([
        new Cesium.TimeInterval({
          start: this.start,
          stop: Cesium.JulianDate.addMinutes(
            this.start,
            10 * this.times_height.length,
            new Cesium.JulianDate()
          ),
        }),
      ]),
      polygon: {
        hierarchy: new Cesium.PolygonHierarchy(
          Cesium.Cartesian3.fromDegreesArray(this.positions)
        ),
        extrudedHeight: this.property,
        height:this.property,
        material: Cesium.Color.fromCssColorString(this.waterColor)
      },
    });
  }
/*
*时间水位与时间关联 
*/
  computeFlight(data) {
    let property = new Cesium.SampledProperty(Number);
    data.forEach((item, i) => {
      property.addSample(
        Cesium.JulianDate.addMinutes(
          this.start,
          10 * i,
          new Cesium.JulianDate()
        ),
        item
      );
    });
    return property;
  }
/*
*设置时间
*/
  viewerSET() {
    this.start = Cesium.JulianDate.fromDate(new Date());
    this.start = Cesium.JulianDate.addHours(
      this.start,
      8,
      new Cesium.JulianDate()
    );
    this.stop = Cesium.JulianDate.addMinutes(
      this.start,
      10 * this.times_height.length,
      new Cesium.JulianDate()
    );
    this.viewer.clock.startTime = this.start.clone();
    this.viewer.clock.currentTime = this.start.clone();
    this.viewer.clock.stopTime = this.stop.clone();
    // this.viewer.clock.multiplier = 3600
    if (this.viewer.timeline)
      this.viewer.timeline.zoomTo(this.start, this.stop);
    this.viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
  }
  /**
   * 获取实时水面高度
   */
  getNowHeight() {
    const self = this;
    this.viewer.clock.onTick.addEventListener(function () {
      if (self.increaseHeight > 0) {
        if (self.initialHeight > self.targertHeight) {
          self.currentIndex += 1;
          if (self.currentIndex > self.times_height.length - 2) {
            self.currentIndex = 0;
          }
          self.initialHeight = self.times_height[self.currentIndex];
          self.targertHeight = self.times_height[self.currentIndex + 1];
          self.increaseHeight = self.targertHeight - self.initialHeight;
        }
      }
      if (self.increaseHeight < 0) {
        if (self.initialHeight < self.targertHeight) {
          self.currentIndex += 1;
          if (self.currentIndex > self.times_height.length - 2) {
            self.currentIndex = 0;
          }
          self.initialHeight = self.times_height[self.currentIndex];
          self.targertHeight = self.times_height[self.currentIndex + 1];
          self.increaseHeight = self.targertHeight - self.initialHeight;
        }
      }
      self.initialHeight += self.increaseHeight / 100;
    });
  }
 
  /**
   * 改变颜色
   * @param {水体颜色} val
   */
  changeWaterColor(val) {
    this.entity.polygon.material = val;
  }
  /**
   * 隐藏与显示
   * @param {Boolean} val
   */
  changeWaterShow(val) {
    this.entity.show = val;
  }

  destroy() {
    this.viewer.entities.remove(this.entity);
    delete this.entity;
    delete this.positions;
    delete this.initialHeight;
    delete this.targertHeight;
    delete this.increaseHeight;
  }
}

export default FloodAnalysis;

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 62
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 62
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值