web前端开源

cesium标绘矩形、圆形和多边形

2022-12-08  本文已影响0人  姜治宇

标绘类

矩形:

export class DrawRectangle {
    constructor(arg) {

        this.viewer = arg.viewer;
        this.Cesium = arg.Cesium;
        this.callback=arg.callback;
        this.floatingPoint = null;//标识点
        this._rectangle = null; //活动矩形
        this._rectangleLast = null; //最后一个矩形
        this._positions = [];  //活动点
        this._entities_point = [];  //脏数据
        this._entities_rectangle = [];  //脏数据
        this._rectangleData = null; //用于构造矩形数据
    }

    //返回最后图形
    get line() {
        return this._rectangleLast;
    }

    //返回矩形数据
    getData() {
        return this._rectangleData;
    }

    //加载
    loadRectangle(data) {
        var $this = this;
        var shape = this.viewer.entities.add({
            name: "rectangle",
            rectangle: {
                coordinates: $this.Cesium.Rectangle.fromCartesianArray(data),
                material: $this.Cesium.Color.RED.withAlpha(0.5)
            }
        });
        $this._entities_rectangle.push(shape);
        return shape;
    }

    //开始创建
    startCreate() {
        var $this = this;
        
        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
       
        this.handler.setInputAction(function (evt) { //单机开始绘制
           
            //屏幕坐标转地形上坐标
            var cartesian = $this.getCatesian3FromPX(evt.position);
           
            if ($this._positions.length == 0) {
                $this._positions.push(cartesian.clone());
                $this.floatingPoint = $this.createPoint(cartesian);
                $this.createPoint(cartesian);// 绘制点
            }
            $this._positions.push(cartesian);
            $this.viewer.scene.forceRender();
        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this.handler.setInputAction(function (evt) { //移动时绘制线
            if ($this._positions.length < 3) return;
            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
            if (!$this.Cesium.defined($this._rectangle)) {
                $this._rectangle = $this.createRectangle();
            }
            $this.floatingPoint.position.setValue(cartesian);
            if ($this._rectangle) {
                $this._positions.pop();
                $this._positions.push(cartesian);
            }
            $this.viewer.scene.forceRender();
        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        this.handler.setInputAction(function (evt) {
            if (!$this._rectangle) return;
            var cartesian = $this.getCatesian3FromPX(evt.position);
            $this._positions.pop();
            $this._positions.push(cartesian);
            $this.createPoint(cartesian);// 绘制点
            $this._rectangleData = $this._positions.concat();
            $this.viewer.entities.remove($this._rectangle); //移除
            $this._rectangle = null;
            $this._positions = [];
            $this.floatingPoint.position.setValue(cartesian);
            var rectangle = $this.loadRectangle($this._rectangleData); //加载
            $this._entities_rectangle.push(rectangle);
            $this._rectangleLast = rectangle;
            if(typeof $this.callback=="function"){
                $this.callback(rectangle);
            }
            $this.destroy();
            $this.viewer.scene.forceRender();
        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        return this;
    }

    //创建点
    createPoint(cartesian) {
       
        var $this = this;
        var point = this.viewer.entities.add({
            position: cartesian,
            point: {
                pixelSize: 10,
                color: $this.Cesium.Color.YELLOW,
            }
        });
        $this._entities_point.push(point);
        $this.viewer.scene.forceRender();
        return point;
    }
    //创建矩形
    createRectangle() {

        var $this = this;
      
        var shape = this.viewer.entities.add({
            name: "rectangle",
            rectangle: {
                coordinates: new $this.Cesium.CallbackProperty(()=>{
                    if($this.checkPositions()){
                        var obj = $this.Cesium.Rectangle.fromCartesianArray($this._positions);
                        return obj;
                    }
                    
                }, false),
                material: $this.Cesium.Color.RED.withAlpha(0.5)
            }
        });
        $this._entities_rectangle.push(shape);
        $this.viewer.scene.forceRender();
        return shape;
    }

    //销毁
    destroy() {
        if (this.handler) {
            this.handler.destroy();
            this.handler = null;
            this.viewer.scene.forceRender();
        }
    }
    //清空实体对象
    clear() {
        for (var i = 0; i < this._entities_point.length; i++) {
            this.viewer.entities.remove(this._entities_point[i]);
        }
        for (var i = 0; i < this._entities_rectangle.length; i++) {
            this.viewer.entities.remove(this._entities_rectangle[i]);
        }
        this.floatingPoint = null;//标识点
        this._rectangle = null; //活动矩形
        this._rectangleLast = null; //最后一个矩形
        this._positions = [];  //活动点
        this._entities_point = [];  //脏数据
        this._entities_rectangle = [];  //脏数据
        this._rectangleData = null; //用于构造矩形数据
        this.viewer.scene.forceRender();
    }
    checkPositions(){
        let flag = true;
        for(let item of this._positions){
            if(!item || !item.x){
                flag = false;
                break;
            }
        }
       
        return flag;
    }
    getCatesian3FromPX(px) {
       
        var cartesian;
        var ray = this.viewer.camera.getPickRay(px);
        if (!ray) return null;
        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
        return cartesian;
    }
}

圆形:

/*
绘制圆
 */
export class DrawCircle {
    constructor(arg) {
        this.viewer = arg.viewer;
        this.Cesium = arg.Cesium;
        this.callback=arg.callback;
        this._cicle = null; //活动圆
        this.floatingPoint = null;
        this._cicleLast = null; //最后一个圆
        this._positions = [];  //活动点
        this._entities_point = [];  //脏数据
        this._entities_cicle = [];  //脏数据
        this._cicleData = null; //用于构造圆形数据
    }

    get cicle() {
        return this._cicleLast;
    }

    //加载圆
    loadCicle(data) {
        var that = this;
        var position = data[0];
        var value = data;
        var r = Math.sqrt(
            Math.pow(value[0].x - value[value.length - 1].x, 2) +
            Math.pow(value[0].y - value[value.length - 1].y, 2)
        );
        var shape = this.viewer.entities.add({
            position: position,
            name: "circle",
            type: "circle",
            ellipse: {
                semiMinorAxis: r,
                semiMajorAxis: r,
                material: that.Cesium.Color.RED.withAlpha(0.5),
                outline: true
            }
        });
        return shape;
    }

    //返回数据
    getData() {
        return this._cicleData;
    }

    startCreate() {
        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        this.viewer.scene.globe.depthTestAgainstTerrain = true;
        var $this = this;
        this.handler.setInputAction(function (evt) { //单机开始绘制
            $this.viewer.scene.globe.depthTestAgainstTerrain = true;
            //屏幕坐标转地形上坐标
            var cartesian = $this.getCatesian3FromPX(evt.position);
            if ($this._positions.length == 0) {
                $this._positions.push(cartesian.clone());
                $this.floatingPoint = $this.createPoint(cartesian);
            }
            if (!$this._cicle) {
                $this.createPoint(cartesian);// 绘制点
            }
            $this._positions.push(cartesian);
        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this.handler.setInputAction(function (evt) { //移动时绘制圆
            if ($this._positions.length < 1) return;
            var cartesian = $this.viewer.scene.pickPosition(evt.endPosition);// $this.getCatesian3FromPX(evt.endPosition);
            if (!$this.Cesium.defined($this._cicle)) {
                $this._cicle = $this.createCicle();
            }
            $this.floatingPoint.position.setValue(cartesian);
            if ($this._cicle) {
                $this._positions.pop();
                $this._positions.push(cartesian);
            }
        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        this.handler.setInputAction(function (evt) {
            if (!$this._cicle) return;
            $this.viewer.scene.globe.depthTestAgainstTerrain = false;
            var cartesian = $this.viewer.scene.pickPosition(evt.position); // $this.getCatesian3FromPX(evt.position);
            $this._positions.pop();
            $this._positions.push(cartesian);
            $this._cicleData = $this._positions.concat();
            $this.viewer.entities.remove($this._cicle); //移除
            $this._cicle = null;
            $this._positions = [];
            $this.floatingPoint.position.setValue(cartesian);
            var cicle = $this.loadCicle($this._cicleData); //加载
            $this._entities_cicle.push(cicle);
            $this._cicleLast = cicle;
            $this.clearPoint();
            if(typeof $this.callback=="function"){
                $this.callback(cicle);
            }
            $this.destroy();
        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        return this;
    }
    checkPositions(){
        let flag = true;
        for(let item of this._positions){
            if(!item || !item.x){
                flag = false;
                break;
            }
        }
       
        return flag;
    }
    //创建圆
    createCicle() {
        // if(this.checkPositions()){
            var that = this;
            var shape = this.viewer.entities.add({
                position: that._positions[0],
                name: "circle",
                type: "circle",
                ellipse: {
                    semiMinorAxis: new that.Cesium.CallbackProperty( ()=>{
                        //半径 两点间距离
                        if(that.checkPositions()){
                            var r = Math.sqrt(
                                Math.pow(that._positions[0].x - that._positions[that._positions.length - 1].x, 2) +
                                Math.pow(that._positions[0].y - that._positions[that._positions.length - 1].y, 2)
                            );
                            return r ? r : r + 1;
                        }

                    }, false),
                    semiMajorAxis: new that.Cesium.CallbackProperty( ()=> {
                        if(that.checkPositions()){
                            var r = Math.sqrt(
                                Math.pow(that._positions[0].x - that._positions[that._positions.length - 1].x, 2) +
                                Math.pow(that._positions[0].y - that._positions[that._positions.length - 1].y, 2)
                            );
                            return r ? r : r + 1;
                        }
     
                    }, false),
                    material: that.Cesium.Color.RED.withAlpha(0.5),
                    outline: true
                }
            });
            that._entities_cicle.push(shape);
            return shape;
        // }

    }

    //创建点
    createPoint(cartesian) {
        var $this = this;
        var point = this.viewer.entities.add({
            position: cartesian,
            point: {
                pixelSize: 10,
                color: $this.Cesium.Color.YELLOW,
            }
        });;
        $this._entities_point.push(point);
        return point;
    }

    getCatesian3FromPX(px) {
        var cartesian;
        var ray = this.viewer.camera.getPickRay(px);
        if (!ray) return null;
        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
        return cartesian;
    }

    destroy() {
        if (this.handler) {
            this.handler.destroy();
            this.handler = null;
        }
    }

    clearPoint(){
        for (var i = 0; i < this._entities_point.length; i++) {
            this.viewer.entities.remove(this._entities_point[i]);
        }
        this._entities_point = [];  //脏数据
    }
    clear() {

        for (var i = 0; i < this._entities_point.length; i++) {
            this.viewer.entities.remove(this._entities_point[i]);
        }

        for (var i = 0; i < this._entities_cicle.length; i++) {
            this.viewer.entities.remove(this._entities_cicle[i]);
        }
        this._cicle = null; //活动圆
        this.floatingPoint = null;
        this._cicleLast = null; //最后一个圆
        this._positions = [];  //活动点
        this._entities_point = [];  //脏数据
        this._entities_cicle = [];  //脏数据
        this._cicleData = null; //用于构造圆形数据
    }
}

多边形:

/*
绘制面
 */
class DrawPolygon {
    constructor(arg) {
        this.viewer = arg.viewer;
        this.Cesium = arg.Cesium;
        this.callback=arg.callback;
        this._polygon = null;  //活动面
        this._polygonLast = null;  //最后一个面
        this._positions = []; //活动点
        this._entities_point = [];  //脏数据
        this._entities_polygon = [];  //脏数据
        this._polygonData = null; //用户构造面
    }

    //返回最后活动面
    get polygon() {
        return this._polygonLast;
    }

    //返回面数据用于加载面
    getData() {
        return this._polygonData;
    }

    //加载面
    loadPolygon(data) {
        var $this = this;
        return this.viewer.entities.add({
            polygon: {
                hierarchy: new $this.Cesium.PolygonHierarchy(data),
                clampToGround: true,
                show: true,
                fill: true,
                material: $this.Cesium.Color.RED.withAlpha(0.5),
                width: 3,
                outlineColor: $this.Cesium.Color.BLACK,
                outlineWidth: 1,
                outline: false
            }
        });
    }
    checkPositions(){
        let flag = true;
        for(let item of this._positions){
            if(!item || !item.x){
                flag = false;
                break;
            }
        }
       
        return flag;
    }
    //开始绘制
    startCreate() {
        var $this = this;
        this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
        this.handler.setInputAction(function (evt) { //单机开始绘制
            var cartesian = $this.getCatesian3FromPX(evt.position);
            if ($this._positions.length == 0) {
                $this._positions.push(cartesian.clone());
            }
            $this.createPoint(cartesian);
            $this._positions.push(cartesian);
        }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this.handler.setInputAction(function (evt) { //移动时绘制面
            if ($this._positions.length < 1) return;
            var cartesian = $this.getCatesian3FromPX(evt.endPosition);
            if ($this._positions.length == 3) {
                if (!$this.Cesium.defined($this._polygon)) {
                    $this._polygon = $this.createPolygon();
                }
            }
            $this._positions.pop();
            $this._positions.push(cartesian);
        }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        this.handler.setInputAction(function (evt) {
            if (!$this._polygon) return;
            var cartesian = $this.getCatesian3FromPX(evt.position);
            $this._positions.pop();
            $this._positions.push(cartesian);
            $this.createPoint(cartesian);
            $this._polygonData = $this._positions.concat();
            $this.viewer.entities.remove($this._positions); //移除
            $this._positions=null;
            $this._positions = [];
            var Polygon = $this.loadPolygon($this._polygonData);
            $this._entities_polygon.push(Polygon);
            $this._polygonLast = Polygon;
            if(typeof $this.callback=="function"){
                $this.callback(Polygon);
            }
            $this.destroy();
        }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        return this;
    }

    //创建面
    createPolygon() {
            var $this = this;
        
            var polygon = this.viewer.entities.add({
                polygon: {
                    hierarchy: new $this.Cesium.CallbackProperty(()=> {
                        if($this.checkPositions()) {
                            return new $this.Cesium.PolygonHierarchy($this._positions);
                        }
                        
                    }, false),
                    clampToGround: true,
                    show: true,
                    fill: true,
                    material: $this.Cesium.Color.RED.withAlpha(0.5),
                    width: 3,
                    outlineColor: $this.Cesium.Color.BLACK,
                    outlineWidth: 1,
                    outline: false
                }
            });
            $this._entities_polygon.push(polygon);
            return polygon;
        

    }

    //创建点
    createPoint(cartesian) {
        var $this = this;
        var point = this.viewer.entities.add({
            position: cartesian,
            point: {
                pixelSize: 10,
                color: $this.Cesium.Color.YELLOW,
            }
        });
        $this._entities_point.push(point);
        return point;
    }


    //销毁事件
    destroy() {
        if (this.handler) {
            this.handler.destroy();
            this.handler = null;
        }
    }

    //清空实体对象
    clear() {
        for (var i = 0; i < this._entities_point.length; i++) {
            this.viewer.entities.remove(this._entities_point[i]);
        }
        for (var i = 0; i < this._entities_polygon.length; i++) {
            this.viewer.entities.remove(this._entities_polygon[i]);
        }
        this._polygon = null;  //活动面
        this._polygonLast = null;  //最后一个面
        this._positions = []; //活动点
        this._entities_point = [];  //脏数据
        this._entities_polygon = [];  //脏数据
        this._polygonData = null; //用户构造面
    }

    getCatesian3FromPX(px) {
        var cartesian;
        var ray = this.viewer.camera.getPickRay(px);
        if (!ray) return null;
        cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
        return cartesian;
    }
}

export default DrawPolygon

调用

        callbackFun(obj) {
            console.log('画完了~~', obj)
            this.entity = obj;
            this.drawsObj.destroy()//销毁handler事件交互
        },

        clearDraw() {
            this.viewer.entities.removeAll()
        },
        createShape(str) {
            this.clearDraw()

            let obj;
            let params = {
                viewer: this.viewer,
                Cesium: this.Cesium,
                callback: this.callbackFun
            };
            switch (str) {
                case 'square':
                    obj = new DrawRectangle(params);
                    break;
                case 'circular':
                    obj = new DrawCircle(params);
                    break;
                case 'polygon':
                    obj = new DrawPolygon(params);
                    break;
            }
            
            this.drawsObj = obj.startCreate();
            this.rectCon[str] = this.drawsObj;//缓存图形数据
        }
这里我们需要注意一下交互事件问题。 2.png

如图所示,如果我选了矩形、然后再选择圆形的话,这时会建立两个handler事件交互,这样就会同时画出两个图形,这是不对的。
正确的做法是,选择一个图形,要把上一个图形的handler销毁掉。

    watch: {
        shape: {
            handler(val, oldVal) {
                console.log(val, oldVal)
                if (val) {

                    if(oldVal) {
                        //防止多次创建图形交互,将上一次对象的交互清除
                        console.log('框选容器>>>',this.rectCon);

                        Object.keys(this.rectCon).map(item=>{
                            console.log(item);
                            if(item && item === oldVal) {
                                this.rectCon[item].destroy();
                                this.rectCon[item].clear();
                            }
                            
                        });
                    }

                    this.createShape(val);//画出图形
                } else {
                    
                    this.destroyHandler()
                }
            },
            deep: true,
            immediate: true
        }

    },
上一篇下一篇

猜你喜欢

热点阅读