上帝希望:
有个底图管理功能,用户配置好需要展示的底图后,在地图页面会出现相应的底图可供切换;
大概就这样吧底图切换。
思考:
1、首先要想动态管理底图,地图页面动态渲染底部的basemap组件。
那底图的前端渲染数据格式要确定,
2、cesium 切换图层的方法
3、看了网上大佬们写的cesium 底图切换,大部分都不算真正意义上的底图,脱离上帝太远了,落不了地
设计思路:
1、数据格式:看了页面长那样,大概知道了,数据需要:img , label,图层的类型type 以及构造 layer 的参数 params ;
2、切换图层方法:
(
我先插一下什么叫底图的切换:底图就是最底层的图层,在底图切换的时候上面叠加的图层不会受到任何影响
)
之前在arcgis 中实现底图的切换:arcgis 的map 类中 有一个basemap 的属性,只需要将底图加入basemap 中就可以了,切换的时候更改basemap 中的图层即可,不需要在考虑图层的顺序
一开始我按照之前 arcgis 写的思路:寻找 view 中basemap 这个属性,但是 cesium 的 viewer 没有这个属性,他甚至没有底图这个概念,只有 imageryLayers 图像图层,大部分的图层都算这个子类。
然后我就想把底图的图层都放在一个类似于 layersGroup 的图层组集合中,然后找到这个集合,每次切换的时候对这个集合进行操作,方便管理。
cesium 的确实有 ImageryLayerCollection 这样的一个类,我尝试创建这样一个图层组集合,但是发现viewer 不支持直接加入这个集合;这个 ImageryLayerCollection 我认为只是 对于viewer.imageryLayers 返回这样一个图层集合,可在这里看到集合的操作方法等等。(暂时没看到其他用处)
既然走不通,那就姥姥的踏踏实实的写切换方法把 ============》》》》
先移除之前的,然后在添加现在的,最后在调整下层级顺序
上代码!
首先是数据格式:
tdtUrl: "https://t{s}.tianditu.gov.cn", //天地图主域名
const basemapOptions =[
/**
* type代表地图服务类型
* 0 代表ArcGisMapServerImageryProvider;
* 1 代表createOpenStreetMapImageryProvider;
* 2 代表WebMapTileServiceImageryProvider;
* 3 代表createTileMapServiceImageryProvider;
* 4 代表UrlTemplateImageryProvider;
* 5 代表WebMapServiceImageryProviderr);
*/
{
id:'TDTSL',
img:'',//缩略图
type:2,
label:'天地图矢量',
params:[
{
url: tdtUrl + '/cva_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cva&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,
layer: 'veccva',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
credit: new Cesium.Credit('天地图矢量注记'),
maximumLevel: 18
},
{
url: tdtUrl + '/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=vec&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,
layer: 'vec',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
credit: new Cesium.Credit('天地图矢量'),
maximumLevel: 18
},
]
},
{
id:'TDTYX',
img:'',//缩略图
type:2,
label:'天地图影像',
params:[
{
url: tdtUrl + '/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,
layer: 'imgcia',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
credit: new Cesium.Credit('天地图影像注记'),
maximumLevel: 18
},
{
url: tdtUrl + '/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,
layer: 'img',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
credit: new Cesium.Credit('天地图影像'),
maximumLevel: 18
},
]
}
]
大概就上面的吧。
然后是切换方法:
这个不想放啊,再放还不如直接放整个底图切换的 js 咯;
算了,给你们抄吧,抄作业不得抄个爽!!!
/**
* @Description: 提供底图配置参数,底图切换方法
* @author MrKuang
* @VX k792794653
* @date 2022/8/5 0005
*/
const basemapOptions =[
/**
* type代表地图服务类型
* 0 代表ArcGisMapServerImageryProvider;
* 1 代表createOpenStreetMapImageryProvider;
* 2 代表WebMapTileServiceImageryProvider;
* 3 代表createTileMapServiceImageryProvider;
* 4 代表UrlTemplateImageryProvider;
* 5 代表WebMapServiceImageryProviderr);
*/
{
id:'TDTSL',
img:'',//缩略图
type:2,
label:'天地图矢量',
params:[
{
url: tdtUrl + '/cva_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cva&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,
layer: 'veccva',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
credit: new Cesium.Credit('天地图矢量注记'),
maximumLevel: 18
},
{
url: tdtUrl + '/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=vec&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,
layer: 'vec',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
credit: new Cesium.Credit('天地图矢量'),
maximumLevel: 18
},
]
},
{
id:'TDTYX',
img:'',//缩略图
type:2,
label:'天地图影像',
params:[
{
url: tdtUrl + '/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,
layer: 'imgcia',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
credit: new Cesium.Credit('天地图影像注记'),
maximumLevel: 18
},
{
url: tdtUrl + '/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' + token,
layer: 'img',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
credit: new Cesium.Credit('天地图影像'),
maximumLevel: 18
},
]
}
]
export const changeBasemap =(viewer,val)=>{
const f =viewer.imageryLayers._layers.filter(item=>{
return item.lyr_id;
})
if(f.length == 0){
viewer.imageryLayers.remove(viewer.imageryLayers.get(0))
const l = getLayer(getLayerOption('TDTSL'));//默认加载天地图矢量
l.forEach(itme =>{
viewer.imageryLayers.add(itme);
viewer.imageryLayers.lowerToBottom(itme);
})
}else{
for (const elem of f) {
viewer.imageryLayers.remove(elem);
}
const l = getLayer(getLayerOption(val));//默认加载天地图矢量
l.forEach(itme =>{
viewer.imageryLayers.add(itme);
viewer.imageryLayers.lowerToBottom(itme);
})
}
}
function getLayerOption(val){
return basemapOptions.find(item =>{
return item.id == val;
})
}
function getLayer (val){
let tempLayerList=[];
switch (val.type){
case 0:{
break;
}
case 1:{
break;
}
case 2:{
val.params.forEach(item =>{
let l =new Cesium.ImageryLayer(
new Cesium.WebMapTileServiceImageryProvider(item)
)
l.lyr_id = 'basemapLayer';
l.lyr_name = val.id;
tempLayerList.push(
l
)
})
break;
}
}
return tempLayerList;
}
索性前端页面调用方式也放出来吧:
实例化viewer 之后添加这样就行
切换的时候这样:
我这边还是直接写的'TDTYX',
因为我前端页面还没写好啊,哈哈哈,到时候写完直接把底图标签中数据的id 传进来就ok了。
最后大概看下效果把: