• cesium entity 和primitive 绘制对象 primitive合并 但是有不同的外观 定义几何体的时候设置外观属性


    Entity 和primitive 对比

    1. entity偏向数据,primitive偏向图形.primitive更底层
    2. entity用法简单,primitive用法复杂。我们会有这样的疑问:entity已经封装的如此完美,调用如此便捷,为何还要primitive接口呢?区别就是加载效率。primitive更接近webgl底层,没有entity各种各样的附加属性,因此在加载时效率会更高。为了直观感受两者区别,我们分别用entity和primitive方式绘制3150个圆。
    一entity方式
    for (var lon = -180.0; lon < 180.0; lon += 4.0) {
                for (var lat = -70.0; lat < 70.0; lat += 4.0) {
                    viewer.entities.add({
                        position: Cesium.Cartesian3.fromDegrees(lon, lat),
                        ellipse: {
                            semiMinorAxis: 10000.0,
                            semiMajorAxis: 10000.0,
                            //height: 200000.0,
                            material: Cesium.Color.GREEN
                        }
                    });
                }
            }
     //primitive方式
            var instances = [];
            for (var lon = -180.0; lon < 180.0; lon += 4.0) {
                for (var lat = -70.0; lat < 70.0; lat += 4.0) {
                    var ellipse = new Cesium.EllipseGeometry({
                        center: Cesium.Cartesian3.fromDegrees(lon, lat),
                        semiMajorAxis: 10000.0,
                        semiMinorAxis: 10000.0,
                        vertexFormat: Cesium.VertexFormat.POSITION_ONLY
                    });
                    var geometry = Cesium.EllipseGeometry.createGeometry(ellipse);
                    var ellipseInstance = new Cesium.GeometryInstance({
                        geometry: geometry,
                        attributes: {
                            color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
                        }
                    });
    
                    instances.push(ellipseInstance);
                }
            }
            viewer.scene.primitives.add(new Cesium.Primitive({
                geometryInstances: instances,
                appearance: new Cesium.PerInstanceColorAppearance()
    
            }));
    

    查看浏览器内存消耗情况:

    Cesium学习笔记18--绘制对象-效率比较

    Entity

    1材质
    空间对象可视化,不仅需要知道对象的空间位置,还需要知道对象的显示样式。显示样式就是通过材质来控制,比如说颜色、透明度、纹理贴图、更高级的光照等等。我们常用到就是颜色和透明度。
    以下代码为绘制一个半透明的红色椭圆,设置material为Cesium.Color.RED.withAlpha(0.5)透明度为0.5的红色:
        viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(103.0, 40.0),
            name: 'Red ellipse on surface with outline',
            ellipse: {
                semiMinorAxis: 250000.0,
                semiMajorAxis: 400000.0,
                material: Cesium.Color.RED.withAlpha(0.5),
            }
        });
    2填充和边框
    填充和边框共同组成了面状对象的样式,通过制定属性fill(默认为true)和outline(默认为false)来确定是否显示填充和边框,material对应填充样式,outlineColor和outlineWidth对应边框的颜色和宽度。如一下内容绘制一个填充半透明红色边框为蓝色的椭圆:
     viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(103.0, 40.0),
            name: 'Red ellipse on surface with outline',
            ellipse: {
                semiMinorAxis: 300000.0,
                semiMajorAxis: 300000.0,
                height: 200000.0,
                fill:true,
                material: Cesium.Color.RED.withAlpha(0.5),
                outline: true, //必须设置height,否则ouline无法显示
                outlineColor: Cesium.Color.BLUE.withAlpha(0.5),
                outlineWidth:10.0//不能设置,固定为1
            }
        });
    效果:
    Cesium学习笔记14--绘制对象-Entity管理
    
    3贴图
    通过设置material为图片url,可以将图片填充到对象中:
     viewer.entities.add({
                position: Cesium.Cartesian3.fromDegrees(103.0, 40.0),
                name: 'Red ellipse on surface with outline',
                ellipse: {
                    semiMinorAxis: 250000.0,
                    semiMajorAxis: 400000.0,
                    height: 200000.0,
                    fill:true,
                    material: "./sampledata/images/globe.jpg",
                    outline: true, //必须设置height,否则ouline无法显示
                    outlineColor: Cesium.Color.BLUE.withAlpha(0.5),
                    outlineWidth: 10.0//windows系统下不能设置固定为1
                }
            });
    4垂直拉伸
    有时候我们需要将面在垂直方向进行拉伸形成体,通过extrudedHeight即可实现这种效果,形成的体积任然符合它拉伸面的地球曲率。
    viewer.entities.add({
                position: Cesium.Cartesian3.fromDegrees(103.0, 40.0),
                name: 'Red ellipse on surface with outline',
                ellipse: {
                    semiMinorAxis: 250000.0,
                    semiMajorAxis: 400000.0,
                    height: 200000.0,
                    extrudedHeight: 400000.0,
                    fill:true,
                    material: Cesium.Color.RED.withAlpha(0.5),
                    outline: true, //必须设置height,否则ouline无法显示
                    outlineColor: Cesium.Color.BLUE.withAlpha(0.5),
                    outlineWidth:10.0//windows系统下不能设置固定为1
                }
            });
    5场景中entity管理
    viewer.entities属性实际上是一个EntityCollecton对象,是entity的一个集合,提供了add、remove、removeAll等等接口来管理场景中的entity。
    查看帮助文档,提供一下接口:
    Cesium.EntityCollection.collectionChangedEventCallback(collection, added, removed, changed)
    add(entity) → Entity
    computeAvailability() → TimeInterval
    contains(entity) → Boolean
    getById(id) → Entity
    getOrCreateEntity(id) → Entity
    remove(entity) → Boolean
    removeAll()
    removeById(id) → Boolean
    resumeEvents()
    suspendEvents()
    6选择
    在多数应用场景中,我们不仅需要绘制出空间对象还需要用鼠标拾取对象,cesium为我们提供了scene.pick接口,如下代码实现坐标左键单击实现对象的拾取:
     viewer.entities.add({
                id:'obj_id_110',
                position: Cesium.Cartesian3.fromDegrees(103.0, 40.0),
                name: 'Red ellipse on surface with outline',
                ellipse: {
                    semiMinorAxis: 250000.0,
                    semiMajorAxis: 400000.0,
                    height: 200000.0,
                    extrudedHeight: 400000.0,
                    fill: true,
                    material: Cesium.Color.RED.withAlpha(0.5),
                    outline: true, //必须设置height,否则ouline无法显示
                    outlineColor: Cesium.Color.BLUE.withAlpha(0.5),
                    outlineWidth: 10.0//windows系统下不能设置固定为1
                }
            });
    
            var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
            handler.setInputAction(function (movement) {
                var pick = viewer.scene.pick(movement.position);
                if (Cesium.defined(pick) && (pick.id.id === 'obj_id_110')) {
                    ;
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    
    以上代码,在添加的entity中加入id唯一标识,然后利用ScreenSpaceEventHandler接口监听鼠标事件,在左键单击事件中,通过viewer.scene.pick获取点击出的对象,如果对象不为空且id匹配则说明选中。
    
    

    Primitive

    1合并几何图形(Combing Geometries)
    cesium给出primitive最大用意应该是提高渲染效率问题,当我们使用一个图元绘制多个静态对象时,这种优势就显现出来了。下面代码时绘制两个对象:
    var instance = new Cesium.GeometryInstance({
                geometry: new Cesium.RectangleGeometry({
                    rectangle: Cesium.Rectangle.fromDegrees(105.20, 30.55, 106.20, 31.55),
                    vertexFormat:Cesium.EllipsoidSurfaceAppearance.VERTEXT_FORMAT
                })
            });
            var instance1 = new Cesium.GeometryInstance({
                geometry: new Cesium.RectangleGeometry({
                    rectangle: Cesium.Rectangle.fromDegrees(107.20, 30.55, 108.20, 31.55),
                    vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEXT_FORMAT
                })
            });
            viewer.scene.primitives.add(new Cesium.Primitive({
                geometryInstances: [instance, instance1],
                appearance: new Cesium.EllipsoidSurfaceAppearance({
                    material:Cesium.Material.fromType('Stripe')
                })
            }));
    我们可以使用PerInstanceColorAppearance为每个实例赋不同颜色:
    var instance = new Cesium.GeometryInstance({
                geometry: new Cesium.RectangleGeometry({
                    rectangle: Cesium.Rectangle.fromDegrees(105.20, 30.55, 106.20, 31.55),
                    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEXT_FORMAT
                }),
                attributes: {
                    color:new Cesium.ColorGeometryInstanceAttribute(0.0,0.0,1.0,0.8)
                }
            });
            var instance1 = new Cesium.GeometryInstance({
                geometry: new Cesium.RectangleGeometry({
                    rectangle: Cesium.Rectangle.fromDegrees(107.20, 30.55, 108.20, 31.55),
                    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEXT_FORMAT
                }),
                attributes: {
                    color: new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 0.8)
                }
            });
            viewer.scene.primitives.add(new Cesium.Primitive({
                geometryInstances: [instance, instance1],
                appearance: new Cesium.PerInstanceColorAppearance()
            }));
    合并多个GeometryInstances 为一个Primitive可以极大的提高性能,下面的例子创建了2592一颜色各异的矩形,覆盖整个地球 :
    var instances = [];
            for (var lon = -180.0; lon < 180.0; lon += 5.0) {
                for (var lat = -90.0; lat < 90.0; lat += 5.0) {
                    instances.push(new Cesium.GeometryInstance({
                    geometry: new Cesium.RectangleGeometry({
                    rectangle: Cesium.Rectangle.fromDegrees(lon, lat, lon + 5.0, lat +5.0)
                        }),
                        attributes: {
                            color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({
                                alpha: 0.5
                            }))
                        }
                    }));
                }
            }
            viewer.scene.primitives.add(new Cesium.Primitive({
                geometryInstances: instances, //合并
                //某些外观允许每个几何图形实例分别指定某个属性,例如:
                appearance: new Cesium.PerInstanceColorAppearance()
            }));
    2选取几何图形(Picking)
    即使多个 GeometryInstance被合并为单个Primitive,让然可以独立的被访问。我们可以为每一个GeometryInstance指定一个id,并且可以通过Scene.pick来判断该实例是否被选取:
     var instance = new Cesium.GeometryInstance({
                geometry: new Cesium.RectangleGeometry({
                    rectangle: Cesium.Rectangle.fromDegrees(107.20, 30.55, 108.20, 31.55)
                }),
                id: 'rectangle-1',
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
                }
            });
            viewer.scene.primitives.add(new Cesium.Primitive({
                geometryInstances: instance,
                appearance: new Cesium.PerInstanceColorAppearance()
            }));
            var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
            //设置单击事件的处理句柄
            handler.setInputAction(function (movement) {
                var pick = viewer.scene.pick(movement.position);
                if (Cesium.defined(pick) && (pick.id === 'rectangle-1')) {
                    ;
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    3几何图形实例(Geometry Instances)
    上面的例子中,我们已经用到了GeometryInstances,注意GeometryInstance与Geometry的关系:前者是后者的容器,多个Instance可以共用一个Geometry,并且可以通过GeometryInstances.modelMatrix属性提供不同position、scale、rotate等位置、缩放、旋转信息。例如,下面的例子使用同一个Geometry绘制了两个Instance,一个位于另一个的上方:
    var ellipsoidGeometry = new Cesium.EllipsoidGeometry({
                vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
                radii: new Cesium.Cartesian3(300000.0, 200000.0, 150000.0)//三轴半径
            });
            //下方的实例
            var cyanEllipsoidInstance = new Cesium.GeometryInstance({
                geometry: ellipsoidGeometry,
                modelMatrix: Cesium.Matrix4.multiplyByTranslation(
                   Cesium.Transforms.eastNorthUpToFixedFrame(
                    Cesium.Cartesian3.fromDegrees(107.20, 30.55)),
                    new Cesium.Cartesian3(0.0, 0.0, 150000.0),
                    new Cesium.Matrix4()
                ),
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
                }
            });
            //上方的实例
            var orangeEllipsoidInstance = new Cesium.GeometryInstance({
                geometry: ellipsoidGeometry,
                modelMatrix: Cesium.Matrix4.multiplyByTranslation(
                    Cesium.Transforms.eastNorthUpToFixedFrame(
                    Cesium.Cartesian3.fromDegrees(107.20, 30.55)),
                    new Cesium.Cartesian3(0.0, 0.0, 450000.0),
                    new Cesium.Matrix4()
                ),
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE)
                }
            });
            viewer.scene.primitives.add(new Cesium.Primitive({
                geometryInstances: [
                    cyanEllipsoidInstance, orangeEllipsoidInstance
                ],
                appearance: new Cesium.PerInstanceColorAppearance({
                    translucent: false,
                    closed: true
                })
            }));
    4更新单个GeometryInstance的属性
      var circleInstance = new Cesium.GeometryInstance({
                geometry: new Cesium.CircleGeometry({
                    center: Cesium.Cartesian3.fromDegrees(107.20, 30.55),
                    radius: 250000.0,
                    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
                }),
                attributes: {
                    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(1.0, 0.0, 0.0, 0.5)),
                    show: new Cesium.ShowGeometryInstanceAttribute(true) //显示或者隐藏
                },
                id: 'circle'
            });
            var primitive = new Cesium.Primitive({
                geometryInstances: circleInstance,
                appearance: new Cesium.PerInstanceColorAppearance({
                    translucent: false,
                    closed: true
                })
            });
            viewer.scene.primitives.add(primitive);
            //定期修改颜色
            setInterval(function () {
                //获取某个实例的属性集
                var attributes = primitive.getGeometryInstanceAttributes('circle');
                attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
                Cesium.Color.fromRandom({
                    alpha: 1.0
                }));
    5场景中primitive管理
    场景通过viewer.scene.primitives属性来管理添加的primitive对象,primitives是PrimitiveCollection类型,查看帮助文档:
    Cesium学习笔记16--绘制对象-Primitive管理
    提供一下接口来管理场景中primitive对象:
    add(primitive) → Object
    contains(primitive) → Boolean
    destroy() → undefined
    get(index) → Object
    isDestroyed() → Boolean
    lower(primitive)
    lowerToBottom(primitive)
    raise(primitive)
    raiseToTop(primitive)
    remove(primitive) → Boolean
    removeAll()
    

    演示

    这里对entity几个图形做了一下简单封装供使用

    /**
     * entity 添加实体
     * 
     * @type 类型
     * @param entity参数
     * 调用方法
     * var entity = new _cesiumTool({viewer:this.viewer}).createEntity({handleType:"cylinder",p:{length: Math.max.apply(null,height),slices:4}});
     */
    _cesiumTool.prototype.createEntity =  function(param){
        try {
         var t = this,viewer = t.viewer,p = param.p,entity = null;
         if(param === null) return;
         
         switch(param.handleType){
             case "cylinder":{ 
                 var cylinderEntity = viewer.entities.add({
                     cylinder: {
                         HeightReference: Cesium.HeightReference.CLAMP_TO_GROUND, //表示相对于地形的位置。
                         length: p.length == null?600000:p.length,     //长度
                         topRadius: p.topRadius == null?0:p.topRadius,    //顶点半径
                         bottomRadius: p.bottomRadius == null?600000 / 4 :p.bottomRadius,  //底部半径
                         material: p.material == null?Cesium.Color.RED.withAlpha(.4) :p.material,  //填充材料
                         outline: p.outline == null? !0:p.outline,            //轮廓
                         numberOfVerticalLines: p.numberOfVerticalLines == null?0:p.numberOfVerticalLines, //垂直线数
                         slices:p.slices == null?128:p.slices,         //周边数
                         outlineColor: p.outlineColor == null?Cesium.Color.RED.withAlpha(.8):p.outlineColor  //颜色轮廓
                     }
                 });
                 entity = cylinderEntity;
                 break; 
             }
             case "box":{
                 var boxEntity = viewer.entities.add({
                     name: 'Blue box',
                     position: Cesium.Cartesian3.fromDegrees(homePOsition[0], homePOsition[1], 0),
                     box: {
                         dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
                         material: Cesium.Color.BLUE
                     }
                 });
                 entity = boxEntity;
                 break; 
             }
             case "circle":{
                 var circleEntity = viewer.entities.add({
                     position: Cesium.Cartesian3.fromDegrees(111.0, 40.0, 150000.0),
                     name: 'Green circle at height',
                     ellipse: {
                         semiMinorAxis: 300000.0,
                         semiMajorAxis: 300000.0,
                         height: 200000.0,
                         material: Cesium.Color.GREEN
                     }
                 });
                 entity = circleEntity;
                 break; 
             }
             case "ellipse":{
                 var ellipseEntity = viewer.entities.add({
                     position: Cesium.Cartesian3.fromDegrees(103.0, 40.0),
                     name: 'Red ellipse on surface with outline',
                     ellipse: {
                         semiMinorAxis: 250000.0,
                         semiMajorAxis: 400000.0,
                         material: Cesium.Color.RED.withAlpha(0.5),
                         outline: true,
                         outlineColor: Cesium.Color.RED
                     }
                 });
                 entity = ellipseEntity;
                 break; 
             }
             case "corridor":{
                 var corridorEntity = viewer.entities.add({
                     name: 'Red corridor on surface with rounded corners and outline',
                     corridor: {
                         positions: Cesium.Cartesian3.fromDegreesArray([
                         100.0, 40.0,
                         105.0, 40.0,
                         105.0, 35.0
                         ]),
                          200000.0,
                         material: Cesium.Color.RED.withAlpha(0.5),
                         outline: true,
                         outlineColor: Cesium.Color.RED
                     }
                 });
                 entity = corridorEntity;
                 break; 
             }
             case "polygon":{
                 var polygonEntity = viewer.entities.add({
                     name: 'Red polygon on surface',
                     polygon: {
                         hierarchy: Cesium.Cartesian3.fromDegreesArray([115.0, 37.0,
                         115.0, 32.0,
                         107.0, 33.0,
                         102.0, 31.0,
                         102.0, 35.0]),
                         material: Cesium.Color.RED
                     }
                 });
                 entity = polygonEntity;
                 break; 
             }
             case "polyline":{
                 var polylineEntity = viewer.entities.add({
                     name: 'Red line on the surface',
                     polyline: {
                         positions: Cesium.Cartesian3.fromDegreesArray([75, 35,
                         125, 35]),
                          5,
                         material: Cesium.Color.RED
                     }
                 });
                 entity = polylineEntity;
                 break; 
             }
             default :{}   
         }
        } catch (error) {
            console.log("error mannager:" + error)
        }
        
        return entity;
     }
    

    本文转自 https://blog.csdn.net/weixin_40902527/article/details/95785501?spm=1001.2014.3001.5502,如有侵权,请联系删除。

  • 相关阅读:
    iOS实时查看App运行日志
    Jmeter-使用Ultimate Thread Group插件来设置负载场景
    Flask使用Flask-SQLAlchemy操作MySQL数据库
    使用requests库提交multipart/form-data 格式的请求
    spark 性能调优(一) 性能调优的本质、spark资源使用原理、调优要点分析
    一、spark错误
    sqoop 补充
    Hbase—— rowkey 过滤器(rowfilter)
    spark 调优——基础篇
    scala 的安装 与 IDEA安装使用
  • 原文地址:https://www.cnblogs.com/hustshu/p/16155380.html
Copyright © 2020-2023  润新知