第一步,根据每条数据,生成instance
- 创建 Geometry,根据你需要的Geometry类型,使用不同的api,我这里使用的是PolygonGeometry,基本上在文档里搜索Geometry,Geometry结尾的都可以用,例如
BoxGeometry,CircleGeometry等 - 根据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 })
}