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
]),
width: 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]),
width: 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,如有侵权,请联系删除。

原创文章,作者:bd101bd101,如若转载,请注明出处:https://blog.ytso.com/245293.html

(0)
上一篇 2022年4月18日
下一篇 2022年4月18日

相关推荐

发表回复

登录后才能评论