Cesium 动态绘制点线面

1,049 阅读1分钟

我写的这个点线面绘制融入了增删改的功能。
其中可以通过手动点击地图进行动态绘制线面,也支持通过给定坐标数组来进行线面的增加。
绘制好的线面,可以点击进行修改;
以上介绍了我的大概的要给操作,下面以面的构建来进行代码解释;
cesium中想动态构建线面,离不开的一个属性就是CallbackProperty。
以下是部分核心代码:
1、构建面核心代码
此处面的postions用了callbackproperty,就可以进行动态绘制了,关于property的讲解可以参阅:www.jianshu.com/p/f0b479972…

createPolygon: function(obj) {
        var $this = this;
        return this.viewer.entities.add({
            polygon: {
                hierarchy: new Cesium.CallbackProperty(function() {
                    return $this.positions
                }, false),
                clampToGround: obj.clampToGround || true,
                show: true,
                fill: obj.fill || true,
                material: obj.material || Cesium.Color.WHITE,
                width: obj.width || 3,
                outlineColor: obj.outlineColor || Cesium.Color.BLACK,
                outlineWidth: obj.outlineWidth || 1,
                outline: false || obj.outline

            }

        });
    },

2、操作逻辑核心代码
大致解释以下操作逻辑:
首先是绑定了鼠标左击,当鼠标在地图上点击时,会保存点击的坐标,用于构建面。鼠标移动时,会动态显示面;
鼠标右击时结束操作;

startCreate: function(callBack) {
        var $this = this;
        this.handler.setInputAction(function(evt) { //单机开始绘制
            var cartesian = cCesium.getCatesian3FromPX(evt.position, $this.viewer);
            if ($this.positions.length == 0) {
                $this.positions.push(cartesian.clone());
            }
            $this.positions.push(cartesian);
            var point = $this.createPoint(cartesian);
            point.wz = $this.gonPointArr.length;
            $this.gonPointArr.push(point);
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this.handler.setInputAction(function(evt) { //移动时绘制面
            if ($this.positions.length < 1) return;
            var cartesian = cCesium.getCatesian3FromPX(evt.endPosition, $this.viewer);
            if ($this.positions.length == 2) {
                if (!Cesium.defined($this.polygon)) {
                    $this.polygon = $this.createPolygon($this.style);
                    $this.polygon.objId = $this.objId;
                }
            }
            if ($this.polygon) {
                $this.positions.pop();
                $this.positions.push(cartesian);
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        this.handler.setInputAction(function(evt) {
            if (!$this.polygon) return;
            var cartesian = cCesium.getCatesian3FromPX(evt.position, $this.viewer);
            $this.state = 1;
            $this.handler.destroy();
            if ($this.floatPoint) {
                if ($this.floatPoint) $this.floatPoint.show = false;
                $this.floatPoint = null;
            }
            $this.positions.pop();
            $this.positions.push(cartesian);
            var point = $this.createPoint(cartesian);
            point.wz = $this.gonPointArr.length;
            $this.gonPointArr.push(point);
            callBack($this.polygon);
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    }

getCatesian3FromPX方法是在模型或者地形上获取点的通用方法,此处兼容模型和地形上坐标的获取;

//通过屏幕坐标获取地形或者模型上的点 entity为需屏蔽的实体
    function getCatesian3FromPX(px, viewer, entity) {
        var pick = viewer.scene.pick(px);
        var cartesian;
        var drillPick = viewer.scene.drillPick(px);
        var truePick = null;
        if (entity) {
            for (var i = 0; i < drillPick.length; i++) {
                if (drillPick[i].id._id != entity.id) {
                    truePick = drillPick[i].id;
                    break;
                }
            }
        } else {
            truePick = pick;
        }
        if (viewer.scene.pickPositionSupported && Cesium.defined(truePick)) { //表示选中的是模型上某点
            cartesian = viewer.scene.pickPosition(px);
        } else {
            var ray = viewer.camera.getPickRay(px);
            if (!ray) return;
            cartesian = viewer.scene.globe.pick(ray, viewer.scene);
        }
        return cartesian;
    }