Cesium点线面实体编辑功能

Cesium点线面实体编辑功能

前言

基于Cesium封装点线面实体的编辑功能,能够新增节点,移动节点,整体移动实体。

编辑点效果

在这里插入图片描述

编辑线效果在这里插入图片描述

编辑面效果在这里插入图片描述

关键代码

export default class EntityEdit {
    constructor(viewer) {
        this.viewer = viewer;
        this.initEventHandler();
    }

    //鼠标事件
    initEventHandler() {
        this.eventHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    }

    //激活编辑
    activate() {
        this.deactivate();
        //鼠标左键点击事件 鼠标左键点击拾取需要编辑的对象
        this.initLeftClickEventHandler();
    }

    //禁用编辑
    deactivate() {
        this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this.unRegisterEvents();
        this.clearAllEditVertex();
    } 

    //左键点击事件
    initLeftClickEventHandler() {
        this.eventHandler.setInputAction(e => {
            let id = this.viewer.scene.pick(e.position);
            if (!id || !id.id) {
                this.handleEditEntity();
                return; // 没有拾取到对象 直接返回 不做任何操作
            }

            // 拾取到对象 判断拾取到的对象类型
            if (!id.id || !id.id.Type) return;
            //重复点击同一个对象
            if (this.editEntity && this.editEntity.id == id.id.id) return;

            //拾取到新的对象
            this.handleEditEntity(); //处理上一个编辑对象
            this.handlePickEditEntity(id.id);
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    }

    //处理编辑对象
    handleEditEntity() {
        this.unRegisterEvents();
        this.clearAllEditVertex();
        let editEntity = this.editEntity;
        if (!editEntity) return;
        this.closeEntityEditMode();
        this.editEntity = undefined;
        if (!this.isEdited) return; //没有任何编辑 直接返回   

        this.isEdited = false;
        this.isEditing = false;
    }

    //处理拾取到的对象
    handlePickEditEntity(pickId) {
        ....

        this.isEditing = false;
        this.isEdited = false;

        this.editPositions = this.getEditEntityPositions();
        this.EditMoveCenterPositoin = this.getCenterPosition();

        this.openEntityEditModel(); 
        this.clearAllEditVertex();
        this.unRegisterEvents();
        this.createEditVertex();
        this.createMidVertex();
        this.registerEvents();
    } 

    //注册事件监听
    registerEvents() {
        //鼠标左键按下事件 当有对象被选中时 如果拾取到编辑辅助要素 表示开始改变对象的位置
        this.initLeftDownEventHandler();
        //鼠标移动事件 鼠标移动 如果有编辑对象 表示改变编辑对象的位置
        this.initMouseMoveEventHandler();
        //鼠标左键抬起事件 当有编辑对象时  
        this.initLeftUpEventHandler();
    }

    //取消事件监听
    unRegisterEvents() {
        this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
        this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
        this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    }

    //场景鼠标左键按下事件
    initLeftDownEventHandler() {
        this.eventHandler.setInputAction((e) => {
            let id = this.viewer.scene.pick(e.position);
            // 拾取到对象 判断拾取到的对象类型 
            if (!id || !id.id || !id.id.type) return;
            //拾取到具有type 属性的entity对象  
            if (id.id.type == "EditVertex" || id.id.type == "EditMove") {
                this.isEditing = true;
                //禁用场景的旋转移动功能 保留缩放功能
                this.viewer.scene.screenSpaceCameraController.enableRotate = false;
                //改变鼠标状态
                this.viewer.enableCursorStyle = false;
                this.viewer._element.style.cursor = '';
                document.body.style.cursor = "move";
                this.editVertext = id.id;
                this.editVertext.show = false;
                this.clearMidVertex();
            } else if (id.id.type == "EditMidVertex") {
                this.editPositions.splice(id.id.vertexIndex, 0, id.id.position._value);
                this.clearAllEditVertex();
                this.createEditVertex();
                this.createMidVertex();
                this.isEdited = true;
            }
        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
    }

    //场景鼠标左键抬起事件
    initLeftUpEventHandler() {
        this.eventHandler.setInputAction(((e) => {
            if (!this.isEditing) return;
            this.viewer.enableCursorStyle = true;
            document.body.style.cursor = "default";
            this.viewer.scene.screenSpaceCameraController.enableRotate = true;
            this.editVertext.show = true;
            this.isEditing = false;
            this.clearMidVertex();
            this.createMidVertex();
        }), Cesium.ScreenSpaceEventType.LEFT_UP);
    }

    //场景鼠标移动事件
    initMouseMoveEventHandler() {
        this.eventHandler.setInputAction(((e) => {
            let pickPosition = this.viewer.scene.pickPosition(e.endPosition);
            if (!pickPosition) return;

            if (!this.isEditing) return;
            if (this.editVertext.type == "EditMove") {
                let startPosition = this.EditMoveCenterPositoin;
                if (!startPosition) return;
                this.moveEntityByOffset(startPosition, pickPosition);
            } else {
                this.editPositions[this.editVertext.vertexIndex] = pickPosition;
            }
            this.isEdited = true;
            this.EditMoveCenterPositoin = this.getCenterPosition();
        }), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    }

    //获取编辑对象中心点
    getCenterPosition() {
        let points = [];
        let maxHeight = 0;
        //如果是点 返回第一个点 
        if (this.editEntity.Type == "EditableMarker") {
            return this.editPositions[0];
        } 
        
        this.editPositions.forEach(position => {
            const point3d = this.cartesian3ToPoint3D(position);
            points.push([point3d.x, point3d.y]);
            if (maxHeight < point3d.z) maxHeight = point3d.z;
        })

        ....
        return Cesium.Cartesian3.fromDegrees(lonLat[0], lonLat[1], maxHeight);
    }

    //根据偏移量移动实体
    moveEntityByOffset(startPosition, endPosition) {
       ...
    }

    //创建编辑节点
    createEditVertex() {
        this.vertexEntities = [];
        this.editPositions.forEach((p, index) => {
            const entity = this.viewer.entities.add({
                position: new Cesium.CallbackProperty(e => {
                    return this.editPositions[index];
                }, false),
                type: "EditVertex",
                vertexIndex: index, //节点索引 
                point: {
                    color: Cesium.Color.DARKBLUE.withAlpha(0.4),
                    pixelSize: 10,
                    outlineColor: Cesium.Color.YELLOW.withAlpha(0.4),
                    outlineWidth: 3,
                    disableDepthTestDistance: 2000,
                },
            })
            this.vertexEntities.push(entity);
        });

        if (this.editPositions.length == 1) { //只有一个节点表示点类型 
            return;
        }
        this.createEditMoveCenterEntity();
    }
}

详情参见 Cesium实战项目

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xt3d

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值