Cesium笔记(3):基本控件简介—ImageryProvider地图⽡⽚地图配
cesiumjs中可定制多种图层,可以使⽤互联⽹上很多地图提供商的图层数据,也可以使⽤⾃⼰的地图数据。Cesium⽀持多种标准化格式的GIS⽡⽚服务,可以把栅格图层绘制到
地球的表⾯——cesiumjs的地图图层本质上是⼀些⽡⽚数据,这些图层的亮度、对⽐度、⾊相均可以动态调整。
对于地图⽡⽚数据,OGC(Open Geospatial Consortium开放地理联盟)有很多标准,如TMS、WMTS、各个商业公司也有⾃⼰的内部标准。推荐阅读:《》
cesiumjs⽀持的图层格式
wms
TMS
WMTS (with time dynamic imagery)
ArcGIS
Bing Maps
Google Earth
Mapbox
OpenStreetMap
默认地,Cesium使⽤Bing Maps作为默认的图层。这个图层被打包进Viewer中⽤于演⽰。Cesium需要您⾃⼰创建ion account然后⽣成⼀个access key⽤于访问图层数据。
Cesium ion
Cesium ion是⼀个提供⽡⽚图和3D地理空间数据的平台,Cesium ion⽀持把数据添加到⽤户⾃⼰的CesiumJS应⽤中。下⾯我们将使⽤Sentinal-2⼆维贴图和Cesium世界地形,
⼆者都需要ion的⽀持。
如果我们在使⽤Cesium的过程中,没有申请ion,同时没有⾃⼰的数据源⽤⽽是使⽤cesium提供的数据源,viewer的底部常常会提⽰⼀⾏⼩的英⽂字母。⼤意就是需要申请
access token。
在创建Cesium Viewer的时候,将access token填为⾃⼰的access token即可。
Cesium.Ion.defaultAccessToken = '<YOUR ACCESS TOKEN HERE>';
使⽤Cesium的数据源,需要配置IonImageryProvider(去Cesium ion页⾯,将相关的案例数据 Add to my assets,此时将在个⼈的app中图层数据源变得可⽤)
let imageryProvider= new Cesium.IonImageryProvider({
assetId: 3812,
accessToken: 'JqdGkiOiJhMTg2Mzk0My02NWJmLTQ1ODgtOWRiMy0wODM1ZTkwNGM1NTYiLCJpZCI6MjM0NzYsInNjb3BlcyI6WyJhc2wiLCJhc3IiLCJhc3ciLCJnYyJdLCJpYXQiOjE1ODM0NjEyMD })
要是⾃定义配置,可以使⽤ImageryProvider
影像服务综述
Cesium中提供了多种ImageryProvider⽅式,Cesium⽬前⽀持的影像服务类型有:
ArcGisMapServerImageryProvider
⽀持ArcGIS Online和Server的相关服务
BingMapsImageryProvider
Bing地图影像,可以指定mapStyle,详见BingMapsStyle类
createOpenStreetMapImageryProvider
OSM影像服务,根据不同的url选择不同的风格
createTileMapServiceImageryProvider
看⽂档是根据MapTiler规范,貌似是可以⾃⼰下载⽡⽚,发布服务,类似ArcGIS影像服务的过程
GoogleEarthImageryProvider
企业级服务,没有⽤过
ImageryProvider
基类,所有的影像服务最终都基于此类,如果你需要扩展新的Provider也会继承该类
MapboxImageryProvider
Mapbox影像服务,根据mapId指定地图风格
SingleTileImageryProvider
单张图⽚的影像服务,适合离线数据或对影像数据要求并不⾼的场景下
UrlTemplateImageryProvider
指定url的format模版,⽅便⽤户实现⾃⼰的Provider,⽐如国内的⾼德,腾讯等影像服务,url都是⼀个固定的规范,都可以通过该Provider轻松实现。⽽OSM也是通过该类
实现的。
WebMapServiceImageryProvider
符合WMS规范的影像服务都可以通过该类封装,指定具体参数实现
WebMapTileServiceImageryProvider
服务WMTS1.0.0规范的影像服务,都可以通过该类实现,⽐如国内的天地图
TileCoordinatesImageryProvider
渲染每⼀个⽡⽚的围,⽅便调试
GridImageryProvider
渲染每⼀个⽡⽚内部的格⽹,了解每个⽡⽚的精细度
配置影像服务
var bing = new Cesium.BingMapsImageryProvider({
url : 'dev.virtualearth',
key : 'get-yours-at-www.bingmapsportal/',
mapStyle : Cesium.BingMapsStyle.AERIAL});
var viewer = new Cesium.Viewer('cesiumContainer', {
shouldAnimate : true,
ImageryProvider:bing,
baseLayerPicker : false,//关闭图层选择器,不然还怎么指定呢
});
扩展影像服务
如果需要⾃⼰提供地图图层数据,就需要⾃⼰实现⼀个imageryProvider并赋予viewer的imageryProvider属性。
天地图影像服务
以国内数据的范畴来看,个⼈认为最佳,⼀来是数据内容和完整性,⼆来是不⽤许可⽆偏移,三来浏览速度还是很不错,国内其他影像服务能够满⾜这三点的并不多。
天地图影像服务都是全球范围,分为墨卡托投影和经纬度两种坐标系,后者标识的是CGCS2000坐标系,
对我这样的⾮专业⼈⼠,我等同于WGS84。另外,天地图提供了中英⽂的注记,也是很不错的。
⾸先,通过天地图的GetCapabilities信息,获取其相关的参数,重要信息如下:
通过红框处,我们可以知道,该WMTS服务的url,Layer的Name,Style,Format以及TileMatrixSet等关键属性的值。有了这些属性,我们就可以通过WebMapTileServiceImageryProvider构造出天地图的Provider
var imageryProvider = new Cesium.WebMapTileServiceImageryProvider({
url : 't0.tianditu/img_w/wmts?',
layer : 'img',
style : 'default',
format : 'tiles',
tileMatrixSetID : 'w',
// tileMatrixLabels : ['default028mm:0', 'default028mm:1', 'default028mm:2' ...],
maximumLevel: 18,
credit : new Cesium.Credit('天地图')
});
viewer.imageryLayers.addImageryProvider(imageryProvider);
//全球影像中⽂注记服务
viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({
url: "t0.tianditu/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default.jpg",
layer: "tdtAnnoLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible",
show: false
}));
创建天地图不⿇烦,但如何更好的创建呢?
⽐如轮询机制,我们知道天地图提供了't0','t1','t2','t3','t4','t5','t6','t7'8个域名,服务端TCP最⼤链接数是有限制的,轮询机制下⽡⽚下载的速度更有保证,很可惜,尽管Cesium提供了subdomains的属性,但需要把url按照format的⽅式来指定参数,所以我们需要稍微调整⼀下构建过程,把我们需要的参数都format到url中
Cesium⼤多也是默认Provider是按照墨卡托投影的,但天地图也提供了经纬度的影像服务,创建经纬度的天地图需要注意两个地⽅,⼀个是tilingScheme,指定为经纬度,另⼀个就是tileMatrixLabels,因为level是从1开始(⽽不是0),所以需要指定每⼀层级的索引号。
地图地图叠加——添加多个Provider
⼀个Provider满⾜⽤户的业务要求,⽐如有⼀个全球影像,但同时有⼀副全美⼈⼝密度专题图,是否能够叠加上去?
看似简单,其实⾥⾯涉及到很多细节问题,叠加顺序涉及到渲染队列的优先级,两幅影像的投影不⼀致怎么办?如果全美⼈⼝密度专题图不是全球范围,只是美国范围,这样叠加是否能够准确?
Cesium很好的解决了这些实际中的问题,简单说每⼀个Provider都对应⼀个tilingScheme,⽀持经纬度和墨卡托两种投影⽅式,默认是全球范围,⽤户也可以指定其范
围,Cesium内部会根据这些参数来实现叠加效果。可以指定每⼀个ImagerLayer的Style。
//初始化⼀个查看器,并且提供⼀个栅格图层
var viewer = new Cesium.Viewer( 'cesiumContainer', {
imageryProvider : new Cesium.ArcGisMapServerImageryProvider( {
url : 'server.arcgisonline/ArcGIS/rest/services/World_Street_Map/MapServer'
} ),
baseLayerPicker : false
} );
//添加另外⼀个图层
3tiles
var layers = viewer.scene.imageryLayers;
var blackMarble = layers.addImageryProvider( new Cesium.TileMapServiceImageryProvider( {
url : '///tilesets/imagery/blackmarble',
maximumLevel : 8,
credit : 'Black Marble imagery courtesy NASA Earth Observatory'
} ) );
//设置图层的透明度
blackMarble.alpha = 0.5;
/
/设置图层的亮度
blackMarble.brightness = 2.0;
//添加⼀个图层,在特定位置绘制⼀个图⽚
layers.addImageryProvider(new Cesium.SingleTileImageryProvider({
url : '../images/Cesium_Logo_overlay.png',
rectangle : Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75)
}));
多种图层能够被添加、移除、排序和适应到Cesium中。
Cesium提供了⼀系列⽅法⽤于处理图层,⽐如颜⾊⾃适应,图层叠加融合。⼀些样例代码如下:
ImageryProvider添加图形标记
如果需要做⼀些标记怎么办?除了⽤entry实体添加外,其实⽤图层也是可以的
var layers = viewer.scene.imageryLayers;
layers.addImageryProvider(new Cesium.SingleTileImageryProvider({
url : '../Apps/Sandcastle/images/Cesium_Logo_overlay.png',
rectangle : Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75)
}));
不过我是基本不⽤此法
Cesium投影系统选择
Cesium⽀持经纬度和墨卡托两种⽅式,⽽且效率都很不错,那我们该如何选择呢?当然是有什么就⽤什么了,但相⽐⽽⾔,经纬度的效率要快⼀些。可惜墨卡托的影像更丰富⼀些。为什么经纬度的效率⾼,这要牵扯到地形数据,以及动态投影的计算,后⾯在介绍Cesium地形原理时,会详细的阐述,这⾥我们只需要知道这个性能考虑因素就可以了。
参考⽂章