圖層組
某天領導找我,說業務中可能存在多個影像服務為一個圖層組,并且需要同時加載和同時在圖層列表中上下移動的需求。
例如一些專題地圖,包含所有學校、醫院、公交站等圖層,而這些圖層都是單獨發布的。
在 Cesium 中確實存在一個圖層組 ImageryLayerCollection 。但是可以發現 ImageryLayerCollection 和 PrimitiveCollection 不同,雖然兩者都會在 Cesium 初始化時創建一個默認的對象,但是 PrimitiveCollection 可以嵌套使用而 ImageryLayerCollection 不行。
Cesium 不能添加圖層組其實對同時加載多個圖層影響不大,但是如果需要在圖層樹中移動位置,就比較復雜了。領導說項目人員很頭疼,速速解決。
實現思路
既然原生的 ImageryLayerCollection 只接受 ImageryLayer 作為子對象。那寫一個能夠管理多個服務的 ImageryLayer 不就行了嗎。
為了不動 Cesium 源碼,可以直接拷貝一份 ImageryLayer.js 到外面修改實現圖層組。
其實 ImageryLayer.js 中做的東西并不算復雜,上級的地形四叉樹在渲染時,會為每塊地形瓦片查找他的貼圖(附著在地形上的影像),這一步操作最終會進入到 _createTileImagerySkeletons 方法,然后就是請求瓦片和判斷是否需要重投影的操作。具體可以參考最復雜的地球皮膚 影像與地形的渲染與下載過程
只是 ImageryLayer.js 中只對一個 imageryProvider 進行管理和操作。那需要做的其實只是把管理一個 imageryProvider 改成管理多個而已。
成果檢驗
測試代碼中創建了三個圖層。為了測試對不同 imageryProvider 的統一管理是否能夠成功實現,因此特地混用了影像服務的切片方案。
bingMapsAerialWithLabels 切片方案為 WebMercatorTilingScheme 而 其余兩個服務切片方案為 GeographicTilingScheme。
觀察 viewer.scene.imageryLayers 中的內容可以發現,成功使用一個 imageryLayer 加載了三個服務
繼續拓展
由于目前圖層組管理的是多個imageryProvider,而不是多個 imageryLayer, 因此實際上只能做到一層嵌套,也就是圖層組里面只能放圖層,而不能放圖層組。
由于目前已經能滿足項目需求,因此就懶得再搞下去了😅
其實要解決也簡單,再封裝一個管理 ImageryLayer 的 ImageryLayer 就行了。
原文鏈接
Cesium中實現圖層組