Cesium 绘制可编辑点

Cesium Point点

实现可编辑的pointEntity 实体
在这里插入图片描述



前言

支持 鼠标按下 拖动修改点,释放修改完成。


一、使用步骤

1、点击 按钮 开始 绘制,单击地图 绘制完成
2、编辑状态下(hasEdit = true)拖动修改位置,释放完成修改。
2、传入 hasEdit:true 绘制完成后自动激活编辑。默认为false
3、可以取消编辑、激活编辑

二、使用方法

引入

import Point from "@/utils/cesium/point";

const point = new Point(map)

  point.startDraw({
    // hasEdit: true,
    style: {
      pixelSize: 10,
      color: Cesium.Color.RED,
      outlineColor: Cesium.Color.WHITE,
      outlineWidth: 2,
    }
  })
// 编辑状态控制
 point.hasEdit = [boolean]

二、具体实现

主要是对 ccesium 事件监听的灵活使用

1. 开始绘制

代码如下(示例):

  startDraw(options: PolylineOptions) {
    this.clear();

    this.style = options.style;

    if (options.hasEdit) {
      this.enableEdit = options.hasEdit;
    }

    if (!this.handler) {
      this.handler = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );
    }

    // @ts-ignore
    this.viewer._container.style.cursor = "crosshair"; //修改鼠标样式 ,精确选择

    this.addEventListener();
  }

2.绘制事件监听

    //鼠标 左键点击
    this.handler.setInputAction((e) => {
      const target = this.viewer.scene.pick(e.position);

      // && target.collection
      if (target && this.enableEdit && this.drawEnd) {
        this.addEditEventListen(e);
        return;
      }

      // 非编辑状态
      if (!this.editState && !this.drawEnd) {
        const point: any = this.viewer.scene.pickPosition(e.position);
        this.polylinePostions.push(point);

        // 默认开启编辑 显示编辑点
        if (this.enableEdit) {
          const editPoints: any = this.creatPoint(point);
          this.pointList.push(editPoints);
        }

        if (this.polylinePostions.length === 1) {
          this.drawPolyline();
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    // 鼠标移动
    this.handler.setInputAction((e: any) => {
      if (!this.drawEntity) {
        return;
      }

      const position = this.viewer.scene.pickPosition(e.endPosition); //结束点

      this.tempPositions = this.polylinePostions.concat([position]);

      // 显示绘制提示
      const screenPosition =
        this.viewer.scene.cartesianToCanvasCoordinates(position);
      this.utils.bindWindowDom(screenPosition);
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    //双击绘制完成
    this.handler.setInputAction((e: any) => {
      const tempPositions = this.tempPositions.slice(
        0,
        this.polylinePostions.length
      );

      this.drawEntity.polyline.positions = new Cesium.CallbackProperty((e) => {
        return tempPositions;
      }, false);

      this.drawEnd = true;

      if (this.enableEdit && this.drawEnd) {
        this.addEditEventListen();
        this.selectEntity = this.drawEntity;
      }

      this.removeEventListener(); // 绘制结束
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

3、编辑事件监听。

    // 显示编辑点
    if (this.enableEdit && event) {
      this.viewer.scene.screenSpaceCameraController.enableRotate = false; //锁定相机
      this.showEditPoint(event);
      this.editState = true;
    }

    this.handler.setInputAction((e: any) => {
      const target = this.viewer.scene.pick(e.position);

      if (!target) {
        this.closeEdit(); //点击其它位置 取消编辑
      }

      // 选中 编辑的点
      if (target && target.collection) {
        this.viewer.scene.screenSpaceCameraController.enableRotate = false; //固定相机

        this.editPoint = this.viewer.entities.getById(target.id.id);
        const position: any = this.editPoint?.position.getValue();

        this.index = this.polylinePostions.findIndex(
          //找出要编辑点 在 polyline的位置
          (item: Cesium.Cartesian3) =>
            item.x === position.x &&
            item.y === position.y &&
            position.z === item.z
        );

        this.addMouseMoveEvent(); //开启鼠标移动事件监听
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

    // 鼠标 左键松开 完成编辑
    this.handler.setInputAction((e: any) => {
      this.viewer.scene.screenSpaceCameraController.enableRotate = true; //解锁相机移动
      this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE); //移除鼠标移动监听
      this.utils.destoryTip();
    }, Cesium.ScreenSpaceEventType.LEFT_UP);

三、 完整代码

import * as Cesium from "cesium";

interface PointOptions {
  hasEdit?: boolean;
  style: Cesium.PointGraphics.ConstructorOptions;
}

export default class Point {
  private viewer: Cesium.Viewer;
  private hander: Cesium.ScreenSpaceEventHandler | any;
  
  private isEdit: boolean = false; //是否编辑
  private isEditing: boolean = false; // 是否正处于编辑状态下
  private drawEnd: boolean = false; // 是否绘制完成
  private editPoint: Cesium.PointGraphics | undefined; // 正在编辑的点矢量对象
  private isStart: boolean = false; // 是否开始编辑
  private utils = new Utils(); // 工具类
  private style: Cesium.PointGraphics.ConstructorOptions = {}; // 点矢量样式

  constructor(viewer: Cesium.Viewer) {
    this.viewer = viewer;
  }

  set hasEdit(enable: boolean) {
    this.isEdit = enable;
    if (this.isEdit) {
      this.addEditMouseEvent();
    } else {
      this.removeEditMouseEvent();
    }
  }

  startDraw(options: PointOptions) {
    this.style = options.style;

    if (!this.hander) {
      this.hander = new Cesium.ScreenSpaceEventHandler(
        this.viewer.scene.canvas
      );
    }

    if (options?.hasEdit) {
      this.isEdit = options.hasEdit;
    }

    this.drawEnd = false;
    // @ts-ignore
    this.viewer._container.style.cursor = "crosshair"; //修改鼠标样式 ,精确选择

    this.hander.setInputAction((e) => {
      this.viewer.scene.screenSpaceCameraController.enableRotate = true; //锁定相机
      // @ts-ignore
      this.viewer._container.style.cursor = "auto"; //修改鼠标样式 ,精确选择

      if (!this.isEdit) {
        this.hander.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
      }

      if (this.isStart) {
        this.isStart = false;
        this.editPoint = undefined;
      }
    }, Cesium.ScreenSpaceEventType.LEFT_UP);

    this.hander.setInputAction((e) => {
      const postion = this.viewer.scene.pickPosition(e.position);

      if (this.isEdit && this.drawEnd) {
        this.isEditing = false;
        return;
      }

      this.creatPoint(postion);
      this.drawEnd = true; //绘制完成

      if (this.isEdit && !this.isEditing && this.drawEnd) {
        // 创建鼠标 按下 鼠标移动 事件
        this.addEditMouseEvent();
        this.isEditing = true;
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }

  private addEditMouseEvent() {
    this.hander.setInputAction((e) => {
      const target = this.viewer.scene.pick(e.position);
      if (target) {
        this.editPoint = this.viewer.entities.getById(target.id.id);
        this.viewer.scene.screenSpaceCameraController.enableRotate = false; //锁定相机
        this.isStart = true; //开始编辑
      }
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
    this.mouseMoveEventLinsten();
  }

  private mouseMoveEventLinsten() {
    this.hander.setInputAction((e) => {
      const target = this.viewer.scene.pick(e.endPosition);
      const position = this.viewer.scene.pickPosition(e.endPosition);
      if (target) {
        // 显示绘制提示
        const screenPosition =
          this.viewer.scene.cartesianToCanvasCoordinates(position);
        this.utils.bindWindowDom(
          screenPosition,
          "鼠标按下 拖动修改位置<br>释放后完成修改"
        );
      } else if (!this.isStart) {
        this.utils.destoryTip();
      }

      if (this.editPoint) {
        this.editPoint.position = position;
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }

  private removeEditMouseEvent() {
    this.hander.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
    this.hander.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    this.hander.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }

  private creatPoint(position: Cesium.Cartesian3) {
    this.viewer.entities.add({
      id: generateUUID(),
      position: position,
      point: {
        ...this.style,
      },
    });
  }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值