Cesium军事标绘编辑

效果图

在这里插入图片描述

关键代码

// 军事标绘编辑类  

import { point3dsToPoint2ds } from "../PlotUtils/utils3d"
import { cartesian3ToPoint3D } from "../../PlotBase/PlotBaseUtils"
import PlotTypes from "../PlotTypes"
import * as turf from "@turf/turf"
export default class MilitaryPlotEditor {
    constructor(viewer, militaryPlotLayer) {
        this.viewer = viewer;
        this.militaryPlotLayer = militaryPlotLayer; //只能从指定的图层中获取编辑对象 如果拾取的对象不在该图层 不进行编辑 这样不用处理绘制和编辑器的关系
        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.clear();
    }

    //清空编辑节点
    clear() {
        this.clearEditVertex();
    }

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

            // 拾取到对象 判断拾取到的对象类型
            if (!id.id || id.id.plotType != "MilitaryPlot") {
                this.handleEditMilitaryPlot();
                return;
            }

            //重复点击同一个对象
            if (this.militaryPlot && this.militaryPlot.plotCode == id.id.plotCode) return;
            //拾取到新的GeoPlot对象
            this.handleEditMilitaryPlot(); //处理上一个编辑对象
            this.handlePickMilitaryPlot(id.id);
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    }

    //处理编辑对象
    handleEditMilitaryPlot() {
        this.clear();
        let militaryPlot = this.militaryPlot;
        this.militaryPlot = undefined;
        if (!this.isEdited) return; //没有任何编辑 直接返回
        console.log("对象被编辑过是否需要保存操作??");

        //触发编辑事件 militaryPlot

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

    //处理拾取到的对象
    handlePickMilitaryPlot(pickId) {
        this.militaryPlot = this.militaryPlotLayer.getByPlotCode(pickId.plotCode);
        if (!this.militaryPlot) return; //图层里面没有该对象 说明是在绘制的时候触发该事件
        this.isEditing = false;
        this.isEdited = false;
        this.militaryPlot.openEditMode(true);
        debugger
        this.editPositions = this.plotPointsToPositions();
        this.EditMoveCenterPositoin = this.getMilitaryPlotCenterPosition();

        this.clear();
        this.createEditVertex();
        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);
        // this.eventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }

    //场景鼠标左键按下事件
    initLeftDownEventHandler() {
        this.eventHandler.setInputAction((e) => {
            let id = this.viewer.scene.pick(e.position);
            if (!id) {
                return;
            }
            // 拾取到对象 判断拾取到的对象类型 
            if (!id.id || !id.id.type) return;
            //拾取到具有type 属性的entity对象  
            if (id.id.type == "MilitaryPlotEditVertex" || id.id.type == "MilitaryPlotEditMoveVertex") {
                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;
            }
        }, 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;
        }), Cesium.ScreenSpaceEventType.LEFT_UP);
    }

    //场景鼠标移动事件
    initMouseMoveEventHandler() {
        this.eventHandler.setInputAction(((e) => {
            //先拾取位置 如果没有拾取到 直接返回  因为场景拾取位置有时会发生错误 拾取不到位置
            let pickPosition = this.viewer.scene.pickPosition(e.endPosition);
            if (!pickPosition) return;
            //判断是否有正在移动的对象  
            if (!this.isEditing) return;
            // this.militaryPlot.updatePosition(pickPosition); //更新位置  因为传递过来的是数组对象 直接更新 不用在调用更新方法
            // 判断是整体平移还是节点平移
            if (this.editVertext.type == "MilitaryPlotEditMoveVertex") {
                let startPosition = this.EditMoveCenterPositoin;
                if (!startPosition) return;
                this.moveEntityByOffset(startPosition, pickPosition);
            } else {
                this.editPositions[this.editVertext.vertexIndex] = pickPosition;
                this.militaryPlot.setPoints(point3dsToPoint2ds(this.editPositions));
            }
            this.isEdited = true;
            this.EditMoveCenterPositoin = this.getMilitaryPlotCenterPosition();
        }), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    }

    //获取编辑对象的中心点
    getMilitaryPlotCenterPosition() {
        //如果是圆 或者点 返回第一个点作为移动点
        switch (this.militaryPlot.baseInfo.plotName) {
            case PlotTypes.CIRCLE:
            case PlotTypes.MARKER:
                return this.editPositions[0];
        }

        //构建turf.js  lineString
        let geo = turf.lineString(this.militaryPlot.getPoints());
        let bbox = turf.bbox(geo);
        let bboxPolygon = turf.bboxPolygon(bbox);
        let pointOnFeature = turf.center(bboxPolygon);
        let lonLat = pointOnFeature.geometry.coordinates;
        return Cesium.Cartesian3.fromDegrees(lonLat[0], lonLat[1], this.militaryPlot.getHeight());
    }

    //根据偏移量移动实体
    moveEntityByOffset(startPosition, endPosition) {
        let startPoint3d = cartesian3ToPoint3D(startPosition);
        let endPoint3d = cartesian3ToPoint3D(endPosition);
        let offsetX = endPoint3d.x - startPoint3d.x;
        let offsetY = endPoint3d.y - startPoint3d.y;

        //设置偏移量
        let element, point3d;
        for (let i = 0; i < this.editPositions.length; i++) {
            element = cartesian3ToPoint3D(this.editPositions[i]);
            element.x += offsetX;
            element.y += offsetY;
            this.editPositions[i] = Cesium.Cartesian3.fromDegrees(element.x, element.y, element.z)
        }
        this.militaryPlot.setPoints(point3dsToPoint2ds(this.editPositions));
    }

    plotPointsToPositions() {
        let points = this.militaryPlot.getPoints();
        let height = this.militaryPlot.getHeight();

        let degreesArrayHeights = [];
        for (let i = 0; i < points.length; i++) {
            const element = points[i];
            degreesArrayHeights.push(element[0]);
            degreesArrayHeights.push(element[1]);
            degreesArrayHeights.push(height);
        }

        return Cesium.Cartesian3.fromDegreesArrayHeights(degreesArrayHeights);
    }

    //创建编辑节点对象
    createEditVertex() {
        this.vertexEntities = [];
        let positions = this.plotPointsToPositions();

        //对圆进行特殊处理
        if (this.militaryPlot.baseInfo.plotName == PlotTypes.CIRCLE) {
            this.createCircleEditVertex();
            this.createEditMoveCenterEntity();
            return;
        }
        positions.forEach((p, index) => {
            const entity = this.viewer.entities.add({
                position: new Cesium.CallbackProperty(e => {
                    return this.editPositions[index];
                }, false),
                type: "MilitaryPlotEditVertex",
                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();
    }

    //创建编辑圆的节点对象
    createCircleEditVertex() {
        const entity = this.viewer.entities.add({
            position: new Cesium.CallbackProperty(e => {
                return this.editPositions[1];
            }, false),
            type: "MilitaryPlotEditVertex",
            vertexIndex: 1, //节点索引 
            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);
    }

    //创建整体移动的entity对象
    createEditMoveCenterEntity() {
        this.EditMoveCenterEntity = this.viewer.entities.add({
            position: new Cesium.CallbackProperty(e => {
                return this.EditMoveCenterPositoin;
            }, false),
            type: "MilitaryPlotEditMoveVertex",
            point: {
                color: Cesium.Color.RED.withAlpha(0.4),
                pixelSize: 10,
                outlineColor: Cesium.Color.WHITE.withAlpha(0.3),
                outlineWidth: 3,
                disableDepthTestDistance: 2000,
            },
        })
    }

    //清空编辑节点
    clearEditVertex() {
        if (this.vertexEntities) {
            this.vertexEntities.forEach(item => {
                this.viewer.entities.remove(item);
            })
        }
        this.vertexEntities = [];
        this.viewer.entities.remove(this.EditMoveCenterEntity);
    }
}

详情参见 Cesium实战项目

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xt3d

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

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

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

打赏作者

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

抵扣说明:

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

余额充值