贴地是指将三维几何图形(如点、线、面)的位置固定在地形表面上,使得它们随着地形的起伏而起伏。在CesiumJS中,实现贴地效果是一项常见的需求,尤其是在处理地形数据时。贴地意味着将点、线、面等几何图形紧密贴合到地形表面,防止漂浮在空中,从而提供更加真实的视觉效果。
点、线、面的贴地实现
点的贴地
对于点(Point),贴地是通过设置 heightReference
属性实现的。heightReference
定义了实体相对于地球表面的高度参考,它可以取以下几个值:
Cesium.HeightReference.NONE
:无高度参考,点将位于其局部空间内指定的高度。Cesium.HeightReference.CLAMP_TO_GROUND
:点将贴合到地形上,即与地形的高度对齐Cesium.HeightReference.RELATIVE_TO_GROUND
:实体的高度是相对于地形的,常用于需要在地形上方一定高度展示的实体。
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915),
point: {
color: Cesium.Color.SKYBLUE,
pixelSize: 10,
outlineColor: Cesium.Color.YELLOW,
outlineWidth: 3,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
}
});
线的贴地
对于线(Polyline),贴地是通过设置 clampToGround
属性为 true
来实现的。这个属性表示线将随着地形的起伏而起伏,实现贴地效果。
viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
-122.19, 46.1914, -122.21, 46.21, -122.23, 46.21
]),
width: 2,
material: Cesium.Color.GREEN.withAlpha(0.5),
clampToGround: true,
}
});
面的贴地
对于面(Polygon),贴地设置稍微复杂一些。需要将 perPositionHeight
设置为 false
,这样面的每个顶点就不会单独根据地形高度变化,而是整个面都贴合到地形上。同时,设置 heightReference
为 CLAMP_TO_GROUND
确保面是贴在地形上的。
viewer.entities.add({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
-122.19, 46.1914, -122.21, 46.21, -122.23, 46.21
]),
material: Cesium.Color.BLUE.withAlpha(0.5),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
}
});
模型
3D Tiles模型贴地
对于3D Tiles模型,贴地通常是通过调整模型矩阵(model matrix)来实现的。下述示例代码展示了如何通过设置模型矩阵来调整3D Tiles模型的高度,使其贴合地形:
var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: 'path/to/your/tileset.json',
}));
tileset.readyPromise.then(function(tileset) {
var heightOffset = -210; // 根据实际情况调整高度偏移值
var boundingSphere = tileset.boundingSphere;
var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset);
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
});
实体(Entity)模型贴地
对于实体模型,可以通过设置 heightReference
属性为 CLAMP_TO_GROUND
来实现贴地效果:
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706),
model: {
uri: 'path/to/your/model.glb',
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
}
});
贴模型
在CesiumJS中,classificationType
属性用于控制实体的绘制是否与地形或3D Tiles进行交互,从而实现不同的视觉效果。这个属性可以取以下几个值:
- Cesium.ClassificationType.TERRAIN:仅在地形上绘制。当设置为这个值时,实体(如多边形、线等)将只与地形进行交互,忽略3D Tiles的影响。
- Cesium.ClassificationType.CESIUM_3D_TILE:仅在3D Tiles上绘制。这意味着实体的绘制将只与3D Tiles相交,而不考虑地形的影响。
- Cesium.ClassificationType.BOTH:在地形和3D Tiles上都绘制。这是默认值,实体的绘制会同时考虑地形和3D Tiles的影响。
var polygonEntity = viewer.entities.add({
polygon : {
hierarchy : Cesium.Cartesian3.fromDegreesArray([
-122.0744619, 44.0503706,
-121.0744619, 44.0503706,
-121.0744619, 43.0503706,
-122.0744619, 43.0503706
]),
material : Cesium.Color.GREEN.withAlpha(0.5),
heightReference : Cesium.HeightReference.CLAMP_TO_GROUND,
classificationType: Cesium.ClassificationType.BOTH
}
});