Cesium测量

2024-04-10  本文已影响0人  zhuyx0304
class MeasureAngle {
  _state = new Map();
  _layers = null;
  _handler = null;
  constructor(viewer) {
    this._viewer = viewer;
  }
  getNormal(startPoint, _temp) {
    const { _viewer }  = this;
    let zero = new Cesium.Cartographic(0.0, 1.5708, 0.0);
    zero = _viewer.scene.globe.ellipsoid.cartographicToCartesian(zero);
    let pot = Cesium.Cartesian3.subtract(zero, startPoint, new Cesium.Cartesian3());
    var dir = Cesium.Cartesian3.normalize(pot, new Cesium.Cartesian3());
    var ray = new Cesium.Ray(startPoint, dir);
    
    let distance = Math.abs(startPoint.y - _temp.y);
    let np = Cesium.Ray.getPoint(ray, distance);
    return [startPoint, np];
  }
  draw() {
    const { _viewer } = this;
    const _handler = new Cesium.ScreenSpaceEventHandler(_viewer.scene.canvas);
    const _layers = this._setLayers();
    const _polylineEntity = this._polylineEntity();
    const _positions = this._setPositions(_polylineEntity);
    const _labelEntity = this._labelEntity();
    _layers.entities.add(_polylineEntity);
    _layers.entities.add(_labelEntity);
    let _currentPoint = null;
    let _dottedLine = null;
    _handler.setInputAction((e) => {
      const position = _viewer.camera.pickEllipsoid(e.position);
      let _temp = _viewer.camera.pickEllipsoid(new Cesium.Cartesian2(e.position.x, e.position.y - 100));
      if(!position || !_temp) return;
      if(_positions.length === 0) _positions.push(position.clone());            
      _positions.push(position);
      const _ps = this.getNormal(position, _temp);
      _dottedLine = this._dottedLine(_ps);
      _layers.entities.add(_dottedLine);
      _currentPoint = this._addPoint(position);      
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    _handler.setInputAction((e) => {
      const position = _viewer.camera.pickEllipsoid(e.endPosition);
      if(position && _positions.length > 0) _positions.splice(_positions.length - 1, 1, position);
      if(_positions.length === 0) {
        _labelEntity.label.text = "点击左键绘制第一个点。";
      }else if(_positions.length > 0) {
        _labelEntity.label.text = "点击左键绘制下一个点,点击右键结束。";
      }
      if(position) {
        _labelEntity.show = true;
        _labelEntity.position = position;
      }else {
        _labelEntity.show = false;
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    _handler.setInputAction((e) => {
      if(_positions.length === 1 && _currentPoint && _dottedLine) {
        _layers.entities.remove(_currentPoint)
        _layers.entities.remove(_dottedLine)
      };          
      _layers.entities.remove(_labelEntity);
      this._handler.destroy();
      this._handler = null;
      _currentPoint = null;
      _dottedLine = null;
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    this._handler = _handler;
    this._layers = _layers;
  }
  clear() {
    const { _viewer } = this;
    if(this._handler) {
      this._handler.destroy();
      this._handler = null;
    }
    if(this._layers) {
      _viewer.dataSources.remove(this._layers);
      _viewer.entities.remove(this._layers)
      this._layers = null;
    }
    this._state.clear();
  }
  _dottedLine(positions) {
    return new Cesium.Entity({
      polyline: {
        positions,
        material: new Cesium.PolylineDashMaterialProperty({
          color: Cesium.Color.YELLOW,
          dashLength: 12.0,
        }),
        width: 2
      }
    })
  }
  _addPoint(position, distance) {
    const { _viewer } = this;
    const point = this._pointEntity(position, distance);
    this._layers.entities.add(point);
    return point;
  }
  _setPositions(_polylineEntity) {
    const { _state } = this;
    _state.set(_polylineEntity.id, []);
    const positions = _state.get(_polylineEntity.id);
    _polylineEntity.polyline.positions = new Cesium.CallbackProperty(() => {
      return positions;
    }, false)
    return positions;
  }
  _setLayers() {
    const { _viewer } = this;
    let _layers = null;
    if(!this._layers) {
      _layers = new Cesium.CustomDataSource("distanceLayers");
      _viewer.dataSources.add(_layers);
    }else {
      _layers = this._layers;
    }          
    return _layers;
  }
  _polylineEntity() {
    return new Cesium.Entity({
      name: "折线",
      polyline: {
        material: Cesium.Color.YELLOW,
        width: 2
      }
    })
  }
  _pointEntity(position, text) {
    return new Cesium.Entity({
      name: "点",
      position,
      label: {
        text,
        showBackground: true,
        font: '10px sans-serif', 
        pixelOffset: new Cesium.Cartesian2(0, -50)
      },
      point: {
        pixelSize: 8,
        color: Cesium.Color.YELLOW,
        outlineWidth: 2,
        outlineColor: Cesium.Color.BLACK
      }
    })
  }
  _labelEntity(position, text) {
    return new Cesium.Entity({
      name: "点",
      position,
      label: {
        text,
        showBackground: true,
        font: '10px sans-serif',
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM
      },
    })
  }
}

function cartesian3ToWgs84(cartesian3) {
  const cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3);
  const longitude = Cesium.Math.toDegrees(cartographic.longitude);
  const latitude = Cesium.Math.toDegrees(cartographic.latitude);
  const height = cartographic.height;
  return { longitude, latitude, height };
}

function courseAngle(lng_a, lat_a, lng_b, lat_b) {
          
  //以a点为原点建立局部坐标系(东方向为y轴,北方向为x轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵
  // const localToWorld_Matrix = Cesium.Transforms.northEastDownToFixedFrame(
  //     new Cesium.Cartesian3.fromDegrees(lng_a, lat_a)
  // );
  
  //以a点为原点建立局部坐标系(东方向为x轴,北方向为y轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵
  const localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(
      new Cesium.Cartesian3.fromDegrees(lng_a, lat_a)
  );
  //求世界坐标到局部坐标的变换矩阵
  const worldToLocal_Matrix = Cesium.Matrix4.inverse(
      localToWorld_Matrix,
      new Cesium.Matrix4()
  );
  //a点在局部坐标的位置,其实就是局部坐标原点
  const localPosition_A = Cesium.Matrix4.multiplyByPoint(
      worldToLocal_Matrix,
      new Cesium.Cartesian3.fromDegrees(lng_a, lat_a),
      new Cesium.Cartesian3()
  );
  //B点在以A点为原点的局部的坐标位置
  const localPosition_B = Cesium.Matrix4.multiplyByPoint(
      worldToLocal_Matrix,
      new Cesium.Cartesian3.fromDegrees(lng_b, lat_b),
      new Cesium.Cartesian3()
  );
  
  //弧度
  // const angle = Math.atan2(
  //     localPosition_B.y - localPosition_A.y,
  //     localPosition_B.x - localPosition_A.x
  // );
  //弧度
  const angle = Math.atan2(
      localPosition_B.x - localPosition_A.x,
      localPosition_B.y - localPosition_A.y
  );
  //角度
  let theta = angle * (180 / Math.PI);
  if (theta < 0) {
      theta = theta + 360;
  }
  return theta;
}
class MeasureArea {
  _state = new Map();
  _layers = null;
  _handler = null;
  constructor(viewer) {
    this._viewer = viewer;
  }
  draw() {
    const { _viewer } = this;
    const _handler = new Cesium.ScreenSpaceEventHandler(_viewer.scene.canvas);
    const _layers = this._setLayers();
    const _polygonHierarchy = new Cesium.PolygonHierarchy();
    const _polygonEntity = this._polygonEntity(_polygonHierarchy);
    const _positions = this._setPositions(_polygonEntity);
    const _labelEntity = this._labelEntity();
    const _areaLabelEntity = this._labelEntity();
    _layers.entities.add(_polygonEntity);
    _layers.entities.add(_labelEntity);
    _layers.entities.add(_areaLabelEntity);

    let _points = [];
    _handler.setInputAction((e) => {
      const position = _viewer.camera.pickEllipsoid(e.position);
      if(!position) return;
      if(_positions.length === 0) {
        _positions.push(position.clone());
        _polygonHierarchy.positions.push(position.clone());
      }            
      _positions.push(position);
      _polygonHierarchy.positions.push(position);
      _points.push(this._addPoint(position, 0 + " m"));
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    _handler.setInputAction((e) => {
      const position = _viewer.camera.pickEllipsoid(e.endPosition);
      if(position && _positions.length > 0) {
        _positions.splice(_positions.length - 1, 1, position);     
        _polygonHierarchy.positions.splice(_positions.length - 1, 1, position);         
      }
      if(_positions.length === 0) {
        _labelEntity.label.text = "点击左键绘制第一个点。";
      }
      if(_positions.length > 0) {
        _labelEntity.label.text = "点击左键绘制下一个点,点击右键结束。";
      }
      if(_positions.length > 2) {
        _areaLabelEntity.label.text = 0 + " ㎡";
        _areaLabelEntity.position = this._getPolygonCenter(_polygonEntity.polygon);
      }
      if(position) {
        _labelEntity.show = true;
        _labelEntity.position = position;
      }else {
        _labelEntity.show = false;
      }

    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    _handler.setInputAction((e) => {
      _layers.entities.remove(_labelEntity);
      if(_points.length < 3) {
        _points.forEach(point => {
          _layers.entities.remove(point);
        });
        _polygonEntity.polyline.positions = [];
        _polygonHierarchy.positions = [];
      }else {
        _positions.pop();
        _polygonHierarchy.positions.pop();
        _positions.push(_positions[0]);
        _polygonHierarchy.positions.push(_positions[0]);
        _areaLabelEntity.position = this._getPolygonCenter(_polygonEntity.polygon);
      }                        
      
      this._handler.destroy();
      this._handler = null;
      _points = [];
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    this._handler = _handler;
    this._layers = _layers;
  }
  clear() {
    const { _viewer } = this;
    if(this._handler) {
      this._handler.destroy();
      this._handler = null;
    }
    if(this._layers) {
      _viewer.dataSources.remove(this._layers);
      _viewer.entities.remove(this._layers)
      this._layers = null;
    }
    this._state.clear();
  }
  _addPoint(position, distance) {
    const { _viewer } = this;
    const point = this._pointEntity(position, distance);
    this._layers.entities.add(point);
    return point;
  }
  _setPositions(_polygonEntity) {
    const { _state } = this;
    _state.set(_polygonEntity.id, []);
    const positions = _state.get(_polygonEntity.id);
    _polygonEntity.polyline.positions = new Cesium.CallbackProperty(() => {
      return positions;
    }, false);
    return positions;
  }
  _setLayers() {
    const { _viewer } = this;
    let _layers = null;
    if(!this._layers) {
      _layers = new Cesium.CustomDataSource("distanceLayers");
      _viewer.dataSources.add(_layers);
    }else {
      _layers = this._layers;
    }          
    return _layers;
  }
  _polygonEntity(polygonHierarchy) {
    return new Cesium.Entity({
      name: "折线",
      polyline: {
        material: Cesium.Color.YELLOW,
        width: 2
      },
      polygon: {
        hierarchy: new Cesium.CallbackProperty(() => {
          return polygonHierarchy;
        }, false),
        material: Cesium.Color.GREENYELLOW.withAlpha(0.5),
      }
    })
  }
  _pointEntity(position, text) {
    return new Cesium.Entity({
      name: "点",
      position,
      label: {
        text,
        showBackground: true,
        font: '10px sans-serif', 
        pixelOffset: new Cesium.Cartesian2(0, -50)
      },
      point: {
        pixelSize: 8,
        color: Cesium.Color.YELLOW,
        outlineWidth: 2,
        outlineColor: Cesium.Color.BLACK
      }
    })
  }
  _labelEntity(position, text) {
    return new Cesium.Entity({
      name: "点",
      position,
      label: {
        text,
        showBackground: true,
        font: '10px sans-serif',
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM
      },
    })
  }
  _getPolygonCenter(polygon) {
    const positions = polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;
    return Cesium.BoundingSphere.fromPoints(positions).center;
  }
}
class MeasureDistance {
  _state = new Map();
  _layers = null;
  _handler = null;
  constructor(viewer) {
    this._viewer = viewer;
  }
  draw() {
    const { _viewer } = this;
    const _handler = new Cesium.ScreenSpaceEventHandler(_viewer.scene.canvas);
    const _layers = this._setLayers();
    const _polylineEntity = this._polylineEntity();
    const _positions = this._setPositions(_polylineEntity);
    const _labelEntity = this._labelEntity();
    _layers.entities.add(_polylineEntity);
    _layers.entities.add(_labelEntity);
    let _currentPoint = null;
    _handler.setInputAction((e) => {
      const position = _viewer.camera.pickEllipsoid(e.position);
      if(!position) return;
      if(_positions.length === 0) _positions.push(position.clone());            
      _positions.push(position);
      _currentPoint = this._addPoint(position, 0 + " m");
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    _handler.setInputAction((e) => {
      const position = _viewer.camera.pickEllipsoid(e.endPosition);
      if(position && _positions.length > 0) _positions.splice(_positions.length - 1, 1, position);
      if(_positions.length === 0) {
        _labelEntity.label.text = "点击左键绘制第一个点。";
      }else if(_positions.length > 0) {
        _labelEntity.label.text = "点击左键绘制下一个点,点击右键结束。";
      }
      if(position) {
        _labelEntity.show = true;
        _labelEntity.position = position;
      }else {
        _labelEntity.show = false;
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    _handler.setInputAction((e) => {
      if(_positions.length > 0) _positions.pop();   
      if(_positions.length === 1 && _currentPoint) _viewer.entities.remove(_currentPoint);         
      _layers.entities.remove(_labelEntity);
      this._handler.destroy();
      this._handler = null;
      _currentPoint = null;
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    this._handler = _handler;
    this._layers = _layers;
  }
  clear() {
    const { _viewer } = this;
    if(this._handler) {
      this._handler.destroy();
      this._handler = null;
    }
    if(this._layers) {
      _viewer.dataSources.remove(this._layers);
      _viewer.entities.remove(this._layers)
      this._layers = null;
    }
    this._state.clear();
  }
  _addPoint(position, distance) {
    const { _viewer } = this;
    const point = this._pointEntity(position, distance);
    this._layers.entities.add(point);
    return point;
  }
  _setPositions(_polylineEntity) {
    const { _state } = this;
    _state.set(_polylineEntity.id, []);
    const positions = _state.get(_polylineEntity.id);
    _polylineEntity.polyline.positions = new Cesium.CallbackProperty(() => {
      return positions;
    }, false)
    return positions;
  }
  _setLayers() {
    const { _viewer } = this;
    let _layers = null;
    if(!this._layers) {
      _layers = new Cesium.CustomDataSource("distanceLayers");
      _viewer.dataSources.add(_layers);
    }else {
      _layers = this._layers;
    }          
    return _layers;
  }
  _polylineEntity() {
    return new Cesium.Entity({
      name: "折线",
      polyline: {
        material: Cesium.Color.YELLOW,
        width: 2
      }
    })
  }
  _pointEntity(position, text) {
    return new Cesium.Entity({
      name: "点",
      position,
      label: {
        text,
        showBackground: true,
        font: '10px sans-serif', 
        pixelOffset: new Cesium.Cartesian2(0, -50)
      },
      point: {
        pixelSize: 8,
        color: Cesium.Color.YELLOW,
        outlineWidth: 2,
        outlineColor: Cesium.Color.BLACK
      }
    })
  }
  _labelEntity(position, text) {
    return new Cesium.Entity({
      name: "点",
      position,
      label: {
        text,
        showBackground: true,
        font: '10px sans-serif',
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM
      },
    })
  }
}
var distance = new MeasureDistance(viewer);
      var area = new MeasureArea(viewer);
      var angle = new MeasureAngle(viewer);
上一篇 下一篇

猜你喜欢

热点阅读