选择图层选择器初始图层
cesium每更新一个版本,就会导致默认的三维球不可见,原因是bingkey发生了变化,如果我们想设置三维球加载的初始图层,可以修改viewer的imageryProvider属性,但是这样做会导致一个问题:baseLayerPicker控件的按钮图标会显示为空白
今天我们来解决这个问题。
拿到问题不要直接开怼,想一想,应该怎么做?
- 首先我们知道这个控件就是一个div,那毫无疑问,使用js强制修改肯定是可以尝试的
- 如果尝试失败,那就只能去看源码了,毕竟初始化加载bing地图是可以的
先来尝试第一个
先开F12,选中baseLayerPicker控件,可以看到图片的展示是由class为cesium-baseLayerPicker-selected的img显示的,而且样式为不可见
<img draggable="false" class="cesium-baseLayerPicker-selected" data-bind="attr: { src: buttonImageUrl }, visible: !!buttonImageUrl" style="display: none;">
既然这样我们就直接修改掉
var viewer = new Cesium.Viewer('cesiumContainer', {
baseLayerPicker: true,
imageryProvider: new Cesium.OpenStreetMapImageryProvider({
url : 'https://a.tile.openstreetmap.org/'
}),
});
//这里为了保证思路清晰,没做代码错误检查
let imgitem = document.getElementsByClassName('cesium-baseLayerPicker-selected')[0];
imgitem.src=Cesium.buildModuleUrl('Widgets/Images/ImageryProviders/openStreetMap.png');
imgitem.setAttribute("style","");
发现可以达到目的,但是,总感觉改的方式。。。很丑陋,试一下第二个方法
参考源码来改
先在源码里搜索一下new OpenStreetMapImageryProvider,看在哪里用到了,发现在\Source\Widgets\BaseLayerPicker\createDefaultImageryProviderViewModels.js里面有,代码很简单,就是创建了一个数组保存了不同图层的设置
我们先来看BaseLayerPicker的初始化,逐步调试,发现进入BaseLayerPickerViewModel之后有个这
this.selectedImagery = defaultValue(options.selectedImageryProviderViewModel, imageryProviderViewModels[0]);
this.selectedTerrain = defaultValue(options.selectedTerrainProviderViewModel, terrainProviderViewModels[0]);
也就是说,控件初始化之后,默认选择了imageryProviderViewModels的第一个子元素,那我们可不可以修改呢?答案是可以,
上面的代码 options.selectedImageryProviderViewModel表示selectedImageryProviderViewModel是可以传入的,
再看Viewer.js中对BaseLayerPicker的初始化,表示imageryProviderViewModels 也是可以传入的
// BaseLayerPicker
var baseLayerPicker;
var baseLayerPickerDropDown;
if (createBaseLayerPicker) {
var imageryProviderViewModels = defaultValue(options.imageryProviderViewModels, createDefaultImageryProviderViewModels());
var terrainProviderViewModels = defaultValue(options.terrainProviderViewModels, createDefaultTerrainProviderViewModels());
...
}
于是,我们可以尝试
var vmodels = Cesium.createDefaultImageryProviderViewModels();
var viewer = new Cesium.Viewer('cesiumContainer', {
baseLayerPicker: true,
imageryProviderViewModels:vmodels,
selectedImageryProviderViewModel:vmodels[9]
});
成功
控件初始化后修改
还有个更简单的方法,控件初始化之后,直接修改
viewer.baseLayerPicker.viewModel.selectedImagery = viewer.baseLayerPicker.viewModel.imageryProviderViewModels[9];
总结一下:
- 大多数情况我们都可以直接是用js修改界面达到自己的目的,够灵活,但是解决方案不够优雅,也有可能造成莫名其妙的问题,不是最优的解法。
- 参考源码的调用方法优雅,但不是很灵活,因为库本身不一定提供了你需要的接口。
- 既然通过Cesium.createDefaultImageryProviderViewModels可以拿到所有图层配置的集合,那么要自己添加的话,只需要往这个集合里增加更多的图层配置就行啦~