Cesium动态绘制实体(点、标注、面、线、圆、矩形)

 

//自定义绘制图形,支持 点,线,面,矩形,圆,标识,可自定义绘制过程中的和绘制完的预览
    this.drawGraphic = function(view,_mode,_callback,_GraphicProperty){
        //清空所有可能的监听和画到一半的图形
        if(handler){
            handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
            handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
            handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
            handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        }
        if(activeShapePoints||activeShape||floatingPoint||boundaryPoints.length>0||returnGraphic){
            if(floatingPoint){
                view.entities.remove(floatingPoint);
                floatingPoint = undefined;
            }
            if(activeShape){
                view.entities.remove(activeShape);
                activeShape = undefined;
            }
            activeShapePoints = [];
            if(boundaryPoints.length>0){
                for(let i=0;i<boundaryPoints.length;i++){
                    view.entities.remove(boundaryPoints[i]);
                }
            }
        }
       //配置
        var drawingMode = _mode;
        var GraphicProperty;
        if(_GraphicProperty===null||_GraphicProperty===""||_GraphicProperty===undefined){
            GraphicProperty = {}
        }else{
            GraphicProperty=_GraphicProperty
        }
        //监听左键点击事件
        function listenClick(_view,_callback) {
            handler = new Cesium.ScreenSpaceEventHandler(view.scene.canvas);
            handler.setInputAction(function(movement) {
                let position = view.scene.pickPosition(movement.position);
                let screenPosition = movement.position;
                let callbackObj = {};
                callbackObj.cartesian3=position;
                callbackObj.movement=movement;
                callbackObj.screenPosition=screenPosition;
                _callback(callbackObj,handler);
            },Cesium.ScreenSpaceEventType.LEFT_CLICK);
        }
        //模式判断
        if(drawingMode==='point'){
            listenClick(_view, function(callbackObj, handler) {
                let position = callbackObj.cartesian3;
                let Point;
                //构造实体
                if(GraphicProperty.style&&GraphicProperty.style.point){
                    Point =  view.entities.add({
                        id:GraphicProperty.id||null,
                        description:GraphicProperty.description||'',
                        name:GraphicProperty.name||'',
                        position:position,
                        point:GraphicProperty.style.point
                    });
                }else{
                    Point =  view.entities.add({
                        type:'Selection tool',
                        position:position,
                        point:{
                            color:  Cesium.Color.WHITE,
                            pixelSize: 10,
                            outlineColor: Cesium.Color.BLACK,
                            outlineWidth:  0,
                            show:  true,
                        }
                    });
                }
                //回调产生的点
                if(_callback){
                    _callback(Point);
                }
                //销毁左键监听
                handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
                handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
                handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
            });
        }
        else if(drawingMode==='marker'){
            if(GraphicProperty.style&&GraphicProperty.style.billboard){
                listenClick(_view, function(callbackObj, handler) {
                    //此时场景中的点
                    let position = callbackObj.cartesian3;
                    //赋值,构造点实体Entity
                    let  Marker =  view.entities.add({
                        id:GraphicProperty.id||null,
                        description:GraphicProperty.description||null,
                        name:GraphicProperty.name||'',
                        type:'Selection tool',
                        show:GraphicProperty.show||true,
                        position:position,
                        billboard:GraphicProperty.style.billboard
                    });
                    //回调构造的点
                    if(_callback){
                        _callback(Marker);
                    }
                    //销毁
                    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
                    handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
                    handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
                });
            }else{
                listenClick(_view, function(callbackObj, handler) {
                    //此时场景中的点
                    let position = callbackObj.cartesian3;
                    //赋值,构造点实体Entity
                    let  Marker =  view.entities.add({
                        type:'Selection tool',
                        show: true,
                        position:position,
                        point:{
                            color:  Cesium.Color.WHITE,
                            pixelSize: 10,
                            outlineColor: Cesium.Color.BLACK,
                            outlineWidth:  0,
                            show:  true,
                        }
                    });
                    //回调构造的点
                    if(_callback){
                        _callback(Marker);
                    }
                    //销毁
                    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                    handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
                    handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
                    handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
                });
            }
        }
        else{
            handler = new Cesium.ScreenSpaceEventHandler(view.canvas);
            //取消自带的双击放大监听
            view.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
            //构造点,例如在活动的提示点
            function createPoint(worldPosition) {
                var point = view.entities.add({
                    position : worldPosition,
                    point : {
                        color : Cesium.Color.WHITE,
                        pixelSize : 5,
                    }
                });
                return point;
            }
            //绘制图形
            function drawShape(positionData) {
                var shape;
                if (drawingMode === 'polyline') {
                    if(GraphicProperty.style&&GraphicProperty.style.polyline){
                        GraphicProperty.style.polyline.positions=positionData;
                        shape = view.entities.add({
                            id:GraphicProperty.id||null,
                            name:GraphicProperty.name||'',
                            description:GraphicProperty.description||'',
                            polyline : GraphicProperty.style.polyline
                        });
                    }else{
                        shape = view.entities.add({
                            polyline : {
                                positions : positionData,
                                width : 3
                            }
                        });
                    }
                }
                else if (drawingMode === 'polygon') {
                    if(GraphicProperty.style&&GraphicProperty.style.polygon){
                        GraphicProperty.style.polygon.hierarchy=positionData;
                        GraphicProperty.style.polygon.perPositionHeight=true;
                        shape = view.entities.add({
                            id:GraphicProperty.id||null,
                            name:GraphicProperty.name||'',
                            description:GraphicProperty.description||'',
                            polygon:GraphicProperty.style.polygon
                        });
                    }else{
                        shape = view.entities.add({
                            polygon: {
                                hierarchy: positionData,
                                material: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE.withAlpha(0.7)),
                                perPositionHeight:true
                            }
                        });
                    }
                }
                else if (drawingMode === 'circle'){
                    //当positionData为数组时绘制最终图,如果为function则绘制动态图
                    let xyz = new Cesium.Cartesian3(activeShapePoints[0].x, activeShapePoints[0].y, activeShapePoints[0].z);
                    //转WGS84
                    let wgs84 = view.scene.globe.ellipsoid.cartesianToCartographic(xyz);
                    let height = wgs84.height;
                    let value = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData;
                    if(GraphicProperty.style&&GraphicProperty.style.ellipse){
                        GraphicProperty.style.ellipse.semiMinorAxis=new Cesium.CallbackProperty(function () {
                            //半径 两点间距离
                            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));
                            return r ? r : r + 1;
                        }, false);
                        GraphicProperty.style.ellipse.semiMajorAxis=new Cesium.CallbackProperty(function () {
                            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));
                            return r ? r : r + 1;
                        }, false);
                        GraphicProperty.style.ellipse.height=height;
                        shape = view.entities.add({
                            position: activeShapePoints[0],
                            id:GraphicProperty.id||null,
                            name:GraphicProperty.name||'',
                            description:GraphicProperty.description||'',
                            ellipse:GraphicProperty.style.ellipse
                        });
                    }
                    else{
                        shape = view.entities.add({
                            position: activeShapePoints[0],
                            ellipse: {
                                semiMinorAxis: new Cesium.CallbackProperty(function () {
                                    //半径 两点间距离
                                    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));
                                    return r ? r : r + 1;
                                }, false),
                                semiMajorAxis: new Cesium.CallbackProperty(function () {
                                    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));
                                    return r ? r : r + 1;
                                }, false),
                                material: GraphicProperty.material||Cesium.Color.BLUE.withAlpha(0.5),
                                height:height,
                                outline: true
                            }
                        });
                    }
                }
                else if (drawingMode === 'rectangle'){
                    let xyz = new Cesium.Cartesian3(activeShapePoints[0].x, activeShapePoints[0].y, activeShapePoints[0].z);
                    //转WGS84
                    let wgs84 = view.scene.globe.ellipsoid.cartesianToCartographic(xyz);
                    let height = wgs84.height;
                    //当positionData为数组时绘制最终图,如果为function则绘制动态图
                    let arr = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData;
                    if(GraphicProperty.style&&GraphicProperty.style.rectangle){
                        GraphicProperty.style.rectangle.coordinates=new Cesium.CallbackProperty(function () {
                            return Cesium.Rectangle.fromCartesianArray(arr);
                        }, false);
                        GraphicProperty.style.rectangle.height=height;
                        shape = view.entities.add({
                            id:GraphicProperty.id||null,
                            name:GraphicProperty.name||'',
                            description:GraphicProperty.description||'',
                            rectangle : GraphicProperty.style.rectangle
                        });
                    }else{
                        shape = view.entities.add({
                            rectangle : {
                                coordinates :  new Cesium.CallbackProperty(function () {
                                    return Cesium.Rectangle.fromCartesianArray(arr);
                                }, false),
                                material : Cesium.Color.GREEN.withAlpha(0.5),
                                height:height
                            }
                        });
                    }
                }
                return shape;
            }
            //左键监听,每一次绘制都要留下记录
            handler.setInputAction(function(event) {
              //在场景中使用深度拾取scene.pickPosition  globe的pick还有camera的pick在场景中拾取不准确
                var earthPosition = view.scene.pickPosition(event.position);
                //当鼠标不在地表时,earthPosition切成未定义undefined
                if (Cesium.defined(earthPosition)) {
                    if (activeShapePoints.length === 0) {
                        floatingPoint = createPoint(earthPosition);
                        activeShapePoints.push(earthPosition);
                        var dynamicPositions = new Cesium.CallbackProperty(function () {
                            if (drawingMode === 'polygon') {
                                return new Cesium.PolygonHierarchy(activeShapePoints);
                            }
                            return activeShapePoints;
                        }, false);
                        activeShape = drawShape(dynamicPositions);
                    }
                    activeShapePoints.push(earthPosition);
                    let boundaryPoint=createPoint(earthPosition);
                    boundaryPoints.push(boundaryPoint);
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
            //鼠标移动的监听
            handler.setInputAction(function(event) {
                if (Cesium.defined(floatingPoint)) {
                    var newPosition = view.scene.pickPosition(event.endPosition);
                    if (Cesium.defined(newPosition)) {
                        floatingPoint.position.setValue(newPosition);
                        activeShapePoints.pop();
                        activeShapePoints.push(newPosition);
                    }
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
            //重置图形,形成最终形态,把动态过程中的图形全部去掉
            function terminateShape() {
                activeShapePoints.pop();
                let final_Entity;
                if(activeShapePoints.length){
                    final_Entity = drawShape(activeShapePoints);//绘制最终图
                }
                view.entities.remove(floatingPoint);
                view.entities.remove(activeShape);
                floatingPoint = undefined;
                activeShape = undefined;
                activeShapePoints = [];
                for(let i=0;i<boundaryPoints.length;i++){
                    view.entities.remove(boundaryPoints[i]);
                }
                return final_Entity;
            }
            //右键监听,结束画图
            handler.setInputAction(function(event) {
                returnGraphic = terminateShape();
                if(_callback){
                    _callback(returnGraphic);
                }
                handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
                handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
                handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
            }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        }
    };

 

 

 

 

点、标注、面、线、圆、矩形的style式样构造按照Cesium自己的那个graphic来构造
//构造polygon属性
  function constructPolygon(_param){
        if(!_param){
            _param={};
        }
        let PolygonlEntity = {};
        PolygonlEntity.polygon = {
            hierarchy: _param.hierarchy||null,
            show:_param.show||true,
            fill:_param.fill||true,
            outline: _param.outline || false,
            outlineWidth: _param.maximumHeights || null,
            outlineColor: _param.show || true,
            distanceDisplayCondition: _param.distanceDisplayCondition || undefined,
            material:_param.material||Cesium.Color.WHITE,
            perPositionHeight:_param.perPositionHeight||true    //这个属性是false时会始终贴在地表,不会变成空间性的面
        };
        return PolygonlEntity;
    };

//构造polyline属性
   function constructPolyline(_param) {
        if(!_param){
            _param={};
        }
        let PolylineEntity = {};
        PolylineEntity.polyline = {
            width: _param.width || 1.0,
            positions: _param.positions||null,
            show: _param.show || true,
            material: _param.material || Cesium.Color.WHITE,
            distanceDisplayCondition: _param.distanceDisplayCondition || undefined
        };
        return PolylineEntity;
    };

//构造rectangle属性
  function constructRectangle(_param) {
        if(!_param){
            _param={};
        }
        let RectangleEntity = {};
        RectangleEntity.rectangle = {
            coordinates: _param.coordinates||null,
            show: _param.show || true,
            fill: _param.fill || true,
            material: _param.material || Cesium.Color.WHITE,
            distanceDisplayCondition: _param.distanceDisplayCondition || undefined
        };
        return RectangleEntity;
    };

//构造point属性
  function constructPoint(_param) {
        let PointEntity = {};
        if (!_param) {
            _param = {}
        }
        PointEntity.point = {
            color: _param.color || Cesium.Color.WHITE,
            pixelSize: _param.pixelSize || 1,
            outlineColor: _param.outlineColor || Cesium.Color.BLACK,
            outlineWidth: _param.outlineWidth || 0,
            show: _param.show || true,
            scaleByDistance: _param.scaleByDistance || null,
            translucencyByDistance: _param.translucencyByDistance || null,
            heightReference: _param.heightReference || Cesium.HeightReference.NONE,
            distanceDisplayCondition: _param.distanceDisplayCondition || undefined,
        };
        return PointEntity;
    };

//构造marker(billboard)属性
   function constructBillboard(_param) {
        if(!_param){
            _param={};
        }
        let BillboardEntity = {};
        BillboardEntity.billboard = {
            image: _param.image||null,
            show: _param.show || true,
            scale: _param.scale || 1.0,
            eyeOffset: _param.eyeOffset || Cesium.Cartesian3.ZERO,
            pixelOffset: _param.pixelOffset || Cesium.Cartesian2.ZERO,
            // sizeInMeters:_param.sizeInMeters||true,
            horizontalOrigin: _param.horizontalOrigin || Cesium.HorizontalOrigin.CENTER, //水平方向  中心
            verticalOrigin: _param.verticalOrigin || Cesium.VerticalOrigin.CENTER, //垂直方向 底部
            rotation: _param.rotation || 0,
            heightReference: _param.heightReference || Cesium.HeightReference.NONE,
            distanceDisplayCondition:_param.distanceDisplayCondition ||undefined
            // pixelOffsetScaleByDistance:_param.pixelOffsetScaleByDistance
        };
        return BillboardEntity
    };

//构造circle(ellipse)的属性
    function constructEllipse(_param) {
        if(!_param){
            _param={};
        }
        let EllipseEntity = {};
        EllipseEntity.ellipse = {
            semiMinorAxis: _param.semiMinorAxis || 2000,
            semiMajorAxis: _param.semiMajorAxis || 2000,
            height: _param.height || 0,
            material: _param.material || Cesium.Color.WHITE,
        };
        return EllipseEntity;
    };
 
 

 

绘制

 let pointStyle = {
        style: constructPoint({
            color: Cesium.Color.RED,
            pixelSize: 10,
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 0,
            show: true,
            distanceDisplayCondition: camera.DistanceDisplayCondition(0.1, 2500.0)
        })
    };

    let markerStyle = {
        style: constructBillboard({
            image: 'images/pic.png',
            scale: 0.3,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            pixelOffset: coordinates.createCatesian2(0, -20),
        })
    };

    let rectangleStyle = {
        style: constructRectangle({
            material:style.setColorWithAlpha(Cesium.Color.GREEN,0.5)
        })
    };

    let circleStyle = {
        style: constructEllipse({
            material:style.setColorWithAlpha(Cesium.Color.DARKGOLDENROD,0.5)
        })
    };

    //绘制
    let drawarr = [];
    function draW(e) {
        switch (e) {
            case 'point':
                drawGraphic(view,'point',function (_entity) {
                    drawarr.push(_entity);
                },pointStyle);
                break;
            case 'polyline':
                drawGraphic(view,'polyline',function (_entity) {
                    drawarr.push(_entity);
                },polylineStyle);
                break;
            case 'polygon':
                drawGraphic(view,'polygon',function (_entity) {
                    drawarr.push(_entity);
                },polygonStyle);
                break;
            case 'marker':
                drawGraphic(view,'marker',function (_entity) {
                    drawarr.push(_entity);
                },markerStyle);
                break;
            case 'circle':
                drawGraphic(view,'circle',function (_entity) {
                    drawarr.push(_entity);
                },circleStyle);
                break;
            case 'rectangle':
                drawGraphic(view,'rectangle',function (_entity) {
                    drawarr.push(_entity);
                },rectangleStyle);
                break;
        }
    }

 

 

最终效果:

Cesium是一个开源的3D地球可视化引擎,可以用来展示地球上的各种实体。在Cesium动态绘制实体需要以下步骤: 1. 导入Cesium库和相关的插件,比如Cesium.js和Cesium-terrain-builder等。 2. 创建一个Cesium Viewer对象,并设置地球的初始位置和视角。 3. 添加水实体对象,可以使用Cesium的Entity对象来表示水,其中的属性包括位置、高度、颜色、纹理等。 4. 使用Cesium的时间轴(TimeLine)控件来控制水实体动态变化,比如水位的上升和下降等。 5. 根据需要设置其他的场景参数,比如光照、阴影、雾气等。 下是一个简单的示例代码,演示了如何在Cesium动态绘制实体: ```javascript // 创建Cesium Viewer对象 var viewer = new Cesium.Viewer('cesiumContainer', { terrainProvider: Cesium.createWorldTerrain() }); // 设置地球的初始位置和视角 viewer.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 20000), orientation: { heading: Cesium.Math.toRadians(20), pitch: Cesium.Math.toRadians(-20), roll: 0 } }); // 添加水实体对象 var waterSurface = viewer.entities.add({ name: 'Water Surface', position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 0), ellipsoid: { radii: new Cesium.Cartesian3(1000, 1000, 1000), material: new Cesium.Color(0, 0.5, 1, 0.5) } }); // 使用Cesium的时间轴控件来控制水实体动态变化 viewer.timeline.addEventListener('settime', function(e) { var time = e.timeJulian; var waterLevel = Math.sin(time) * 50; waterSurface.position = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, waterLevel); }); // 设置其他的场景参数 viewer.scene.globe.enableLighting = true; viewer.scene.fog.enabled = true; ``` 在以上代码中,我们先创建了一个Cesium Viewer对象,并设置了地球的初始位置和视角。然后,我们添加了一个水实体对象,使用了Cesium的Entity对象来表示水,其中的属性包括位置、高度、颜色、纹理等。接着,我们使用Cesium的时间轴控件来控制水实体动态变化,根据时间变化来更新水的高度。最后,我们设置了其他的场景参数,比如光照、阴影、雾气等,以增强场景的真实感和美观度。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值