目录
前言:
(这一期来的比较晚,最近在分心研究jenkins 结合 gitlab自动化部署。有人可能会疑问了,这也要你来做?是的啊,谁让我有个做测试的媳妇呢)
为什么第一个想到的是这个功能??
因为在我看来,所有的gis应用,图层的控制显隐切换,是根本离不开的,也是最基础的。
这一节的实现思路就是:
实现加载天地图影像,天地图矢量,天地图地形图,然后绑定图层切换按钮,实现底图的切换。
先看下实现的效果:
一、加载天地图等WMTS图层
在cesium中加载wmts图层需要用到 Cesium 中的 WebMapTileServiceImageryProvider 类,先贴代码,在一 一 解释(加载天地图需要自己申请key)
//天地图矢量
//天地图矢量
that.TDT_SL =new that.Cesium.WebMapTileServiceImageryProvider({
url:'http://{s}.tianditu.gov.cn/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='+that.token,
layer:'vec',
style:'default',
format:'tiles',
tileMatrixSetID:'w',
subdomains:['t0','t1','t2','t3','t4','t5','t6','t7'],
credit:new that.Cesium.Credit('天地图矢量'),
maximumLevel:18
})
//天地图影像
//天地图影像
that.TDL_YX =new that.Cesium.WebMapTileServiceImageryProvider({
url:'http://{s}.tianditu.gov.cn/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='+that.token,
layer:'img',
style:'default',
format:'tiles',
tileMatrixSetID:'w',
subdomains:['t0','t1','t2','t3','t4','t5','t6','t7'],
credit:new that.Cesium.Credit('天地图影像'),
maximumLevel:18
})
//天地图地形
//天地图影像
that.TDL_YX =new that.Cesium.WebMapTileServiceImageryProvider({
url:'http://{s}.tianditu.gov.cn/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='+that.token,
layer:'img',
style:'default',
format:'tiles',
tileMatrixSetID:'w',
subdomains:['t0','t1','t2','t3','t4','t5','t6','t7'],
credit:new that.Cesium.Credit('天地图影像'),
maximumLevel:18
})
现在剖析下上面 WebMapTileServiceImageryProvider 里面的构造参数
参数名称 | 用途 | 备注 |
url | 服务地址 | 天地图地址从官网找 |
layer | wmts请求的层名称 | |
style | wmts请求的样式名称 | 默认default 不用管 |
format | 从服务器检索图像的MIME类型。 | 'image/jpeg' |
tileMatrixSetID | 用于WMTS请求的TileMatrixSet的标识符。 | |
subdomins | {s} URL模板中用于占位符的子域。如果此参数是单个字符串,则字符串中的每个字符都是一个子域。如果是数组,则数组中的每个元素都是一个子域。 | 这个我要单独细说 |
credit | 数据源属性,可点击显示在html上 | |
maximumLevel | 最大级别,对应的还有minimumLevel |
其中上述的layer , format , tileMatrixSetID 都是我从天地图切片信息中找到它定义的,见下图,经过测试,我随便填好像也无所谓,但是不能少
说到其中那个subdomins这个属性我就来气,曾经有个测试说我控制台有好多报错,我过去一看,是天地图切片资源没有请求到,跟他说还说不通,要让我把错误解决,这个*****,我真想把他给解决了。
这里我和大家说下,天地图是提供了t0-t7 8个域名的,我们用其中任意一个都可以,但是为什么还要在请求的时候添加那么多子域名呢,是因为服务端TCP的连接石油限制的,经常请求不到,所以为了在轮询机制下最大化的提高加载速度,所以提供了
subdomins属性。
哦对了,后面的that.token 是我自己的天地图key,你们用自己去申请
二、创建viewer,初始化
var viewer = new that.Cesium.Viewer("mapContainter", {
animation: false, //是否显示动画控件文章目录
baseLayerPicker: false, //是否显示图层选择控件
geocoder: false, //是否显示地名查找控件
timeline: false, //是否显示时间线控件
sceneModePicker: false, //是否显示投影方式控件
navigationHelpButton: false, //是否显示帮助信息控件
infoBox: true, //是否显示点击要素之后显示的信息
imageryProvider:that.TDL_DX,
scene3Donly:false,//若为true,则所有的几何图形都以3D模式绘制节约GPU资源
showRenderLoopErrors:false,//若为true,将在面板上显示错误信息
});
参数用途写的很详细了,部分没写,所有的参数都在下面,可根据自己需要修改
名称 | 类型 | 属性 | 默认 | 描述 |
---|---|---|---|---|
111111111111111111111111111111111111111 | 1111111111111111111111111 | 1111111111111111111111 | 1111111111111 | 11111111111111111111111111111111111111111111111111111111111111111111 |
animation | 布尔型 | <可选> | true | 如果设置为false,将不创建“动画”窗口小部件。 |
baseLayerPicker | 布尔型 | <可选> | true | 如果设置为false,则不会创建BaseLayerPicker小部件。 |
fullscreenButton | 布尔型 | <可选> | true | 如果设置为false,将不会创建FullscreenButton小部件。 |
vrButton | 布尔型 | <可选> | false | 如果设置为true,将创建VRButton小部件。 |
geocoder | 布尔 | Array。< GeocoderService > | <可选> | true | 如果设置为false,则不会创建Geocoder小部件。 |
homeButton | 布尔型 | <可选> | true | 如果设置为false,将不会创建HomeButton小部件。 |
infoBox | 布尔型 | <可选> | true | 如果设置为false,则不会创建InfoBox小部件。 |
sceneModePicker | 布尔型 | <可选> | true | 如果设置为false,将不会创建SceneModePicker小部件。 |
selectionIndicator | 布尔型 | <可选> | true | 如果设置为false,将不会创建SelectionIndicator小部件。 |
timeline | 布尔型 | <可选> | true | 如果设置为false,则不会创建“时间轴”小部件。 |
navigationHelpButton | 布尔型 | <可选> | true | 如果设置为false,将不会创建导航帮助按钮。 |
navigationInstructionsInitiallyVisible | 布尔型 | <可选> | true | 如果导航指令最初应该是可见的,则为true;如果直到用户明确单击该按钮,则不应显示,否则为false。 |
scene3DOnly | 布尔型 | <可选> | false | true 设为时,每个几何实例将仅以3D渲染以节省GPU内存。 |
shouldAnimate | 布尔型 | <可选> | false | true 默认情况下时钟是否应尝试提前模拟时间,false 否则。此选项优先于setting Viewer#clockViewModel 。 |
clockViewModel | ClockViewModel | <可选> | 新的ClockViewModel(clock) | 用于控制当前时间的时钟视图模型。 |
selectedImageryProviderViewModel | ProviderViewModel | <可选> | 当前基础影像图层的视图模型(如果未提供)将使用第一个可用的基础图层。仅当“ baseLayerPicker”设置为true时,此值才有效。 | |
imageryProviderViewModels | Array。< ProviderViewModel > | <可选> | createDefaultImageryProviderViewModels() | 可以从BaseLayerPicker中选择的ProviderViewModels数组。仅当“ baseLayerPicker”设置为true时,此值才有效。 |
selectedTerrainProviderViewModel | ProviderViewModel | <可选> | 当前基础地形图层的视图模型(如果未提供)将使用第一个可用的基础图层。仅当“ baseLayerPicker”设置为true时,此值才有效。 | |
terrainProviderViewModels | Array。< ProviderViewModel > | <可选> | createDefaultTerrainProviderViewModels() | 可以从BaseLayerPicker中选择的ProviderViewModels数组。仅当“ baseLayerPicker”设置为true时,此值才有效。 |
imageryProvider | 影像提供者 | <可选> | createWorldImagery() | 要使用的图像提供者。仅当“ baseLayerPicker”设置为false时,此值才有效。 |
terrainProvider | TerrainProvider | <可选> | 新的EllipsoidTerrainProvider() | 要使用的地形提供商 |
skyBox | 天空盒 | 假 | <可选> | 用来渲染星星的天空盒。当为时undefined ,使用默认星号。如果设置为false ,则不会添加skyBox,Sun或Moon。 | |
skyAtmosphere | 天空大气 | 假 | <可选> | 蓝天,以及地球四肢的光芒。设置为false 关闭。 | |
fullscreenElement | 元素 | 串 | <可选> | document.body | 按下全屏按钮时要置于全屏模式的元素或ID。 |
useDefaultRenderLoop | 布尔型 | <可选> | true | 如果此小部件应控制渲染循环,则为true,否则为false。 |
targetFrameRate | 数 | <可选> | 使用默认渲染循环时的目标帧速率。 | |
showRenderLoopErrors | 布尔型 | <可选> | true | 如果为true,则在发生渲染循环错误时,此小部件将自动向包含错误的用户显示HTML面板。 |
useBrowserRecommendedResolution | 布尔型 | <可选> | true | 如果为true,则以浏览器建议的分辨率渲染并忽略window.devicePixelRatio 。 |
automaticallyTrackDataSourceClocks | 布尔型 | <可选> | true | 如果为true,则此小部件将自动跟踪新添加的数据源的时钟设置,并在数据源的时钟发生更改时进行更新。如果要独立配置时钟,请将其设置为false。 |
contextOptions | 目的 | <可选> | options 传递给的上下文和WebGL创建属性Scene 。 | |
sceneMode | 场景模式 | <可选> | SceneMode.SCENE3D | 初始场景模式。 |
mapProjection | 地图投影 | <可选> | 新的GeographicProjection() | 在2D和Columbus View模式下使用的地图投影。 |
globe | 地球仪 | 假 | <可选> | 新Globe(mapProjection.ellipsoid) | 场景中使用的地球仪。如果设置为false ,则不会添加任何地球仪。 |
orderIndependentTranslucency | 布尔型 | <可选> | true | 如果为true并且配置支持它,则使用顺序无关的半透明性。 |
creditContainer | 元素 | 串 | <可选> | 包含的DOM元素或ID CreditDisplay 。如果未指定,则将信用额添加到小部件本身的底部。 | |
creditViewport | 元素 | 串 | <可选> | 包含由创建的功劳弹出式广告的DOM元素或ID CreditDisplay 。如果未指定,它将显示在小部件本身上。 | |
dataSources | 数据源集合 | <可选> | 新的DataSourceCollection() | 小部件可视化的数据源集合。如果提供此参数,则假定实例由调用方拥有,并且在销毁查看器时不会销毁该实例。 |
terrainExaggeration | 数 | <可选> | 1.0 | 用于放大地形的标量。注意,地形夸张将不会修改任何其他相对于椭球的图元。 |
shadows | 布尔型 | <可选> | false | 确定阴影是否由光源投射。 |
terrainShadows | 阴影模式 | <可选> | ShadowMode.RECEIVE_ONLY | 确定地形是投射还是接收来自光源的阴影。 |
mapMode2D | MapMode2D | <可选> | MapMode2D.INFINITE_SCROLL | 确定2D地图是可旋转的还是可以在水平方向上无限滚动。 |
projectionPicker | 布尔型 | <可选> | false | 如果设置为true,将创建ProjectionPicker小部件。 |
requestRenderMode | 布尔型 | <可选> | false | 如果为true,则仅根据场景中的更改确定是否需要渲染帧。启用可减少应用程序的CPU / GPU使用率,并减少移动设备上的电池消耗,但需要Scene#requestRender 在此模式下显式渲染新帧。在API的其他部分对场景进行更改之后,在许多情况下这是必要的。请参见使用显式渲染提高性能。 |
maximumRenderTimeChange | 数 | <可选> | 0.0 | 如果requestRenderMode为true,则此值定义在请求渲染之前允许的最大模拟时间更改。请参见使用显式渲染提高性能。 |
三、实现切换功能
在做这个的时候我在想cesium的view里有没有类似arcgis js 中 map 类,有basemap这样的一个属性,
如果有直接更改basemap里的内容即可达到底图切换的效果,如果没有的话,那就只能一开始把底图都加载上,然后按照所选的分别控制显隐了
看了下,好像没有,但是cesium提供了自带的一个底图切换小部件,可以先将 底图图层 创建为 ProviderViewModel ,然后在创建viewer的时候将 baseLayerPicker 设置为true,并在 imageryProviderViewModels 这个属性将底图的 ProviderViewModel ,添加进去
详细的步骤可以参考这个博客:https://blog.csdn.net/weixin_30421809/article/details/96011480
但是我肯定不会这样用的啦,因为这个用它自带的组件样式,基本上在实际应用中会被舍弃的,所以只能自己写切换吧,那按我现在的理解程度,那就只能都加载上然后一个个控制显隐吧,虽然麻烦,但是绝对不难,上代码!
实现方法一:页面一开始一股脑都加载上,然后点击方法对应的控制显隐即可:
其中用 viewer.imageryLayers._layers[2].show 和 viewer.imageryLayers.get(1).show 控制显隐
实现方法二:点击方法绑定全部移除,然后重新添加对应的,这种方法会有问题,就是如果此时球上叠加了其他类型专题图,而我们只想更换下底图看看,会不会重新加载的时候把专题图也给覆盖了,要考虑图层叠加的顺序问题
实现思路三:我看有个ImageryLayerCollection 这个类,或许可以在这个类里做文章
这个留给看博客且有兴趣有精力的人吧,或许你们有更好的思路可以在评论区告诉我哦,最后附上注记的地址
that.TDT_ZJ = new that.Cesium.WebMapTileServiceImageryProvider({
url: 'http://{s}.tianditu.gov.cn/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=' + that.token,
layer: '111',
style: 'default',
format: '111',
tileMatrixSetID: '11',
subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
credit: new that.Cesium.Credit('天地图注记'),
maximumLevel: 18
})
呃。。。。最后的最后在多啰嗦一句吧,天地图地图资源分为影像、矢量和地形,其中各个又分为经纬度投影和墨卡托投影,分别代号为 _c 和 _w,心细的同学可能已经知道了,
而加载不同的类型的底图的时候,也只要改天地图url的三处地方即可,就能切换底图的资源地址,无论是arcgis和cesium加载都是如此
好啦,再见吧!
十年生死两茫茫,写程序,到天亮。
千行代码,Bug何处藏。
纵使上线又怎样,朝令改,夕断肠。
领导每天新想法,天天改,日日忙。
相顾无言,惟有泪千行。
每晚灯火阑珊处,夜难寐,又加班。