我们知道,Cesium.Scene有一个成员叫primitives,它是一个PrimitiveCollection的实例,我们可以add新的Cesium.Primitive的实例进去,它会自动将之渲染到场景里。
但是当我们需要进行图形集管理的时候就不能把所有的primitive添加到这里面了,于是Cesium新人就有一个问题:怎么渲染自己new的PrimitiveCollection?
渲染PrimitiveCollection
文档没说,网上搜了一圈也没找到答案,一番折腾后发现:
其实,我们可以把自己new的PrimitiveCollection直接add到viwer.scene.primitives里,这样我们就可以实现场景里的图形的管理树了。
如下所示:
其实文档是有这样一个例子的:
const billboards = new Cesium.BillboardCollection();
const labels = new Cesium.LabelCollection();
const collection = new Cesium.PrimitiveCollection();
collection.add(billboards);
scene.primitives.add(collection); // Add collection
scene.primitives.add(labels); // Add regular primitive
所以:看文档要仔细啊,看文档要仔细啊,看文档要仔细啊|||
add (primitive|PrimitiveCollection, index ) → Object
图层管理
其实在上面我们已经实现了对场景中的图形进行树状管理,只是没有UI去表现和控制。由于我用了ant-design这个UI框架,所以我通过如下方法将viewer.scene.primitives的图形树转成了a-tree组件需要的数据结构。
/**
* 把primitivesCollection转为<a-tree/>需要的结构
* @param { Array<Cesium.Primitive> }
* @param {Array} result 转化结果,<a-tree/>的tree-data
* */
function formatePrimitiveTree(primitives, result) {
primitives instanceof Array && primitives.forEach(p => {
if (!p.id || hideCollections.indexOf(p.id) > -1) {
return;
}
const node = {
key: p.id,
title: p.name
};
if (p._primitives && p._primitives instanceof Array) {
node.children = [];
formatePrimitiveTree(p._primitives, node.children);
}
result.push(node);
})
}
// 调用
const res = [];
formatePrimitiveTree(viewer.scnen.primitives._primitives, res);
当然,primitive上默认没有id、name这些属性,这是我在调用Cesium.Model.fromGltf()这步给他添加的。
如果你把res的值传递给了<a-tree/>的tree-data插槽,应该能看到如下渲染结果: