当前位置: 首页 > 文档资料 > Cesium 中文文档 >

选择图层选择器初始图层

优质
小牛编辑
133浏览
2023-12-01

cesium每更新一个版本,就会导致默认的三维球不可见,原因是bingkey发生了变化,如果我们想设置三维球加载的初始图层,可以修改viewer的imageryProvider属性,但是这样做会导致一个问题:baseLayerPicker控件的按钮图标会显示为空白

今天我们来解决这个问题。

拿到问题不要直接开怼,想一想,应该怎么做?

  1. 首先我们知道这个控件就是一个div,那毫无疑问,使用js强制修改肯定是可以尝试的
  2. 如果尝试失败,那就只能去看源码了,毕竟初始化加载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];

总结一下:

  1. 大多数情况我们都可以直接是用js修改界面达到自己的目的,够灵活,但是解决方案不够优雅,也有可能造成莫名其妙的问题,不是最优的解法。
  2. 参考源码的调用方法优雅,但不是很灵活,因为库本身不一定提供了你需要的接口。
  3. 既然通过Cesium.createDefaultImageryProviderViewModels可以拿到所有图层配置的集合,那么要自己添加的话,只需要往这个集合里增加更多的图层配置就行啦~