cesium中如何创建图片点位和点击Billboard更改其图片

404 阅读2分钟

大屏可视化中,我们会经常遇到一个需求就是在地图上打点,为了好看一般点位都是图片的形式。并且点击的时候会有切换图片,告诉用户当前点击的是哪个点。

在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即可