项目地址
https://github.com/zhengjie9510/webgis-demo
实现效果
实现方法
方式1:heightReference属性
使用 Billboard 自带的 heightReference 属性实现贴地。该方法的好处是实现简单,但如果数据量巨大(50000以上),加载会比较慢。
使用该方法需要在创建 BillboardCollection 时指定 scene 属性。
const collection = new Cesium.BillboardCollection({ scene: viewer.scene })
并在创建 Billboard 时将 heightReference 设置为 CLAMP_TO_GROUND。
collection.add({
position: position,
image: pinBuilder.fromColor(Cesium.Color.fromRandom({ alpha: 1.0 }), 20).toDataURL(),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
})
方式2:sampleTerrainMostDetailed方法
如果数据量较大,另一种可行的方法是先使用 sampleTerrainMostDetailed 获取点的高程,并存储到数据库中,之后直接从数据库中读取数据。该方式只在高程采样时较慢,后面的加载会非常快,比较适用于大量数据的加载显示。
// 1、生成大量随机点
const points = randomPoint(500, { bbox: [100, 25, 102, 27] })
// 2、Cartographic数组
const positions = []
for (let point of points.features) {
const coordinates = point.geometry.coordinates
const position = Cesium.Cartographic.fromDegrees(coordinates[0], coordinates[1])
positions.push(position)
}
// 3、高程采样
const pinBuilder = new Cesium.PinBuilder();
const collection = new Cesium.BillboardCollection()
const terrainProvider = viewer.terrainProvider
const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, positions);
Promise.resolve(promise).then(function (updatedPositions) {
for (let position of updatedPositions) {
collection.add({
position: Cesium.Cartesian3.fromRadians(position.longitude, position.latitude, position.height),
image: pinBuilder.fromColor(Cesium.Color.fromRandom({ alpha: 1.0 }), 20).toDataURL(),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
})
}
viewer.scene.primitives.add(collection)
});