注:Imagery可以翻译为图像、影像,这里就统一翻译为影像,不是特指卫星影像数据。
1.1、ImageryProvider类
Cesium.ImageryProvider类及其子类封装了加载各种影像图层的方法,其中Cesium.ImageryProvider类是抽象类、基类或者可将其理解为接口,它不能被直接实例化。
可以将ImageryProvider看作是影像图层的数据源,我们想使用哪种影像图层数据或服务就用对应的ImageryProvider子类去加载。
ImageryProvider类及其子类的体系结构:
1.2、ImageryLayer类
使用过桌面端GIS产品的同学都知道,一份GIS数据会被组织成图层符号化并渲染,数据相当于内在血液、内脏,信息量丰富,而图层相当于外在皮毛、衣服,用于呈现给外界。
Cesium同样将数据源组织成图层符号化并渲染,Cesium.ImageryLayer类就用于表示Cesium中的影像图层,它就相当于皮毛、衣服,将数据源包裹,它需要数据源为其提供内在丰富的地理空间信息和属性信息。
1.3、ImageryLayerCollection类
Cesium.ImageryLayerCollection类是ImageryLayer类对象的容器,它可以装载、放置多个ImageryLayer类对象,而且它内部放置的ImageryLayer类对象是有序的。
Cesium.Viewer类对象中包含的imageryLayers属性就是ImageryLayerCollection类的实例,它包含了当前Cesium应用程序所有的ImageryLayer类对象,即所有影像图层。
笔者最常用的数据就是OSM数据,不管是OSM的矢量数据还是瓦片地图服务,总之用得最勤,那就先来讲讲怎么在Cesium中加载OSM的影像服务。
直接使用OpenStreetMapImageryProvider类加载即可,几行代码就搞定!
html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>OSM影像图层</title>
<script src="https://cesium.com/downloads/cesiumjs/releases/1.65/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.65/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
<div id="cesium"></div>
<script>
// 初始化Cesium应用程序
const viewer = new Cesium.Viewer('cesium');
// 移除默认的影像图层
const imageryLayers = viewer.imageryLayers;
imageryLayers.remove(imageryLayers.get(0));
// 初始化OSM影像图层数据源
const osmImageryProvider = new Cesium.OpenStreetMapImageryProvider({
url : 'https://a.tile.openstreetmap.org/'
});
// 将OSM影像图层数据源组织为OSM影像图层
const osmImageryLayer = new Cesium.ImageryLayer(osmImageryProvider);
// 将OSM影像图层加入到影像图层容器中
imageryLayers.add(osmImageryLayer);
</script>
</body>
</html>
影像服务确切讲应该是指卫星影像数据,但是这里为了方便也叫影像服务,总之它就是瓦片地图。
XYZ方式就是根据瓦片服务的瓦片坐标系来加载对应瓦片,瓦片坐标系这里就不赘诉了,总之它有三个维度:
在Cesium中使用UrlTemplateImageryProvider类构建XYZ形式URL,去请求对应的影像瓦片。比如可以使用XYZ方式加载上面加载过的OSM影像服务:
html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>XYZ方式加载影像图层</title>
<script src="https://cesium.com/downloads/cesiumjs/releases/1.65/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.65/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
<div id="cesium"></div>
<script>
const viewer = new Cesium.Viewer('cesium');
const imageryLayers = viewer.imageryLayers;
imageryLayers.remove(imageryLayers.get(0));
// 使用XYZ方式加载OSM影像服务
const xyzImageryProvider = new Cesium.UrlTemplateImageryProvider({
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
subdomains: ['a', 'b', 'c']
});
// 将OSM影像数据源组织为OSM影像图层并加入到影像图层容器中
const xyzImageryLayer = new Cesium.ImageryLayer(xyzImageryProvider);
imageryLayers.add(xyzImageryLayer);
</script>
</body>
</html>
这里需要注意参数subdomains,它表示子域。subdomains参数数组中的四个值可以替换url中的{s},也就是改变不同的请求URL,从而提高加载数据的速度。
这就相当于四条道路一起分担人流和车流的压力。
使用XYZ方式加载的OSM影像图层:
微软旗下的必应地图(Bing Map)是收费的,所以在国内基本没人拿来当WebGIS“图层三明治“的底图,不过拿来写示例程序的时候使用还是蛮不错的!
在Cesium中加载Bing Map影像服务和上面加载OSM的影像服务一样简单,直接使用BingMapsImageryProvider类即可。
html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>加载Bing Map的影像服务</title>
<script src="https://cesium.com/downloads/cesiumjs/releases/1.65/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.65/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
<div id="cesium"></div>
<script>
const viewer = new Cesium.Viewer('cesium');
const imageryLayers = viewer.imageryLayers;
imageryLayers.remove(imageryLayers.get(0));
// 加载Bing Map影像服务
var bing = new Cesium.BingMapsImageryProvider({
url : 'https://dev.virtualearth.net',
key : 'Bing Map官方提供的个人Key',
mapStyle : Cesium.BingMapsStyle.AERIAL
});
const bingImageryLayer = new Cesium.ImageryLayer(bing);
imageryLayers.add(bingImageryLayer);
</script>
</body>
</html>
加载Bing Map影像服务需要个人的Key,上面的key参数就是应该填Bing Map官方提供的个人Key,可以直接去Bing Map的官网申请就好,只用于学习和个人用途是不收费的,如果商用就要收费了。
mapStyle这个参数用于指定加载哪种用途,或者说哪种类型的影像服务吧,查看Cesium的官方文档知道可以指定为如下参数:
总之这些不同的影像服务就是是否有路网、是否有注记之类的区别,挑选合适的使用就好了。
Cesium自家的Cesium Ion中也包含了许多影像服务,我们同样可以加载它们。
html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>加载Cesium Ion中的影像服务</title>
<script src="http://localhost:8080/cesium/Cesium/Cesium.js"></script>
<link href="http://localhost:8080/cesium/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
<div id="cesium"></div>
<script>
Cesium.Ion.defaultAccessToken = 'Cesium Ion的个人访问Token';
const viewer = new Cesium.Viewer('cesium');
const imageryLayers = viewer.imageryLayers;
// 加载Cesium Ion中asset ID为3812的影像服务
const ionImageryProvider_3812 = new Cesium.IonImageryProvider({
assetId: 3812
});
// 将影像数据源组织为影像图层
const blackMarbleLayer = new Cesium.ImageryLayer(ionImageryProvider_3812, {
alpha: 0.5,
brightness: 2.0
});
imageryLayers.add(blackMarbleLayer);
</script>
</body>
</html>
想加载Cesium Ion中的某个影像服务,只需要在参数assetId填上对应的asset Id即可。
本文作者:烈焰大火龙
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 © 烈焰大火龙 许可协议。转载请注明出处!