Cesium使用鼠标动态绘制矩形(附带绘制帮助提示语)

1、实现鼠标动态绘制矩形的类RectangleDraw

实现思路是:矩形绘制只需要两个点即可确定一个矩形,其中使用鼠标绘制的实现思路与上一篇博文"Cesium使用鼠标动态绘制线(附带绘制帮助提示语)",链接:https://blog.csdn.net/weixin_43812586/article/details/142145096基本一致.

唯一的难点在于如何通过左上右下两个位置点计算出Cesium当中矩形的四个顶点数据
核心代码如下:

import CesiumByZh from "../CesiumByZh";
import GlobalListener from "../GlobalListener";
export default class RectangleDraw{
    public canvas = CesiumByZh.viewer.scene.canvas;
    public camera = CesiumByZh.viewer.scene.camera;
    public ellipsoid = CesiumByZh.viewer.scene.globe.ellipsoid;
    public viewer = CesiumByZh.viewer;
    public scene = CesiumByZh.viewer.scene;
    protected positions: any[] = [];
    protected dragIconLight: string = "./Images/circle_red.png";//这里是绘制线连接处的一个小圆点的图片,可以自己去找一个小圆点的图片替代
    protected shapeEntity: any;
    protected handler: any;
    protected pointEntity: any;
    protected result: any;
    public pointEntityArray: any[] = [];
    lineColor: string = '#002fff';
    fillColor: string = '#F60';
    lineOpacity: number = 50;
    fillOpacity: number = 50;
    isGround: boolean = true;
    lineWidth: number = 2;

    constructor() {
       
    }

    beginDraw() {
        this.handler = new CesiumByZh.Cesium.ScreenSpaceEventHandler(this.canvas);
       this.handler.setInputAction((event: any) => {
            let position = event.position;
            if (!CesiumByZh.Cesium.defined(position)) {
                return;
            }
            let ray = this.camera.getPickRay(position);
            if (!CesiumByZh.Cesium.defined(ray)) {
                return;
            }
            let cartesian = this.scene.globe.pick(ray, this.scene);
            if (!CesiumByZh.Cesium.defined(cartesian)) {
                return;
            }
            let num = this.positions.length;
            if (num == 0) {
                this.positions.push(cartesian);
                this.createTemporaryShape();
            }
            this.positions.push(cartesian);
            this.pointEntityArray.push(this._createPoint(cartesian));
            if (num > 1) {
                this.positions.pop();
                this._startModify();
            }
        }, CesiumByZh.Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this.handler.setInputAction((event: any) => {
            let position = event.endPosition;
            if (!CesiumByZh.Cesium.defined(position)) {
                return;
            }
            let ray = this.camera.getPickRay(position);
            if (!CesiumByZh.Cesium.defined(ray)) {
                return;
            }
            let cartesian = this.scene.globe.pick(ray, this.scene);
            if (!CesiumByZh.Cesium.defined(cartesian)) {
                return;
            }
            if (this.positions.length == 0) {
                GlobalListener.getInstance().runTipsCallback(['单击开始绘制,右键取消']);
                return
            } else {
                GlobalListener.getInstance().runTipsCallback(['单击完成绘制,右键回退']);
            }
            this.positions.pop();
            this.positions.push(cartesian);
        }, CesiumByZh.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        this.handler.setInputAction((movement: any) => {
            if (this.positions.length == 0) {
                this._clear();
                if (this.cancelHandler) {
                   //重新开始绘制
                }
            } else {
                if (this.positions.length == 2) {
                    this.positions = [];
                    if (this.shapeEntity != null) {
                        CesiumByZh.viewer.entities.remove(this.shapeEntity);
                        this.shapeEntity = null;
                    }
                } else {
                    this.positions.splice(this.positions.length - 2, 1);
                }
                CesiumByZh.viewer.entities.remove(this.pointEntityArray[this.pointEntityArray.length - 1]);
                this.pointEntityArray.pop();
            }
        }, CesiumByZh.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }

    _createPoint(cartesian: any, oid: number = 0) {
        let point = CesiumByZh.viewer.entities.add({
            position: cartesian,
            billboard: {
                image: this.dragIconLight,
                eyeOffset: new CesiumByZh.Cesium.ConstantProperty(new CesiumByZh.Cesium.Cartesian3(0, 0, -500)),
                heightReference: CesiumByZh.Cesium.HeightReference.CLAMP_TO_GROUND
            }
        });
        return point;
    }
    
    //创建绘制用的实体
    createTemporaryShape() {
       let dynamicPositions = new CesiumByZh.Cesium.CallbackProperty(() => {
            if (this.positions.length > 1) {
                return CesiumByZh.Cesium.Rectangle.fromCartesianArray(this.positions);
            } else {
                return null;
            }
        }, false);
        let outlineDynamicPositions = new CesiumByZh.Cesium.CallbackProperty(() => {
            if (this.positions.length > 1) {
                let rect = CesiumByZh.Cesium.Rectangle.fromCartesianArray(this.positions);
                let arr = [rect.west, rect.north, rect.east, rect.north, rect.east, rect.south, rect.west, rect.south, rect.west, rect.north];
                return CesiumByZh.Cesium.Cartesian3.fromRadiansArray(arr);
            } else {
                return null;
            }
        }, false);
        this.shapeEntity = CesiumByZh.viewer.entities.add({
            canSelect: false,
            rectangle: {
                coordinates: dynamicPositions,
                material: CesiumByZh.Cesium.Color.fromCssColorString(this.fillColor).withAlpha(this.fillOpacity / 100),
                height: undefined
            },
            polyline: {
                positions: outlineDynamicPositions,
                clampToGround: this.isGround,
                width: this.lineWidth,
                material: CesiumByZh.Cesium.Color.fromCssColorString(this.lineColor).withAlpha(this.lineOpacity / 100),
            }
        });
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

sannianerban12138

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

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

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

打赏作者

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

抵扣说明:

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

余额充值