当我接收到前人的代码时,我内心是崩溃的。当我看到无数entity被挂载window下以方便传递,entity.id被指定为“类型-后端返回的id”时,我想是时候提前40年退休了,因为处理这种屎山无异于屎里淘金。
-
神说,要优雅————
-
于是我在文档里发现了 EntityCollection 。
不说怪话,今天来谈谈EntityCollection,实际上是对 syncEntityCollection 的介绍。
介绍
或许大家已经尝试过使用 EntityCollection 对entity进行管理,但是对于需要分类的情况,即使是EntityCollection也很难办。因为他只是提供了一种扁平的数据结构(也就是其内部使用的数组)。而 Cesium use 的 syncEntityCollection
给出了一种很有意思的思路:在扁平化数据结构的基础上拓展为树形结构。
简单来说,syncEntityCollection 方法将一个 EntityCollection 同步到另一个 EntityCollection。大白话说起来没什么用,直接上代码:
const collection = new Cesium.EntityCollection()
syncEntityCollection(viewer.entities, collection) // 将 collection 同步到 viewer.entities
这样在对collection进行增删操作时,这些操作都会被同步到viewer.entities,因为viewer.entities也是一个EntityCollection。
const entity = collection.add({})
viewer.entities.contains(entity) // true
collection.remove(entity)
viewer.entities.contains(entity) // false
syncEntityCollection 提供了一种简写,如果没有传递第二个参数,那么会自动创建一个空的集合,同步到目标集合后返回:
const newCollection = syncEntityCollection(viewer.entities)
这种同步是可以多个数量的,既可以向多个EntityCollection同步,也可以被多个EntityCollection同步
const c1 = new Cesium.EntityCollection()
const c2 = syncEntityCollection(c1)
const c3 = new Cesium.EntityCollection()
syncEntityCollection(viewer.entities, c2)
syncEntityCollection(viewer.entities, c3)
接下来是最精彩的地方。因为collection本身也是一个EntityCollection,因此他也可以被同步:
// 没看明白没关系,见下图
const together = syncEntityCollection(viewer.entities)
const syncTo = () => syncEntityCollection(together)
const layers = syncTo()
const others = syncTo()
上面这段代码看起来像这样:
有了这种方案,你可以完全无视entity管理本身带来的复杂度,举个例子:
实战
你的项目中需要管理图层,因此有个图层集合:
const layers = syncEntityCollection(viewer.entities)
图层中存在一个小姐姐类型,用来表示所有小姐姐。你的小姐姐有很多,所以可以用EntityCollection来管理:
const city = syncEntityCollection(layers)
const food = syncEntityCollection(layers)
// ...
const beauty = syncEntityCollection(layers)
然而你的小姐姐还要分正室、侧室、后宫。。。因此小姐姐们也要用EntityCollection管理:
const wife = syncEntityCollection(beauty)
const concubine = syncEntityCollection(beauty)
// ...
终于可以好好把小姐姐放进集合里管理了:
const wifeA = wife.add({
position: xxx
})
const concubineB = concubine.add({
position: yyy
})
代码看起来很简单,对吧?你只需要妥善管理其层级即可,最终看起来像这样:
在必要的时候,可以隐藏所有的wife: wife.show = false
也可以直接隐藏所有的妹子 beauty.show = false
报告完毕!