Cesium+Echarts实现剖面图

import * as Cesium from "cesium";

export default class ProfileAnalysis {
  constructor(viewer) {
    this.viewer = viewer;
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    this.profileItem = []
    this.positionsCartographic = []
    this.positions_Inter = []
    this.poly = null;
    this.floatingPointList = []
  }
  //世界坐标转换为经纬度    
  getDegrees(cart) {
    let lat = Cesium.Math.toDegrees(cart.latitude);
    let lng = Cesium.Math.toDegrees(cart.longitude);
    let alt = cart.height;
    return {x:lng, y:lat, z:alt};
  }

  //空间两点距离计算  
  getSpaceDistance(positions) {
    this.profileItem = [
      {
        point: positions[0],
        distance: 0
      }
    ];
    var distance = 0;
    for (var i = 0; i < positions.length - 1; i++) {
      var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
      var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
      /**根据经纬度计算出距离**/
      var geodesic = new Cesium.EllipsoidGeodesic();
      geodesic.setEndPoints(point1cartographic, point2cartographic);
      var s = geodesic.surfaceDistance;
      //返回两点之间的距离
      s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
      distance = distance + s;
      var m_Item = {
        point: positions[i+1],
        distance: distance
      };
      this.profileItem.push(m_Item);
    }
    return distance.toFixed(2);
  }

  //线段插值点   
  interPoints(positions) {
    this.positionsCartographic = [];
    var terrainSamplePositions = [];
    for (let index = 0; index < positions.length - 1; index++) {
      const element = positions[index];
      var ellipsoid = this.viewer.scene.globe.ellipsoid;
      var cartographic = ellipsoid.cartesianToCartographic(element);
      this.positionsCartographic.push(cartographic);
    }
    for (let i = 0; i < this.positionsCartographic.length; i++) {
      const m_Cartographic0 = this.positionsCartographic[i];
      const m_Cartographic1 = this.positionsCartographic[i + 1];
      if (m_Cartographic1) {
        //等距采样
        // var a = Math.abs(m_Cartographic0.longitude - m_Cartographic1.longitude) * 10000000;
        // var b = Math.abs(m_Cartographic0.latitude - m_Cartographic1.latitude) * 10000000;
        // if (a > b) b = a;
        // var length = parseInt(b / 2);
        // if (length > 1000) length = 1000;
        // if (length < 2) length = 2;
        //等分采样
        let length = 10
        //按照距离等距采样
        // let d =0
        // var point1cartographic = Cesium.Cartographic.fromCartesian(positions[0]);
        // var point2cartographic = Cesium.Cartographic.fromCartesian(positions[1]);
        // /**根据经纬度计算出距离**/
        // var geodesic = new Cesium.EllipsoidGeodesic();
        // geodesic.setEndPoints(point1cartographic, point2cartographic);
        // var s = geodesic.surfaceDistance;
        // //返回两点之间的距离
        // s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
        // d = d + s;
        // let length = Math.ceil(d/50)
        //采样
        for (var j = 0; j < length; j++) {
          terrainSamplePositions.push(
            new Cesium.Cartographic(
              Cesium.Math.lerp(m_Cartographic0.longitude, m_Cartographic1.longitude, j / (length - 1)),
              Cesium.Math.lerp(m_Cartographic0.latitude, m_Cartographic1.latitude, j / (length - 1))
            )
          );
        }
        terrainSamplePositions.pop();
      } else {
        terrainSamplePositions.push(m_Cartographic0);
      }
    }
    this.positions_Inter = [];
    for (var n = 0; n < terrainSamplePositions.length; n++) {
      //地理坐标(弧度)转经纬度坐标
      var m_cartographic = terrainSamplePositions[n];
      var height = this.viewer.scene.globe.getHeight(m_cartographic);
      var point = Cesium.Cartesian3.fromDegrees(m_cartographic.longitude / Math.PI * 180, m_cartographic.latitude / Math.PI * 180, height);
      this.positions_Inter.push(point);
    }
  }

  //剖面分析
  profileAnalysis() {
    this.viewer.scene.globe.depthTestAgainstTerrain = true
    var positions = [];
    var distance = 0;
    var cartesian = null;
    var DistanceArray = [];
    const tempViewer = this.viewer
    this.handler.setInputAction((movement)=> {
      cartesian = this.viewer.scene.pickPosition(movement.endPosition);
      if (positions.length >= 2) {
        if (!Cesium.defined(this.poly)) {
          this.poly = new PolyLinePrimitive(positions);
        } else {
          positions.pop();
          positions.push(cartesian);
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    this.handler.setInputAction((movement) => {
      cartesian = this.viewer.camera.pickEllipsoid(movement.position, this.viewer.scene.globe.ellipsoid);
      if (positions.length == 0) {
        positions.push(cartesian.clone());
      }
      positions.push(cartesian);
      if (this.poly) {
        //进行插值计算
        this.interPoints(this.poly.positions);
        //计算两点间距
        distance = this.getSpaceDistance(this.positions_Inter);
      } else {
        distance = this.getSpaceDistance(positions);
      }
      var textDisance = distance + "米";
      DistanceArray.push(distance);
      this.floatingPoint = this.viewer.entities.add({
        position: positions[positions.length - 1],
        point: {
          pixelSize: 5,
          color: Cesium.Color.RED,
          outlineColor: Cesium.Color.WHITE,
          outlineWidth: 2,
          heightReference: Cesium.HeightReference.NONE
        },
        label: {
          text: textDisance === '0.00米' ? '' : textDisance,
          font: '18px sans-serif',
          fillColor: Cesium.Color.GOLD,
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          outlineWidth: 2,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          pixelOffset: new Cesium.Cartesian2(20, -20),
          heightReference: Cesium.HeightReference.NONE
        }
      });
      this.floatingPointList.push(this.floatingPoint)
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    this.handler.setInputAction((movement) =>{
      this.handler.destroy();//关闭事件句柄
      positions.pop();//最后一个点无效
      let data = this.profileItem.map(e=>{
        let cartographic = Cesium.Cartographic.fromCartesian(e.point);
        // 弧度转为角度(经纬度)
        let lon = Cesium.Math.toDegrees(cartographic.longitude);  //经度值
        let lat = Cesium.Math.toDegrees(cartographic.latitude); //纬度值
        let height2 = this.viewer.scene.globe.getHeight(cartographic)
        return {
          distance: e.distance,
          point: [lon,lat,height2],
        }
      })
      window.startPanintDarw(data)
      this.viewer.scene.globe.depthTestAgainstTerrain = false
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    var PolyLinePrimitive = (function () {
      function _(positions) {
          this.options = {
            id: 'pmfx_line',
            polyline: {
              show: true,
              positions: [],
              material: Cesium.Color.CHARTREUSE,
              width: 2,
              clampToGround: true
            }
          };
          this.positions = positions;
          this._init();
        }
        _.prototype._init = function () {
            var _self = this;
            var _update = function () {
                return _self.positions;
            };
            //实时更新polyline.positions
            this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
            tempViewer.entities.add(this.options);
        };
        return _;
    })();
  }
}

参考其他人的写法,但是其他人写的东西不是很全,不全的东西需要自己写完整。这个是取到完整的点,展示需要通过echarts折线图去绘制

如果针对需要固定距离描点(例如每隔5米的距离就展示一个点这种情况)解决办法如下:

//每五米向线段里填充一个点
        let d = 0
        var point1cartographic = Cesium.Cartographic.fromCartesian(positions[0]);
        var point2cartographic = Cesium.Cartographic.fromCartesian(positions[1]);
        /**根据经纬度计算出距离**/
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(point1cartographic, point2cartographic);
        var s = geodesic.surfaceDistance;
        //返回两点之间的距离
        s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
        d = d + s;
        let position1 = Cesium.Cartesian3.fromDegrees(m_Cartographic0.longitude / Math.PI * 180, m_Cartographic0.latitude / Math.PI * 180, m_Cartographic0.height)
        let position2 = Cesium.Cartesian3.fromDegrees(m_Cartographic1.longitude / Math.PI * 180, m_Cartographic1.latitude / Math.PI * 180, m_Cartographic1.height)               
        let pot = Cesium.Cartesian3.subtract(position2, position1, new Cesium.Cartesian3());//方向
        var dir = Cesium.Cartesian3.normalize(pot, new Cesium.Cartesian3());//向量归一化 
        var ray = new Cesium.Ray(position1, dir);
        let length = Math.floor(d/5)
        for (let index = 1; index < length; index++) {
          let np = Cesium.Ray.getPoint(ray, index*5);//计算延长点
          let npCartographic = Cesium.Cartographic.fromCartesian(np);
          terrainSamplePositions.push(npCartographic)
        }

注意,返回的数据横轴距离也要进行相对应的改动,抛开最后一个点都是5的倍数来计算距离的

你可能感兴趣的:(echarts,javascript,前端,Cesium)