大屏可视化中,我们会经常遇到一个需求就是在地图上打点,为了好看一般点位都是图片的形式。并且点击的时候会有切换图片,告诉用户当前点击的是哪个点。
在cesium中如何创建图片点位,并且绘制大量点的同时保证性能
cesium中提供了类new Cesium.Billboard中文翻译就是广告牌的意思new Cesium.Billboard官方文档 不废话直接看我的代码:
export function addPoints(points: Array<{ lon: number; lat: number }>) {
const primitives = new Cesium.PrimitiveCollection();
const billboards = new Cesium.BillboardCollection();
primitives.add(billboards);
points.forEach((point) => {
if (point.lon && point.lat) {
billboards.add({
image: cameraPoint,
position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat),
width: 52,
height: 81,
id: 'point-' + point.lon + '-' + point.lat,
});
}
});
return { primitives, billboards };
}
const { primitives } = addPoints([
{
lon: 119,
lat: 32,
},
]);
viewer.scene.primitives.add(primitives)
看到我的代码是不是发现也没有用Cesium.Billboard啊。现在我来一点点解读这段代码到底在做什么
new Cesium.PrimitiveCollection
new Cesium.BillboardCollection
其实就是创建一个集合,可以理解是一个容器,目的就是为了方便管理
比如:billboards.destroy()就可以销毁
primitives同理
billboards.add(options)参数options就是new Cesium.Billboard中的options
然后就是primitives,这个就是能让绘制大量点的时候保持性能
其实还有个原始的方法就是创建Cesium.Entity也是可以创建点位的,但是这个第一不好管理,第二性能不好,点少的倒是无所谓的。
创建点击事件,给点位切换图片
直接看代码:
export function setupClickEvent(viewer) {
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((movement) => {
const pickedObject = viewer.scene.pick(movement.position);
if (pickedObject && pickedObject.collection && pickedObject.primitive && pickedObject.collection.contains(pickedObject.primitive)) {
// 修改点击到的 billboard 的图片
console.log('点击到了 billboard', pickedObject.primitive);
pickedObject.primitive.image = soundPoint;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
创建事件没有好说的,网上都有 核心代码就是:
if (pickedObject && pickedObject.collection && pickedObject.primitive && pickedObject.collection.contains(pickedObject.primitive)) {
// 修改点击到的 billboard 的图片
console.log('点击到了 billboard', pickedObject.primitive);
pickedObject.primitive.image = soundPoint;
}
pickedObject.collection其实就是属于应该是属于Cesium.PrimitiveCollection或者Cesium.BillboardCollection类中的,这两个类中都有一个方法contains,主要是用来判断你点击的点是不是属于创建的里面的。
其实我发现 只要pickedObject.primitive存不存在就可以了,以防万一嘛。
然后将新的图片地址赋值给 pickedObject.primitive.image即可