Cesium绘制多边形

class PolygonDrawer {
  viewer = null; // 视图
  handler = null; // 鼠标事件
  dataSource = null; // 自定义数据源
  activePoints = []; // 绘制过程中临时保存的点
  activeShape = null; // 绘制过程中临时保存的图形
  callback = null; // 绘制完成回调
  // 多边形样式
  polygonStyles = {
    fillColor: Cesium.Color.RED.withAlpha(0.5), // 填充颜色
    outlineColor: Cesium.Color.RED, // 边线颜色
    outlineWidth: 2, // 边线宽度
  };
  // 构造函数
  constructor(options = {}) {
    if (!options.viewer) {
      throw new Error('viewer is required');
    }
    this.viewer = options.viewer;
    this.callback = options.callback;
    this.polygonStyles.fillColor = Cesium.Color.fromCssColorString(options.fillColor || "rgba(255, 255, 0, 0.5)");
    this.polygonStyles.outlineColor = Cesium.Color.fromCssColorString(options.outlineColor || "rgba(255, 255, 0, 0.5)");
    this.polygonStyles.outlineWidth = options.outlineWidth || 2;
    this.dataSource = new Cesium.CustomDataSource('custom-polygon-drawer-dataSource');
    this.viewer.dataSources.add(this.dataSource);
  }
  // 开始绘制
  draw() {
    this.viewer.canvas.style.cursor = "crosshair";
    this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas);
    this.handler.setInputAction(
      this.leftClick.bind(this),
      Cesium.ScreenSpaceEventType.LEFT_CLICK
    );
    this.handler.setInputAction(
      this.rightClick.bind(this),
      Cesium.ScreenSpaceEventType.RIGHT_CLICK
    );
    this.handler.setInputAction(
      this.leftDoubleClick.bind(this),
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    );
    this.handler.setInputAction(
      this.mouseMove.bind(this),
      Cesium.ScreenSpaceEventType.MOUSE_MOVE
    );
  }
  // 清除
  clear() {
    this.dataSource.entities.removeAll();
  }
  // 销毁
  destroy() {
    this.viewer.canvas.style.cursor = "default";
    if (this.handler) {
      this.handler.removeInputAction(
        this.leftClick.bind(this),
        Cesium.ScreenSpaceEventType.LEFT_CLICK
      );
      this.handler.removeInputAction(
        this.rightClick.bind(this),
        Cesium.ScreenSpaceEventType.RIGHT_CLICK
      );
      this.handler.removeInputAction(
        this.leftDoubleClick.bind(this),
        Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
      );
      this.handler.removeInputAction(
        this.mouseMove.bind(this),
        Cesium.ScreenSpaceEventType.MOUSE_MOVE
      );
      this.handler.destroy();
      this.handler = null;
    }
  }
  // 左键点击
  leftClick(event) {
    const ray = this.viewer.camera.getPickRay(event.position);
    const position = this.viewer.scene.globe.pick(ray, this.viewer.scene);
    if (Cesium.defined(position)) {
      if (this.activePoints.length === 0) {
        // [0]: 起始点,[1]: 浮动点 [2]: 闭合点
        this.activePoints = [
          position.clone(),
          position.clone(),
          position.clone(),
        ];
        this.activeShape = this.createPolygon(this.activePoints, true);
      } else {
        this.activePoints.pop();
        this.activePoints.push(position);
        this.activePoints.push(this.activePoints[0]);
      }
    }
  }
  // 鼠标移动
  mouseMove(event) {
    if (this.activePoints.length > 0) {
      const ray = this.viewer.camera.getPickRay(event.endPosition);
      const position = this.viewer.scene.globe.pick(ray, this.viewer.scene);
      if (Cesium.defined(position)) {
        this.activePoints.splice(-2, 1, position);
      }
    }
  }
  // 右击删除最后一个点
  rightClick(event) {
    if (this.activePoints.length > 3) {
        this.activePoints.splice(-2, 1);
    }else {
        this.activePoints = [];
    }
  }
  // 左键双击闭合
  leftDoubleClick(event) {
    this.activePoints.splice(-4, 3); // 移除浮动点和双击的重复点
    if (this.activePoints.length > 3) {
      this.callback && this.callback(this.activePoints);
      this.createPolygon(this.activePoints);
      this.viewer.entities.remove(this.activeShape);
      this.activePoints = [];
      this.activeShape = null;
    }
  }
  // 创建多边形
  createPolygon(positions, dynamic = false) {
    let polygonPosition = dynamic
      ? new Cesium.CallbackProperty(() => {
          let newPositions = Array.from(this.activePoints);
          newPositions.pop();
          return new Cesium.PolygonHierarchy(newPositions);
        }, false)
      : positions;
    let linePosition = dynamic
      ? new Cesium.CallbackProperty(() => {
          return this.activePoints;
        }, false)
      : positions;

    return this.dataSource.entities.add({
      polyline: {
        positions: linePosition,
        clampToGround: true,
        width: this.polygonStyles.outlineWidth,
        material: this.polygonStyles.outlineColor,
      },
      polygon: {
        hierarchy: polygonPosition,
        material: new Cesium.ColorMaterialProperty(this.polygonStyles.fillColor),
      },
    });
  }
}

export default PolygonDrawer;

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容