cesium万量级数据加载,使用Primitive API

124 阅读1分钟

第一步,根据每条数据,生成instance

  1. 创建 Geometry,根据你需要的Geometry类型,使用不同的api,我这里使用的是PolygonGeometry,基本上在文档里搜索Geometry,Geometry结尾的都可以用,例如BoxGeometry,CircleGeometry
  2. 根据Geometry数据生成GeometryInstance
getPolygonGeometryInstance(positions, item, color) {
    if (!Array.isArray(positions)) return
    const geo = new Cesium.PolygonGeometry({
        polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(positions))
      }),
    return new Cesium.GeometryInstance({
      // 根据你需要的图元类型,使用不同的api,我这里使用的是PolygonGeometry
      geometry: geo,
      id: item, // 点击事件时通过id拾取数据
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(
          new Cesium.Color.fromCssColorString(color)
        )
      }
    })
  }

第二步,根据instance集,创建Primitive

注意,不要每条数据都创建一个Primitive,内存会爆炸

// 收集instance
let instances = []
this.data.forEach((item, i) => {
    const instance = getPolygonGeometryInstance(item.geoData)
    instances.push(instance)
})
this.setPrimitive(instances)

// 根据instaance创建Primitive
setPrimitive(instances) {
    const primitive = new Cesium.GroundPrimitive({
      geometryInstances: instances,
      appearance: new Cesium.PerInstanceColorAppearance({
        //指定材质的颜色 和顶点颜色相同
        closed: true
      })
    })
    primitive.name = this.name
    viewer.scene.primitives.add(primitive) // 加载Primitive
  }

第三步,添加点击事件

之前有写过entity的点击事件,实际也差不多,都是通过ScreenSpaceEventHandler设置setInputAction来获取点击位置,在通过viewer.scene.pick获取点击位置的数据,一般会返回Primitive实例和id,id即之前创建instance是传入的数据

addAction(callback) {
    if (typeof callback !== 'function') return
    const handle = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
    handle.setInputAction((obj) => {
      // obj内一般就一个position属性,为点击位置在视口内的位置
      const entity = this.viewer.scene.pick(obj.position)
      if (!entity || entity.primitive.name !== this.name) return
      callback(entity, obj)
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    const remove = () => {
      handle.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    }
    this.actions.push({ remove, handle })
  }