加载影像数据
Cesium中的影像图层类
无论是二维地图还是三维地图,如果缺少了底图影像或电子地图,都是不完整的。Cesium为我们提供了ImageryLayerCollection、ImageryLayer以及相关的ImageryProvider类来加载不同的影像图层。虽然Cesium把此类图层叫做Imagery*,但并不是特指卫星影像数据,还包括一些互联网地图、TMS、WMS、WMTS、单个图片等。
ImageryLayer类
Cesium.ImageryLayer类用于表示Cesium中的影像图层,它就相当于皮毛、衣服,将数据源包裹在内,它需要数据源(imageryProvider)为其提供内在丰富的地理空间信息和属性信息。同时,通过该类还能设置影像图层相关属性,比如透明度、亮度、对比度、色调等。
ImageryProvider类
Cesium.ImageryProvider类及其子类封装了加载各种影像图层的方法,其中Cesium.ImageryProvider类是抽象类、基类或者可将其理解为接口,它不能被直接实例化。我们可以把ImageryProvider看作是影像图层的数据源(包裹在ImageryLayer类内部),我们想使用哪种影像图层数据或服务就用对应的ImageryProvider子类去加载,目前Cesium提供了以下14种ImageryProvider。
ImageryLayerCollection类
Cesium.ImageryLayerCollection类是ImageryLayer类对象的容器,它可以装载、放置多个ImageryLayer或ImageryProvider类对象,而且它内部放置的ImageryLayer或ImageryProvider类对象是有序的。
Cesium.Viewer类对象中包含的imageryLayers属性就是ImageryLayerCollection类的实例,它包含了当前Cesium应用程序所有的ImageryLayer类对象,即所有影像图层,所以Cesium中的影像图层可以添加多个。
Cesium加载不同类型的影像图层
根据上面提供的Provider可知道,目前Cesium(1.75版本)支持14种类型的影像图层。
ArcGisMapServerImageryProvider
支持ArcGIS Online和Server的相关服务。
var arcgisProvider = new Cesium.ArcGisMapServerImageryProvider({
url:
"https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer",
});
imageryLayers.addImageryProvider(arcgisProvider)
![](/docs/images/cesium/651.png)
BingMapsImageryProvider
Bing地图影像,可以指定mapStyle,详见BingMapsStyle类。
var bingStyle = [
Cesium.BingMapsStyle.AERIAL_WITH_LABELS,
Cesium.BingMapsStyle.COLLINS_BART,
Cesium.BingMapsStyle.CANVAS_GRAY,
Cesium.BingMapsStyle.CANVAS_LIGHT,
Cesium.BingMapsStyle.CANVAS_DARK,
Cesium.BingMapsStyle.ORDNANCE_SURVEY,
Cesium.BingMapsStyle.ROAD,
Cesium.BingMapsStyle.AERIAL,
];
var bingMapProvider = new Cesium.BingMapsImageryProvider({
url: "https://dev.virtualearth.net", //’'https://dev.virtualearth.net',
key: "AmXdbd8UeUJtaRSn7yVwyXgQlBBUqliLbHpgn2c76DfuHwAXfRrgS5qwfHU6Rhm8",
mapStyle: bingStyle[7],
});
imageryLayers.addImageryProvider(bingMapProvider);
![](/docs/images/cesium/652.png)
GoogleEarthEnterpriseImageryProvider
使用谷歌Earth企业REST API提供瓦片图像,可与Google Earth Enterprise的3D Earth API一起使用。
var geeMetadata = new Cesium.GoogleEarthEnterpriseMetadata(
"http://www.earthenterprise.org/3d"
);
var googleEarthProvider = new Cesium.GoogleEarthEnterpriseImageryProvider({
metadata: geeMetadata,
});
imageryLayers.addImageryProvider(googleEarthProvider);
加载谷歌Earth的瓦片影像需要翻墙,这里就不截图了。
GridImageryProvider(开发调试)
展示内部渲染网格划分情况,了解每个瓦片的精细度,便于调试地形和图像渲染问题。
var arcgisProvider = new Cesium.ArcGisMapServerImageryProvider({
url:
"https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer",
});
viewer.imageryLayers.addImageryProvider(arcgisProvider);
var gridImagery = new Cesium.GridImageryProvider();
var gridImageryLayer = viewer.imageryLayers.addImageryProvider(gridImagery);
imageryLayers.raiseToTop(gridImageryLayer); //将图层置顶
![](/docs/images/cesium/653.png)
IonImageryProvider
cesium Ion 在线服务,默认全局基础图像图层(当前为Bing Maps)。
imageryLayers.addImageryProvider(
new Cesium.IonImageryProvider({ assetId: 3954 })
);
![](/docs/images/cesium/654.png)
MapboxImageryProvider
Mapbox影像服务,根据mapId指定地图风格。
var mapIds = [
"mapbox.satellite",
"mapbox.streets",
"mapbox.streets-basic",
"mapbox.light",
"mapbox.streets-satellite",
"mapbox.wheatpaste",
"mapbox.comic",
"mapbox.outdoors",
"mapbox.run-bike-hike",
"mapbox.pencil",
"mapbox.pirates",
"mapbox.emerald",
"mapbox.high-contrast",
];
imageryLayers.addImageryProvider(
new Cesium.MapboxImageryProvider({
mapId: mapIds[0],
accessToken:
"pk.eyJ1IjoibHM4NzAwNjEwMTEiLCJhIjoiY2tqYXZlZ2JrMDI5bTJzcDJmdDNteGhsNyJ9.0wTn4B1ce9Q4U5GnPso5iA",
})
);
![](/docs/images/cesium/655.png)
MapboxStyleImageryProvider
Mapbox影像服务,根据styleId指定地图风格。
var styleIds = [
"streets-v11",
"outdoors-v11",
"light-v10",
"dark-v10",
"satellite-v9",
"msatellite-streets-v11",
];
imageryLayers.addImageryProvider(
new Cesium.MapboxStyleImageryProvider({
styleId: styleIds[0],
accessToken:
"pk.eyJ1IjoibHM4NzAwNjEwMTEiLCJhIjoiY2tqYXZlZ2JrMDI5bTJzcDJmdDNteGhsNyJ9.0wTn4B1ce9Q4U5GnPso5iA",
})
);
![](/docs/images/cesium/656.png)
OpenStreetMapImageryProvider
OSM影像服务,根据不同的url选择不同的风格。
var osm = new Cesium.OpenStreetMapImageryProvider({
url: "https://a.tile.openstreetmap.org/",
minimumLevel: 0,
maximumLevel: 18,
fileExtension: "png",
});
imageryLayers.addImageryProvider(osm);
![](/docs/images/cesium/657.png)
SingleTileImageryProvider
单张图片的影像服务,适合离线数据或对影像数据要求并不高的场景下。
var imagelayer = new Cesium.SingleTileImageryProvider({
url: "./images/worldimage.jpg",
});
imageryLayers.addImageryProvider(imagelayer);
![](/docs/images/cesium/658.png)
TileCoordinatesImageryProvider(开发调试)
展示内部渲染网格瓦片划分情况,包括网格瓦片等级、X、Y序号,便于调试地形和图像渲染问题。当然也可以和GridImageryProvider一起叠加使用。
var imagelayer = new Cesium.SingleTileImageryProvider({
url: "./images/worldimage.jpg",
});
imageryLayers.addImageryProvider(imagelayer);
var tileCoordinates = new Cesium.TileCoordinatesImageryProvider();
var tileCoordinatesLayer = viewer.imageryLayers.addImageryProvider(tileCoordinates);
imageryLayers.raiseToTop(tileCoordinatesLayer); //将图层置顶
![](/docs/images/cesium/659.png)
TileMapServiceImageryProvider
访问瓦片图的Rest接口。瓦片图被转换为MapTiler或GDAL2Tiles。
var imagelayer = new Cesium.TileMapServiceImageryProvider({
url: "//cesiumjs.org/tilesets/imagery/blackmarble",
maximumLevel: 8,
});
imageryLayers.addImageryProvider(imagelayer);
UrlTemplateImageryProvider
指定url的format模版,方便用户实现自己的Provider.比如国内的高德,腾讯等影像服务,url都是一个固定的规范,都可以通过该Provider轻松实现。而OSM也是通过该类实现的,以下是使用XYZ方式加载上面加载过的OSM影像服务。
const osmImageryProvider = new Cesium.UrlTemplateImageryProvider({
url: "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ["a", "b", "c"],
});
imageryLayers.addImageryProvider(osmImageryProvider);
![](/docs/images/cesium/660.png)
这里需要注意参数subdomains,它表示子域。subdomains参数数组中的四个值可以替换url中的{s},也就是改变不同的请求URL,从而提高加载数据的速度。
WebMapServiceImageryProvider
符合WMS规范的影像服务都可以通过该类封装,指定具体参数实现。
var provider = new Cesium.WebMapServiceImageryProvider({
url: "https://nationalmap.gov.au/proxy/http://geoserver.nationalmap.nicta.com.au/geotopo_250k/ows",
layers: "Hydrography:bores",
parameters: {
transparent: true,
format: "image/png",
},
});
imageryLayers.addImageryProvider(provider);
![](/docs/images/cesium/661.png)
WebMapTileServiceImageryProvider
服务WMTS1.0.0规范的影像服务,都可以通过该类实现,比如国内的天地图。
var shadedRelief1 = new Cesium.WebMapTileServiceImageryProvider({
url:
"https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/WMTS",
layer: "World_Imagery",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "default028mm",
maximumLevel: 23,
});
imageryLayers.addImageryProvider(shadedRelief1);
加载地形数据
Cesium中的地形图层类
前面我们主要学习了cesium内置接口如何操作影像数据,但是在一些应用场景中我们需要操作地形数据,例如模拟逼真的三维场景、与高程相关的一些空间分析和计算等。Cesium提供了TerrainProvider基类,该Provider负责每一个Tile对应的地形数据的构建,定义了一套地形Provider需要实现的接口和规范,但本身并不会参与其中的操作。基于此类,cesium为我们封装了5个现成的继承类操作地形数据:
![](/docs/images/cesium/663.png)
不像上一讲介绍的影像图层(有专门的ImageryLayer)那样,Cesium中的地形类是直接通过不同的terrainProvider控制的,然后把某一个实例化的terrainProvider赋值给Viewer.terrainProvider来控制地形数据的显隐。所以,Cesium中的地形图层只能有一个。
Cesium加载不同的地形数据
Cesium支持渐进流式加载和渲染全球高精度地形,并且包含海、湖、河等水面效果。相对2D地图,山峰、山谷等其他地形特征的更适宜在这种3D地球中展示。
Cesium支持两种类型的地形,STK World Terrain和Small Terrain。
针对于这两种类型的地形,这里不做过多的介绍,感兴趣的可参考cesiumjs开发实践(四) 地形介绍这篇文章。
地形数据集是巨大的,通常都是GB或者TB级别。在普通3D引擎中,使用底层图形API去高效实现地形数据的可视化需要做很多事情。幸好,Cesium已经完成了这个体力活,而我们只需要写几行代码,这些都是terrainProvider的功劳。下面我们主要介绍Cesium中常用的3个terrainProvider。
EllipsoidTerrainProvider
EllipsoidTerrainProvider是Globe默认采用的地形Provider,该Provider不支持水面,没有法向量,所以即使开启光照,对Tile也是无效的。但是它提供了一个全球范围内高度为0的地形,不需要额外的地形文件,就可以实时的自己来构建这个高度为0的Mesh。对那些没有网络环境,或网络不理想,或不需要地形的应用,EllipsoidTerrainProvider提供了最简单的,无需额外负担的地形数据来构网。
另外,EllipsoidTerrainProvider具有其他terrainProvider不具备的属性tileScheme,该属性是Provider内部地球网格的剖分方式,通常是WGS84坐标,也可以选择墨卡托坐标系。Cesium中目前支持WGS1984和墨卡托投影两种。
Terrain和Imagery分别采用自己的TileScheme,比如目前Terrain默认采用WGS1984的坐标系,这和经纬高的真实数据更接近,而目前Imagery影像服务基本都是墨卡托投影。
鉴于此,为了使数据的加载性能更好,可以让地形的TileScheme和影像的保持一致,都设置成墨卡托投影。
var ellipsoidProvider = new Cesium.EllipsoidTerrainProvider();
viewer.terrainProvider = ellipsoidProvider;
ArcGISTiledElevationTerrainProvider
ArcGIS的地形,这个可以说是一个真实的(凹凸的)高度图,原理和EllipsoidTerrainProvider如出一辙,因此同样的不支持法线,水面,但可以选择TileScheme,与EllipsoidTerrainProvider不一样之处在于每一个切片会根据ArcGIS规范请求一张图片,该图片中的像素对应的值就是该像素对应的高度,真的是名副其实的高度图。
var terrainProvider = new Cesium.ArcGISTiledElevationTerrainProvider({
url:
"https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer",
token:
"KED1aF_I4UzXOHy3BnhwyBHU4l5oY6rO6walkmHoYqGp4XyIWUd5YZUC1ZrLAzvV40pR6gBXQayh0eFA8m6vPg..",
});
viewer.terrainProvider = terrainProvider;
CesiumTerrainProvider
Cesium标准地形,在该Provider中支持两种地形格式,一种是高度图(目前Cesium已经废弃 ),另一种则是TIN网格的STK地形。
Cesium厉害的之处就在于目前采用STK的地形服务,并通过QuantizedMeshTerrainData封装了STK地形数据格式,它的优点是支持水面和法线,同时数据量比较小。
var terrainProvider = new Cesium.CesiumTerrainProvider({
url : Cesium.IonResource.fromAssetId(3956),
requestWaterMask: true, // 请求水体效果所需要的海岸线数据
requestVertexNormals: true, // 请求地形照明数据
});
viewer.terrainProvider = terrainProvider;
![](/docs/images/cesium/662.png)