cesium entity 和primitive 繪製物件 primitive合併 但是有不同的外觀
阿新 • • 發佈:2022-04-17
Entity 和primitive 對比
- entity偏向資料,primitive偏向圖形.primitive更底層
- 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() }));
檢視瀏覽器記憶體消耗情況:
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,如有侵權,請聯絡刪除。