前面介紹了Cesium如何加載影像數據、地形數據、以及矢量數據,但是作為一個完整的三維系統,僅僅包括這些數據還是遠遠不夠的。當然,還需要一些其他數據,比如空間可視化數據、三維數據數據等,今天我們先從空間數據的可視化說起,后面會有專門的章節介紹三維數據方面的加載。
Cesium在空間數據可視化方面提供了兩種類型的API,一種是面向圖形開發人員的低級(原始)API,通過Primitive類實現,對于那些對計算機圖形學知識很了解的同學可以采用Primitive API,后面章節會有詳細介紹;另一種是用于數據驅動的高級(實體)API,通過Entity類實現,相對于Primitive API,Entity API實現起來更簡單一些,特別建議初學者使用。Entity API 實際上是對Primitive API的二次封裝,底層調用的仍然是Primitive API,目的就是為我們提供靈活的、易學、易用的高性能可視化界面。本章節內容主要介紹后者Entity API,Primitive API放在后面的高級篇里講解。
Entity支持的圖形類型
通過在Cesium API文檔中查看Entity類的構造函數,我們發現Entity支持的圖形類型都是以Graphics結尾的,一共有17種類型。如下圖所示,列出了Entity支持的圖形類型以及對應的js類。
下面,簡單介紹一下每一種類型的Graphic添加方式。
1)billboard 廣告牌
var entity = viewer.entities.add({
// id: "",
name: "billboard",
// show: true,
// description: "",
// orientation: "",
position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
billboard: {
show: true, // default
image: "./images/Cesium_Logo_overlay.png", // default: undefined
scale: 2.0, // default: 1.0
//像素偏移 type: Cartesian2 default:Cartesian2.ZERO
pixelOffset: new Cesium.Cartesian2(0, -50),
//眼睛偏移 type: Cartesian3 default:Cartesian3.ZERO
eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0),
// 水平對齊方式 type: HorizontalOrigin default:HorizontalOrigin.CENTER
// CENTER 原點在對象的水平中心;LEFT 原點在對象的左側;RIGHT 原點在對象的右側
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
// 垂直對齊方式 type: VerticalOrigin default:VerticalOrigin.CENTER
// CENTER 原點位于 BASELINE 和 TOP 之間的垂直中心;BOTTOM 原點在對象的底部;
// BASELINE 如果對象包含文本,則原點位于文本的基線,否則原點位于對象的底部;TOP 原點在對象的頂部
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // default: CENTER 垂直對齊位置 參考Cesium.VerticalOrigin
// 獲取或設置此廣告牌的高度參考 type: HeightReference default:HeightReference.NONE
// NONE 位置絕對;CLAMP_TO_GROUND 位置固定在地形上;RELATIVE_TO_GROUND 位置高度是指地形上方的高度
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
// 顏色 type: Color default:Color.WHITE
color: Cesium.Color.LIME,
// 獲取或設置以弧度為單位的旋轉角度 type: number default:0
rotation: Cesium.Math.PI_OVER_FOUR,
// 獲取或設置世界空間中的對齊軸 type:Cartesian3 default:Cartesian3.ZERO
alignedAxis: Cesium.Cartesian3.ZERO,
width: 100, // default: undefined
height: 25, // default: undefined
// 根據廣告牌與相機的距離獲取或設置廣告牌的近和遠縮放屬性 type:NearFarScalar
scaleByDistance: new Cesium.NearFarScalar(1.0e3, 2.0, 2.0e3, 1.0),
// 根據廣告牌到相機的距離,獲取或設置廣告牌的近和遠半透明屬性 type:NearFarScalar
translucencyByDistance: new Cesium.NearFarScalar(
1.0e3,
1.0,
1.5e6,
0.5
),
// 根據廣告牌與攝像頭的距離,獲取或設置廣告牌的近像素偏移量和遠像素偏移量縮放屬性 type:NearFarScalar
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(
1.0e3,
1.0,
1.5e6,
0.0
),
// 設置1000米和2000米之間可見 type:DistanceDisplayCondition
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
// 獲取或設置與相機的距離,在深度處禁用深度測試,例如,以防止剪切地形。
// 設置為零時,將始終應用深度測試。設置為Number.POSITIVE_INFINITY時,永遠不會應用深度測試。
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
});
2)box 盒子
var entity = viewer.entities.add({
name: "box",
position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),
box: {
show: true,
dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0), // Cartesian3類型,用于指定框的長度,寬度和高度
// 指定距實體位置的高度是相對于什么的高度。 default: HeightReference.NONE
// NONE 位置絕對;CLAMP_TO_GROUND 位置固定在地形上;RELATIVE_TO_GROUND 位置高度是指地形上方的高度。
heightReference: Cesium.HeightReference.NONE,
fill: true,
// MaterialProperty|Color default:Color.WHITE
material: Cesium.Color.RED.withAlpha(0.5),
outline: true,
// type:Property|Color default:Color.BLACK
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1.0,
// type:ShadowMode default:ShadowMode.DISABLED
// DISABLED 對象不投射或接收陰影;ENABLED 對象投射并接收陰影;CAST_ONLY 對象僅投射陰影;RECEIVE_ONLY 該對象僅接收陰影。
shadows: Cesium.ShadowMode.DISABLED,
// type:DistanceDisplayCondition
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
},
});
3)corridor 走廊
var entity = viewer.entities.add({
name: "corridor",
corridor: {
// show: true,
// 指定定義走廊中心線的 Cartesian3 位置的數組 type: Cartesian3
positions: Cesium.Cartesian3.fromDegreesArray([
-80.0,
40.0,
-85.0,
40.0,
-85.0,
35.0,
]),
width: 200000.0,
height: 200000.0,
heightReference: Cesium.HeightReference.NONE,
extrudedHeight: 100000.0,
extrudedHeightReference: Cesium.HeightReference.NONE,
// 拐角的樣式 type:CornerType default:CornerType.ROUNDED
// ROUNDED 角有光滑的邊緣;MITERED 拐角點是相鄰邊的交點;BEVELED 角被修剪
cornerType: Cesium.CornerType.ROUNDED,
granularity: Cesium.Math.RADIANS_PER_DEGREE, // 每個緯度和經度之間的距離
fill: true,
// 材質 type:MaterialProperty|Color default:Color.WHITE
material: Cesium.Color.BLUE.withAlpha(0.5),
outline: true, // height or extrudedHeight must be set for outlines to display
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1.0,
shadows: Cesium.ShadowMode.DISABLED,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
// 走廊在地面上時將對地形,3D tiles還是對兩者進行分類 type:ClassificationType default:ClassificationType.BOTH
// TERRAIN 將僅對地形進行分類;CESIUM_3D_TILE 將僅對3D Tiles進行分類;BOTH 將同時對Terrain和3D Tiles進行分類。
classificationType: Cesium.ClassificationType.BOTH,
},
});
4)cylinder 圓柱、圓錐
var entity = viewer.entities.add({
name: "cylinder",
position: Cesium.Cartesian3.fromDegrees(-105.0, 40.0, 200000.0),
cylinder: {
// show: true,
length: 400000.0, // 圓柱體長度
topRadius: 200000.0, // 圓柱體頂部半徑
bottomRadius: 200000.0, // 圓柱體底部半徑
heightReference: Cesium.HeightReference.NONE,
fill: true,
material: Cesium.Color.GREEN.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.DARK_GREEN,
outlineWidth: 1.0,
numberOfVerticalLines: 16, // 沿輪廓的周長繪制的垂直線的數量
shadows: Cesium.ShadowMode.DISABLED,
slices: 128, // 圓柱周圍的邊緣數量
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
},
});
5)ellipse 橢圓或拉伸的橢圓
var entity = viewer.entities.add({
name: "Circles and Ellipses",
position: Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 100000.0),
ellipse: {
show: true,
semiMajorAxis: 300000.0, // 長半軸距離
semiMinorAxis: 150000.0, // 短半軸距離
height: 20000.0,
heightReference: Cesium.HeightReference.NONE,
extrudedHeight: 20000.0,
extrudedHeightReference: Cesium.HeightReference.NONE,
// rotation: Cesium.Math.toRadians(45), // 從北方逆時針旋轉
stRotation: 0.0, // 紋理從北方逆時針旋轉
granularity: Cesium.Math.RADIANS_PER_DEGREE, // 橢圓上各點之間的角距離
material: Cesium.Color.BLUE.withAlpha(0.5),
fill: true,
outline: true,
outlineColor: Cesium.Color.DARK_GREEN,
outlineWidth: 1.0,
numberOfVerticalLines: 16, // 沿輪廓的周長繪制的垂直線的數量
shadows: Cesium.ShadowMode.DISABLED,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
// 在地面上時將對地形,3D tiles還是對兩者進行分類 type:ClassificationType default:ClassificationType.BOTH
// TERRAIN 將僅對地形進行分類;CESIUM_3D_TILE 將僅對3D瓷磚進行分類;BOTH 將同時對Terrain和3D Tile進行分類。
classificationType: Cesium.ClassificationType.BOTH,
},
});
6)ellipsoid 橢球體
var entity = viewer.entities.add({
name: "Spheres and Ellipsoids",
position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),
ellipsoid: {
show: true,
radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0), // 橢球半徑
// innerRadii: new Cesium.Cartesian3(0.0, 0.0, 0.0), // 橢球內部半徑
minimumClock: 0.0, // 最小時鐘角度
maximumClock: 2 * Math.PI, // 最大時鐘角度
minimumCone: 0.0, // 最小圓錐角
maximumCone: Math.PI, // 最大圓錐角
heightReference: Cesium.HeightReference.NONE,
fill: true,
material: Cesium.Color.BLUE.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.YELLOW,
outlineWidth: 1.0,
stackPartitions: 64, // 延緯度線切割的次數
slicePartitions: 64, // 延經度線切割的次數
subdivisions: 128, // 每個輪廓環的樣本數,確定曲率的粒度
shadows: Cesium.ShadowMode.DISABLED,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
},
});
7)label 標簽
var entity = viewer.entities.add({
name: "label",
position: Cesium.Cartesian3.fromDegrees(
-75.1641667,
39.9522222,
300000.0
),
label: {
show: true,
text: "label標簽",
font: "24px Helvetica",
// FILL 填充;OUTLINE 只顯示邊框;FILL_AND_OUTLINE 既有填充又有邊框
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
scale: 1.0,
showBackground: true,
backgroundColor: Cesium.Color.BLUE,
backgroundPadding: new Cartesian2(7, 5),
pixelOffset: Cartesian2.ZERO,
eyeOffset: Cartesian3.ZERO,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
heightReference: Cesium.HeightReference.NONE,
fillColor: Cesium.Color.SKYBLUE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
translucencyByDistance: new Cesium.NearFarScalar(
1.0e3,
1.0,
1.5e6,
0.5
),
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(
1.0e3,
1.0,
1.5e6,
0.0
),
scaleByDistance: new Cesium.NearFarScalar(1.0e3, 2.0, 2.0e3, 1.0),
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
});
8)model 模型
var position = Cesium.Cartesian3.fromDegrees(
-123.0744619,
44.0503706,
5000.0
);
var heading = Cesium.Math.toRadians(135);
var pitch = 0;
var roll = 0;
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);
var url = "./data/models/CesiumAir/Cesium_Air.glb";
var entity = viewer.entities.add({
name: "model",
position: position,
orientation: orientation,
model: {
show: true,
uri: url,
scale: 1.0,
minimumPixelSize: 128, // 模型的最小最小像素大小,而不考慮縮放
maximumScale: 20000, // 模型的最大比例尺大小。 minimumPixelSize的上限
incrementallyLoadTextures: true, // 確定在加載模型后紋理是否可以繼續流入
runAnimations: true, // 是否應啟動模型中指定的glTF動畫
clampAnimations: true, // glTF動畫是否應在沒有關鍵幀的持續時間內保持最后一個姿勢
shadows: Cesium.ShadowMode.DISABLED,
heightReference: Cesium.HeightReference.NONE,
silhouetteColor: Cesium.Color.RED, // 輪廓的顏色
silhouetteSize: 0.0, // 輪廓的寬度
color: Cesium.Color.WHITE, // 模型的顏色
// 目標顏色和圖元的源顏色之間混合的不同模式
// HIGHLIGHT 將源顏色乘以目標顏色;REPLACE 將源顏色替換為目標顏色;MIX 將源顏色和目標顏色混合在一起
colorBlendMode: Cesium.ColorBlendMode.HIGHLIGHT,
// 用于指定 colorBlendMode 為 MIX 時的顏色強度。值0.0會產生模型的著色,而值1.0會導致純色,介于兩者之間的任何值都會導致兩者混合
colorBlendAmount: 0.5,
imageBasedLightingFactor: new Cesium.Cartesian2(1.0, 1.0), // 指定基于漫反射和鏡面反射的圖像照明的貢獻
lightColor: undefined, // 為模型著色時指定淺色的屬性。如果 undefined ,則使用場景的淺色。
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
},
});
9)tileset 3D Tiles瓦片集
var tileset = viewer.entities.add({
name: "3D Tiles",
position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
tileset: {
show: true,
uri: new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0.0),
},
});
10)path 路徑
var entityPath = viewer.entities.add({
position: pathPosition,
name: "path",
path: {
show: true,
leadTime: 0,
trailTime: 60,
width: 10,
resolution: 1,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.3,
taperPower: 0.3,
color: Cesium.Color.PALEGOLDENROD,
}),
},
});
11)plane 平面
var bluePlane = viewer.entities.add({
name: "Blue plane",
position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
plane: {
show: true,
// 用于指定平面的法線和距離
plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0.0),
dimensions: new Cesium.Cartesian2(400000.0, 300000.0), // 指定平面的寬度和高度
fill: true,
material: Cesium.Color.BLUE,
outline: false,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1.0,
shadows: Cesium.ShadowMode.DISABLED,
// type:DistanceDisplayCondition
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
},
});
12)point 點
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
point: {
show: true,
pixelSize: 10, // 像素大小
heightReference: Cesium.HeightReference.NONE,
color: Cesium.Color.YELLOW,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 0,
scaleByDistance: new Cesium.NearFarScalar(1.0e3, 10.0, 2.0e3, 1.0),
translucencyByDistance: new Cesium.NearFarScalar(
1.0e3,
1.0,
1.5e6,
0.5
),
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
// 獲取或設置與相機的距離,在深度處禁用深度測試,例如,以防止剪切地形。
// 設置為零時,將始終應用深度測試。設置為Number.POSITIVE_INFINITY時,永遠不會應用深度測試。
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
});
13)polygon 多邊形
var redPolygon = viewer.entities.add({
name: "Red polygon on surface",
polygon: {
show: true,
// 指定PolygonHierarchy
hierarchy: Cesium.Cartesian3.fromDegreesArray([
-115.0,
37.0,
-115.0,
32.0,
-107.0,
33.0,
-102.0,
31.0,
-102.0,
35.0,
]),
height: 0, // 多邊形相對于橢球面的高度
heightReference: Cesium.HeightReference.NONE,
// extrudedHeight: 0, // 多邊形的凸出面相對于橢球面的高度
// extrudedHeightReference: Cesium.HeightReference.NONE,
stRotation: 0.0, // 多邊形紋理從北方逆時針旋轉
granularity: Cesium.Math.RADIANS_PER_DEGREE, // 每個緯度和經度點之間的角距離
fill: true,
material: Cesium.Color.RED,
outline: false,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1.0,
perPositionHeight: false, // 是否使用每個位置的高度
closeTop: true, // 如果為false,則將擠出的多邊形頂部留空
closeBottom: true, // 如果為false,則將擠出的多邊形的底部保留為開放狀態
// 多邊形邊緣必須遵循的線型 type:ArcType 定義連接頂點應采用的路徑。
// NONE 與橢圓表面不符的直線;GEODESIC 遵循測地路徑;RHUMB 遵循大黃蜂或惡魔般的道路。
arcType: Cesium.ArcType.GEODESIC,
shadows: Cesium.ShadowMode.DISABLED,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
// 在地面上時將對地形,3D tiles還是對兩者進行分類 type:ClassificationType default:ClassificationType.BOTH
// TERRAIN 將僅對地形進行分類;CESIUM_3D_TILE 將僅對3D Tiles進行分類;BOTH 將同時對Terrain和3D Tiles進行分類。
classificationType: Cesium.ClassificationType.BOTH,
// 指定用于訂購地面幾何形狀的z索引。僅在多邊形為常數且未指定高度或拉伸高度的情況下才有效 type:ConstantProperty
zIndex: 0,
},
});
14)polyline 多線段
var redLine = viewer.entities.add({
name: "Red line on terrain",
polyline: {
show: true,
// 定義線條的 Cartesian3 位置的數組
positions: Cesium.Cartesian3.fromDegreesArray([-75, 35, -125, 35]),
width: 5,
// 如果arcType不是ArcType.NONE,則指定每個緯度和經度之間的角距離
// granularity: Cesium.Math.RADIANS_PER_DEGREE,
material: Cesium.Color.RED,
// 線低于地形時用于繪制折線的材質
// depthFailMaterial: Cesium.Color.WHITE,
// 折線段必須遵循的線型
// arcType: Cesium.ArcType.GEODESIC,
clampToGround: true, // 是否貼地
shadows: Cesium.ShadowMode.DISABLED, // 折線是投射還是接收光源的陰影
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
// 在地面上時將對地形,3D tiles還是對兩者進行分類 type:ClassificationType default:ClassificationType.BOTH
// TERRAIN 將僅對地形進行分類;CESIUM_3D_TILE 將僅對3D Tiles進行分類;BOTH 將同時對Terrain和3D Tiles進行分類。
classificationType: Cesium.ClassificationType.BOTH,
// 指定用于訂購地面幾何形狀的z索引。僅在多邊形為常數且未指定高度或拉伸高度的情況下才有效 type:ConstantProperty
// zIndex: 0,
},
});
15)polylineVolume 多線段柱體
function computeCircle(radius) {
var positions = [];
for (var i = 0; i < 360; i++) {
var radians = Cesium.Math.toRadians(i);
positions.push(
new Cesium.Cartesian2(
radius * Math.cos(radians),
radius * Math.sin(radians)
)
);
}
return positions;
}
var redTube = viewer.entities.add({
name: "Red tube with rounded corners",
polylineVolume: {
show: true,
// 定義線帶的 Cartesian3 位置的數組
positions: Cesium.Cartesian3.fromDegreesArray([
-85.0,
32.0,
-85.0,
36.0,
-89.0,
36.0,
]),
// 指定 Cartesian2 位置的數組,這些位置定義了要拉伸的形狀
shape: computeCircle(60000.0),
// 拐角的樣式 type:CornerType
// ROUNDED 拐角有光滑的邊緣;MITERED 拐角點是相鄰邊的交點;BEVELED 拐角被修剪。
cornerType: Cesium.CornerType.ROUNDED,
// 如果arcType不是ArcType.NONE,則指定每個緯度和經度之間的角距離
// granularity: Cesium.Math.RADIANS_PER_DEGREE,
fill: true,
material: Cesium.Color.RED,
outline: false,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1.0,
shadows: Cesium.ShadowMode.DISABLED, // 體積是投射還是接收光源的陰影
// type:DistanceDisplayCondition
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
},
});
16)rectangle 矩形
var redRectangle = viewer.entities.add({
name: "Red translucent rectangle",
rectangle: {
show: true,
coordinates: Cesium.Rectangle.fromDegrees(-110.0, 20.0, -80.0, 25.0),
// height: 0, // 矩形相對于橢球面的高度
// heightReference: Cesium.HeightReference.NONE,
// extrudedHeight: 0, // 矩形的拉伸面相對于橢球面的高度
// extrudedHeightReference: Cesium.HeightReference.NONE,
rotation: 0.0, // 矩形從北方向順時針方向的旋轉
stRotation: 0.0, // 矩形紋理從北方逆時針旋轉
granularity: Cesium.Math.RADIANS_PER_DEGREE, // 指定矩形上各點之間的角度距離
fill: true,
material: Cesium.Color.RED.withAlpha(0.5),
outline: false,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1.0,
shadows: Cesium.ShadowMode.DISABLED,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
// 在地面上時將對地形,3D tiles還是對兩者進行分類 type:ClassificationType default:ClassificationType.BOTH
// TERRAIN 將僅對地形進行分類;CESIUM_3D_TILE 將僅對3D Tiles進行分類;BOTH 將同時對Terrain和3D Tiles進行分類。
classificationType: Cesium.ClassificationType.BOTH,
// 指定用于訂購地面幾何形狀的z索引。僅在多邊形為常數且未指定高度或拉伸高度的情況下才有效 type:ConstantProperty
zIndex: 0,
},
});
17)wall 墻
var redWall = viewer.entities.add({
name: "Red wall at height",
wall: {
show: true,
positions: Cesium.Cartesian3.fromDegreesArrayHeights([
-115.0,
44.0,
200000.0,
-90.0,
44.0,
200000.0,
]),
// 用于墻底而不是地球表面的高度數組
minimumHeights: [100000.0, 100000.0],
// 用于墻頂的高度數組,而不是每個位置的高度
// maximumHeights: [],
granularity: Cesium.Math.RADIANS_PER_DEGREE, // 指定矩形上各點之間的角度距離
fill: true,
material: Cesium.Color.RED,
outline: false,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1.0,
shadows: Cesium.ShadowMode.DISABLED,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
// 1.0e3,
// 2.0e3
// ),
},
});
Entity 聚合
同時,針對Billboard、Label、Point,Cesium 提供了 EntityCluster 類用于實現聚合效果,但必須結合 PinBuilder 類實現。下面為實現聚合效果的核心代碼:
var options = {
camera: viewer.scene.camera,
canvas: viewer.scene.canvas,
};
var dataSourcePromise = viewer.dataSources.add(
Cesium.KmlDataSource.load("./data/kml/facilities/facilities.kml", options)
);
dataSourcePromise.then(function (dataSource) {
var pixelRange = 15;
var minimumClusterSize = 3;
var enabled = true;
dataSource.clustering.enabled = enabled;
dataSource.clustering.pixelRange = pixelRange; // 擴展屏幕空間邊界框的像素范圍
dataSource.clustering.minimumClusterSize = minimumClusterSize; // 可以聚合的最小屏幕空間對象
var removeListener;
var pinBuilder = new Cesium.PinBuilder();
var pin50 = pinBuilder.fromText("50+", Cesium.Color.RED, 48).toDataURL();
var pin40 = pinBuilder
.fromText("40+", Cesium.Color.ORANGE, 48)
.toDataURL();
var pin30 = pinBuilder
.fromText("30+", Cesium.Color.YELLOW, 48)
.toDataURL();
var pin20 = pinBuilder
.fromText("20+", Cesium.Color.GREEN, 48)
.toDataURL();
var pin10 = pinBuilder.fromText("10+", Cesium.Color.BLUE, 48).toDataURL();
var singleDigitPins = new Array(8);
for (var i = 0; i < singleDigitPins.length; ++i) {
singleDigitPins[i] = pinBuilder
.fromText("" + (i + 2), Cesium.Color.VIOLET, 48)
.toDataURL();
}
function customStyle() {
if (Cesium.defined(removeListener)) {
removeListener();
removeListener = undefined;
} else {
removeListener = dataSource.clustering.clusterEvent.addEventListener(
function (clusteredEntities, cluster) {
cluster.label.show = false;
cluster.billboard.show = true;
cluster.billboard.id = cluster.label.id;
cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
if (clusteredEntities.length >= 50) {
cluster.billboard.image = pin50;
} else if (clusteredEntities.length >= 40) {
cluster.billboard.image = pin40;
} else if (clusteredEntities.length >= 30) {
cluster.billboard.image = pin30;
} else if (clusteredEntities.length >= 20) {
cluster.billboard.image = pin20;
} else if (clusteredEntities.length >= 10) {
cluster.billboard.image = pin10;
} else {
cluster.billboard.image =
singleDigitPins[clusteredEntities.length - 2];
}
}
);
}
// force a re-cluster with the new styling
var pixelRange = dataSource.clustering.pixelRange;
dataSource.clustering.pixelRange = 0;
dataSource.clustering.pixelRange = pixelRange;
}
// start with custom style
customStyle();
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
var pickedLabel = viewer.scene.pick(movement.position);
if (Cesium.defined(pickedLabel)) {
var ids = pickedLabel.id;
if (Array.isArray(ids)) {
for (var i = 0; i < ids.length; ++i) {
ids[i].billboard.color = Cesium.Color.RED;
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
});
Entity 管理
上面介紹了Entity的圖形類型,有這么多類型的實體,Cesium是如何管理這些實體對象的呢,這就需要我們從初始化Viewer對象開始說起了。當我們初始化Viewer類之后,會得到一個實例化對象viewer,這個viewer會包含一個屬性 entities ,它的類型是 EntityCollection ,也就是 Entity 的集合,它包括了 EntityCollection 類里面的所有屬性和方法。所以 Cesium 管理 Entity 本質上是通過 EntityCollection 類進行管理的,比如add(添加Entity)、contains(是否存在某個Entity)、getById(通過ID獲取Entity)、remove(移除某個Entity)、removeAll(移除所有的Entity)、removeById(通過ID移除Entity)方法等。
var point = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-105.0, 41, 50010),
point: {
show: true,
pixelSize: 10, // 像素大小
},
});
var entity = viewer.entities.getById("entity_1");
viewer.entities.remove(entity);
// viewer.entities.removeById("entity_1");
// viewer.entities.removeAll();
Entity 拾取
在三維場景種,很常見的一種交互方式,就是鼠標點擊三維場景種某一個幾何圖形,查看該圖形的包含的屬性信息,并顯示在對應的信息窗體中。單擊事件通過 ScreenSpaceEventHandler 類注冊,拾取到的信息可通過以下兩種方式獲取。
- scene.pick:獲取窗體坐標處最頂部的實體;
- scene.drillPick:窗體坐標處的實體列表。
// 添加拾取事件
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(function (movement) {
var pickedEntity = pickEntity(viewer, movement.position);
console.log(pickedEntity);
var pickedEntities = drillPickEntities(viewer, movement.position);
console.log(pickedEntities);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
function pickEntity(viewer, windowPosition) {
var picked = viewer.scene.pick(windowPosition);
if (Cesium.defined(picked)) {
var id = Cesium.defaultValue(picked.id, picked.primitive.id);
if (id instanceof Cesium.Entity) {
return id;
}
}
return undefined;
}
function drillPickEntities(viewer, windowPosition) {
var i;
var entity;
var picked;
var pickedPrimitives = viewer.scene.drillPick(windowPosition);
var length = pickedPrimitives.length;
var result = [];
var hash = {};
for (i = 0; i < length; i++) {
picked = pickedPrimitives[i];
entity = Cesium.defaultValue(picked.id, picked.primitive.id);
if (
entity instanceof Cesium.Entity &&
!Cesium.defined(hash[entity.id])
) {
result.push(entity);
hash[entity.id] = true;
}
}
return result;
}
Entity 固定
在實際的應用系統中,會有這樣的需求,要求畫的實體附著在地形表面、或三維建筑表面(比如視頻融合),這時候就需要設置xxGraphics的相關屬性了,可通過 heightReference 或 classificationType 這兩個屬性去控制。屬性值描述如下:
heightReference屬性值:
NONE:位置絕對(默認值);
CLAMP_TO_GROUND:位置固定在地形上;
RELATIVE_TO_GROUND:位置高度是指地形上方的高度classificationType屬性值:
TERRAIN:將僅對地形進行分類;
CESIUM_3D_TILE:將僅對3D Tiles進行分類;
BOTH :將同時對Terrain和3D Tiles進行分類。
其中corridor 、 ellipse 、 polygon 、 polyline 、 rectangle 可通過設置 classificationType 屬性值顯示僅貼地、僅貼建筑或者兩者都貼的效果,billboard 、 box 、 corridor 、 cylinder 、 ellipse 、 ellipsoid 、 label 、 model 、 point 、 polygon 、 tectangle通過設置 heightReference 屬性值為 CLAMP_TO_GROUND 顯示貼地效果。這里需要注意的是,如果是polyline必須設置 clampToGround 屬性為 true 。
// set the heightReference to CLAMP_TO_GROUND
// billboard box corridor cylinder ellipse ellipsoid label model point polygon tectangle
// 其中corridor ellipse polygon retangle會自動貼地
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915),
billboard: {
image: "./images/facility.gif",
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
point: {
color: Cesium.Color.SKYBLUE,
pixelSize: 10,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
label: {
text: "Clamped to ground",
font: "14pt sans-serif",
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BASELINE,
fillColor: Cesium.Color.BLACK,
showBackground: true,
backgroundColor: new Cesium.Color(1, 1, 1, 0.7),
backgroundPadding: new Cesium.Cartesian2(8, 4),
disableDepthTestDistance: Number.POSITIVE_INFINITY, // draws the label in front of terrain
},
});
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915),
model: {
uri: "./data/models/CesiumMan/Cesium_Man.glb",
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
minimumPixelSize: 128,
maximumScale: 100,
},
});
// corridors、ellipse、 polygons and rectangles will be clamped automatically
// if they are filled with a constant color and has no height or extruded height.
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-122.195, 46.1915),
corridor: {
positions: Cesium.Cartesian3.fromDegreesArray([
-122.19,
46.1914,
-122.2,
46.1924,
-122.21,
46.193,
]),
width: 500.0,
material: Cesium.Color.GREEN.withAlpha(0.5),
},
ellipse: {
semiMajorAxis: 300.0, // 長半軸距離
semiMinorAxis: 150.0, // 短半軸距離
// heightReference: Cesium.HeightReference.NONE,
material: Cesium.Color.BLUE.withAlpha(0.5),
// material: "./images/Cesium_Logo_Color.jpg",
// classificationType: Cesium.ClassificationType.BOTH,
},
polygon: {
hierarchy: {
positions: [
new Cesium.Cartesian3(
-2358138.847340281,
-3744072.459541374,
4581158.5714175375
),
new Cesium.Cartesian3(
-2357231.4925370603,
-3745103.7886602185,
4580702.9757762635
),
new Cesium.Cartesian3(
-2355912.902205431,
-3744249.029778454,
4582402.154378103
),
new Cesium.Cartesian3(
-2357208.0209552636,
-3743553.4420488174,
4581961.863286629
),
],
},
// material: Cesium.Color.BLUE.withAlpha(0.5),
material: "./images/Cesium_Logo_Color.jpg",
},
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(-122.2, 46.2, -122.1, 46.3),
material: Cesium.Color.RED.withAlpha(0.5),
},
});
// set the classificationType to TERRAIN
// corridor ellipse polygon polyline rectangle
// 其中polyline 必須 設置clampToGround = true
viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
-122.1968,
46.1915,
-122.1968,
46.2015,
-122.1968,
46.2015,
]),
clampToGround: true,
width: 5,
material: Cesium.Color.ORANGE,
depthFailMaterial: Cesium.Color.RED,
// classificationType: Cesium.ClassificationType.BOTH,
},
});
var polygon = viewer.entities.add({
polygon: {
hierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromRadiansArray([
-1.3194369277314022,
0.6988062530900625,
-1.3193955980204217,
0.6988091578771254,
-1.3193931220959367,
0.698743632490865,
-1.3194358224045408,
0.6987471965556998,
])
),
// NONE 位置絕對;CLAMP_TO_GROUND 位置固定在地形上;RELATIVE_TO_GROUND 位置高度是指地形上方的高度
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
// material: Cesium.Color.RED.withAlpha(0.5),
material: "./images/Cesium_Logo_Color.jpg",
// TERRAIN 將僅對地形進行分類;CESIUM_3D_TILE 將僅對3D Tiles進行分類;BOTH 將同時對Terrain和3D Tiles進行分類。
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
},
});
var polyline = viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
-75.60217330403601,
40.04102882709425,
-75.59968252414251,
40.04093615560871,
-75.598020153828,
40.04079437042357,
-75.59674934074435,
40.040816173283304,
-75.59630042791713,
40.03986900370842,
-75.59563636849978,
40.03930996506271,
-75.59492397899098,
40.03873932846581,
-75.59457991226778,
40.038392701955786,
-75.59424838652453,
40.03775403572295,
-75.59387104290336,
40.03677022167725,
-75.59355000490342,
40.03588760913535,
]),
width: 8,
material: new Cesium.PolylineOutlineMaterialProperty({
color: Cesium.Color.YELLOW,
outlineWidth: 2,
outlineColor: Cesium.Color.BLACK,
}),
clampToGround: true,
// TERRAIN 將僅對地形進行分類;CESIUM_3D_TILE 將僅對3D Tiles進行分類;BOTH 將同時對Terrain和3D Tiles進行分類。
classificationType: Cesium.ClassificationType.TERRAIN,
},
});