reat + cesium。 實現 初始化時自動定位,鼠標移動實時展示坐標及視角高度, 淹沒分析


只貼實現淹沒分析這塊的代碼。

import styles from './cesium.less';
import React from 'react';
import Cesium from 'cesium/Cesium';

Cesium.BingMapsApi.defaultKey = '必應地圖Key.具體請自己申請';


require('cesium/Widgets/widgets.css');

export default class CesiumPage extends React.Component {

  state = {
    log_String: '',
    lat_String: '',
    alti_String: '',
    adapCoordi: [],
    maxHeight: 0,
  }

  componentDidMount() {
   this.initCesium();
  }

  initCesium = () => {
    const url = 'https://dev.virtualearth.net';
    let viewer = new Cesium.Viewer('cesiumContainer', {
      scene3DOnly: true,
      selectionIndicator: false,
      //geocoder: false, //是否顯示地名查找控件
      //homeButton: true, 
      baseLayerPicker:false, //是否顯示圖層選擇控件
      // navigationHelpButton:false,
      //animation: false, // 是否創建動畫小器件,左下角儀表
      //timeline: false, //是否顯示時間線控件
      //vrButton: false, //是否展示VR按鈕
      //fullscreenButton: true, //右下角全屏按鈕
    });
    viewer.cesiumWidget.creditContainer.style.display = 'none';
    //使用必應地圖作為底圖
    viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({
      url: url,
      mapStyle: Cesium.BingMapsStyle.AERIAL
    }))
    //增加地形、
    viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
      url: "http://data.marsgis.cn/terrain",//中國地形
      //url: Cesium.IonResource.fromAssetId(1), //世界地形
      requestWaterMask: false, // 增加水文
      requestVertexNormals: false, //增加光線
    })
    //啟用深度測試以使地形后的物體被擋住
    viewer.scene.globe.depthTestAgainstTerrain = false;
    //綁定鼠標移動時,實時顯示坐標及高度
    this.coordinateShow(viewer);
    /* let initialPosition = new Cesium.Cartesian3.fromDegrees(107.5116,29.4605, 4120);
    let homeCameraView = {destination : initialPosition,};        
    viewer.scene.camera.setView(homeCameraView); */
    //設置鏡頭到具體位置及角度
    this.setPointAdress(viewer);

    this.viewer = viewer;
  }

  //鼠標移動實時顯示坐標及視角高度函數
  coordinateShow = (viewer) => {
    let _this = this,
        canvas= viewer.scene.canvas;
    //具體事件的實現
    let ellipsoid=viewer.scene.globe.ellipsoid;
    let handler = new Cesium.ScreenSpaceEventHandler(canvas);
    handler.setInputAction(function(movement){
        //捕獲橢球體,將笛卡爾二維平面坐標轉為橢球體的笛卡爾三維坐標,返回球體表面的點
        let cartesian=viewer.camera.pickEllipsoid(movement.endPosition, ellipsoid);
          if(cartesian){
              //將笛卡爾三維坐標轉為地圖坐標(弧度)
              let cartographic=viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
              //將地圖坐標(弧度)轉為十進制的度數
              let lat_String=Cesium.Math.toDegrees(cartographic.latitude).toFixed(4),
                  log_String=Cesium.Math.toDegrees(cartographic.longitude).toFixed(4),
                  alti_String=(viewer.camera.positionCartographic.height/1000).toFixed(2);
              _this.setState({
                log_String,
                lat_String,
                alti_String
              })
          }
    },Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }
  //設置視角位置及角度
  setPointAdress = (viewer) => {
    const centerPoint = [107.52, 29.422];
    viewer.camera.flyTo({
      destination :  Cesium.Cartesian3.fromDegrees(...centerPoint, 1500), // 設置位置
      orientation: {
          heading : Cesium.Math.toRadians(-10.0), // 方向
          pitch : Cesium.Math.toRadians(-5.0),// 傾斜角度
          roll : 0, //Cesium.Math.toRadians(-38.0)
      },
      duration:5, // 設置飛行持續時間,默認會根據距離來計算
      complete: function () {
          // 到達位置后執行的回調函數
          console.log('到達目的地');
      },
      cancle: function () {
          // 如果取消飛行則會調用此函數
          console.log('飛行取消')
      },
      pitchAdjustHeight: -90, // 如果攝像機飛越高於該值,則調整俯仰俯仰的俯仰角度,並將地球保持在視口中。
      maximumHeight:5000, // 相機最大飛行高度
      flyOverLongitude: 100, // 如果到達目的地有2種方式,設置具體值后會強制選擇方向飛過這個經度
    });
  }

  setIf = () => {
    let _this = this;
    _this.drawPolygon((positions) => {
      let wgs84_positions = [],
          areaAdapCoordi = [],
          maxHeight = 0;
      for(var i=0; i<positions.length; i++){
          var wgs84_point = _this.Cartesian3_to_WGS84({
              x: positions[i].x,
              y: positions[i].y,
              z: positions[i].z
          });
          wgs84_positions.push(wgs84_point);
      }
      //獲取鼠標點擊的位置高度貌似有問題,為了呈現水的高度,所以手動調增*300米。
      maxHeight = Math.max(...wgs84_positions.map(item => item.alt * 300));
      wgs84_positions.map(item => [item.lng, item.lat, item.alt]).map(item => item.forEach(e => areaAdapCoordi.push(e)));
      this.setState({
        adapCoordi: areaAdapCoordi,//設置選取位置的坐標
        maxHeight: maxHeight // 設置最高高度,即水漫到多高
      })
    });
  }

  //畫面
  drawPolygon = (callback) => {
    var _this = this;
    var PolygonPrimitive = (function () {
        function _(positions) {
            this.options = {
                id:'drawPolygonforwater',
                name: '多邊形',
                polygon: {
                    hierarchy: [],
                    perPositionHeight: true,
                    material: Cesium.Color.RED.withAlpha(0.5),
                    outline : true,
                    outlineColor : Cesium.Color.WHITE,
                    outlineWidth : 4,
                }
            };
            this.hierarchy = positions;
            this._init();
        }

        _.prototype._init = function () {
            var _self = this;
            var _update = function () {
                return _self.hierarchy;
            };
            //實時更新polygon.hierarchy
            this.options.polygon.hierarchy = new Cesium.CallbackProperty(_update, false);
            _this.viewer.entities.add(this.options);
        };
        return _;
    })();

    var handler = new Cesium.ScreenSpaceEventHandler(_this.viewer.scene.canvas);
    var positions = [];
    var poly = undefined;

    //鼠標單擊畫點
    handler.setInputAction(function (movement) {
        let cartesian=_this.viewer.scene.camera.pickEllipsoid(movement.position, _this.viewer.scene.globe.ellipsoid);
        if (positions.length === 0) {
            positions.push(cartesian.clone());
        }
        positions.push(cartesian);
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    //鼠標移動
    handler.setInputAction(function (movement) {
        var cartesian = _this.viewer.scene.camera.pickEllipsoid(movement.endPosition, _this.viewer.scene.globe.ellipsoid);
        if (positions.length >= 2) {
            if (!Cesium.defined(poly)) {
                poly = new PolygonPrimitive(positions);
            } else {
                if(cartesian !== undefined){
                      positions.pop();
                      cartesian.y += (1 + Math.random());
                      positions.push(cartesian);
                }
            }
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    //鼠標右鍵單擊結束繪制
    handler.setInputAction(function (movement) {
        handler.destroy();
        callback(positions);
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  //笛卡爾坐標系轉WGS84坐標系
  Cartesian3_to_WGS84 = (point) =>  {
      let cartesian33 = new Cesium.Cartesian3(point.x, point.y, point.z),
          cartographic = Cesium.Cartographic.fromCartesian(cartesian33),
          lat = Cesium.Math.toDegrees(cartographic.latitude),
          lng = Cesium.Math.toDegrees(cartographic.longitude),
          alt = cartographic.height;
      return {lat: lat, lng: lng, alt: alt};
   }

   _drawWater = () => {
    const { maxHeight } = this.state;
    const targetHeight = maxHeight;
    let _this = this;
    //移除選取的多邊形
    _this.viewer.entities.removeById('drawPolygonforwater');
    //將全局的 地形設置改為地形遮擋,這樣山體可將水漫立方體擋住
    _this.viewer.scene.globe.depthTestAgainstTerrain = !0;
    const { adapCoordi } = this.state;
    this.viewer.entities.removeById('polygonforwaterYanmo');
    let WaterPolygonPrimitive = (function () {
        function _(height) {
            this.options = {
                id:'polygonforwaterYanmo',
                name: '水文立方體',
                polygon: {
                  hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(adapCoordi),
                  material: Cesium.Color.CORNFLOWERBLUE.withAlpha(0.8),
                  perPositionHeight: true,
                  extrudedHeight: 0,
                }
            };
            this.extrudedHeight = height;
            this._init();
        }

        _.prototype._init = function () {
            var _self = this;
            var _update = function () {
              return _self.extrudedHeight;
            };
            //實時更新polygon.extrudedHeight
            this.options.polygon.extrudedHeight = new Cesium.CallbackProperty(_update, false);
            _this.viewer.entities.add(this.options);
        };
        return _;
    })();
    let height = 0,
        warterEn = new WaterPolygonPrimitive(height),
        waterHeight = 0;
    this.timer = setInterval(() => {
      if (waterHeight < targetHeight) {
        waterHeight += 2
        if (waterHeight > targetHeight) {
          waterHeight = targetHeight
        }
        warterEn.extrudedHeight = waterHeight;
      }
    }, 100);
    }

  render() {
    const { log_String, lat_String, alti_String } = this.state;
    return (<div className={styles.cesium}>
      <button onClick={() => this.setIf()}>繪制區域</button>
      <button style={{marginLeft: 8}} onClick={() => this._drawWater()}>開始分析</button>
      <div id="cesiumContainer" className={styles.cesiumContainer}>
        <div className={styles.latlng_show}>
          <div className={styles.latlng_show_log}>
              <font size="3" color="white">經度:<span>{log_String}</span></font>
          </div>
          <div className={styles.latlng_show_lat}>
              <font size="3" color="white">緯度:<span>{lat_String}</span></font>
          </div>
          <div className={styles.latlng_show_alt}>
              <font size="3" color="white">視角高:<span>{alti_String}</span>km</font>
          </div>
        </div>
      </div>
    </div>);
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM