cesium.js入门基础教程二 (影像和标注)
影像简介
Cesium加载大的虚拟地球默认是有影像的,如图:
默认使用的影像是 “Bing Maps Aerial”:
影像提供者 ImageryProvider
除了途中列出的一些影像,开发者可以通过Cesium中的ImagerProvider影像提供者类创建所需的影像,Cesium中提供了很多种ImageryProvider
影像提供类(不包括抽象类ImageryProvider
):
加载图层影像的方法
- 在初始化viwer的时候添加
- 通过
viwer.imageryLayers.addImageryProvider
方法添加
初始化时添加影像
在初始化Viewer
时可在第二个参数Viewer.ConstructorOptions
中添加imageryProvider
属性并提供一个ImageryProvider
对象:
const viewer = new Cesium.Viewer("cesiumContainer", {
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
})
})
注意:使用这种方法添加影像图层只能添加一个
使用addImageryProvider方法添加
使用viewer.imageryLayers.addImageryProvider
方法,顾名思义需要传入一个ImageryProvider
对象:
const ArcGisImagery = viewer.imageryLayers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
}))
影像提供者示例
由于国外的影像地图服务往往拍摄生成的年份比较早,因此很多地区的影像和实际出入较大,所以推荐使用国内的影像服务
ArcGisMapServerImageryProvider
加载Arcgis影像服务的代码如下:
const viewer = new Cesium.Viewer("cesiumContainer", {
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url : 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
})
})
加载后的效果如下:
BingMapsImageryProvider
加载Bing影像服务的代码,其中key
属性需要在bing maps dev center中申请,按照页面提示申请即可:
viewer.imageryProvider = new Cesium.BingMapsImageryProvider({
url: 'https://dev.virtualearth.net',
key: 'xxx',
mapStyle : Cesium.BingMapsStyle.AERIAL
})
加载后的效果如下:
其他地图服务加载方式基本与例子大同小异。
影像图层
影像叠加
在Cesium中可以将多个影像都加载到虚拟地球上,如下面代码中加载了Arcgis的影像服务和切片Tile坐标两种影像:
const viewer = new Cesium.Viewer("cesiumContainer", {
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
})
})
viewer.imageryLayers.addImageryProvider(new Cesium.TileCoordinatesImageryProvider())
影像图层:
每一个加载到Cesium中的ImageryProvider
都属于ImageryLayer
类所实例化的对象,以上面的代码为例,可以在浏览器控制台中输出viewer.scene.imageryLayers
:
发现属性_layers
为一个数组,其内容为添加的两个影像,正好对应了例子中添加的Arcgis影像服务和切片Tile坐标两种影像。
ImageryLayer的属性
通过ImageryLayer
实例化对象可以修改影像的外观属性,常见的可修改属性见下表:
属性含义 | 属性名称 | 默认值 |
---|---|---|
透明度 | aplpha |
1.0 |
明亮值 | brightness |
1.0 |
对比度 | contrast |
1.0 |
色调 | hue |
0.0 |
饱和度 | saturation |
1.0 |
伽马值 | gamma |
1.0 |
在下面这个例子中,通过viewer.imageryLayers._layers[0]获取到的第一个影像图层,即Arcgis影像图层,在修改其alpha
、brightness
和contrast
属性对其影像的透明度、明亮度和对比度等属性进行修改:
const viewer = new Cesium.Viewer("cesiumContainer", {
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
})
})
// 修改影像的透明度、明亮度和对比度
viewer.imageryLayers._layers[0].alpha = 0.5
viewer.imageryLayers._layers[0].brightness = 2
viewer.imageryLayers._layers[0].contrast = 3
影像集合 ImageryLayerCollection
上边说到,影像是可以叠加的,输出viewer.imageryLayers能看到叠加的多个影像图层,当需要修改某个影像的属性的时候,上一节是使用如下方式:
// 修改影像的透明度、明亮度和对比度
viewer.imageryLayers._layers[0].alpha = 0.5
viewer.imageryLayers._layers[0].brightness = 2
viewer.imageryLayers._layers[0].contrast = 3
上边代码是通过_layers[0]
获取到某个影像图层的,显然这种方法的语义化和可读性都是欠缺的。
因此需要一个实例对象来管理所有图层,能够以简单且语义化明确的接口来访问和操作影像图层,这个实例对象就是ImageryLayerCollection
其实在上一节已经出现过ImageryLayerCollection
,viewer.imageryLayers
本身就是一个ImageryLayerCollection
对象:
ImageryLayerCollection的方法:
ImageryLayerCollection
对象有如下常用的方法:
方法名 | 参数 | 作用 |
---|---|---|
containes |
影像图层ImageryLayer |
判断某一个ImageryLayer 是否在ImageryLayerCollection 中,返回true 或false |
get |
数字类型下标index |
根据下标在ImageryLayerCollection 中获取ImageryLayer |
indexOf |
影像图层ImageryLayer |
根据ImageryLayer 获取其在ImageryLayerCollection 中的下标,若不存在则返回-1 |
lower |
影像图层ImageryLayer |
将ImageryLayer的叠加顺序向后移一位 |
lowerToBottom |
影像图层ImageryLayer |
将ImageryLayer 的叠加顺序移到最后一位 |
raise |
影像图层ImageryLayer |
将ImageryLayer 的叠加顺序向前移一位 |
raiseToTop |
影像图层ImageryLayer |
将ImageryLayer 的叠加顺序移到首位 |
使用方法如下:
const viewer = new Cesium.Viewer("cesiumContainer")
// 创建两个影像图层
const TileImagery = viewer.imageryLayers.addImageryProvider(new Cesium.TileCoordinatesImageryProvider())
const ArcGisImagery = viewer.imageryLayers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
}))
// 判断ArcGisImagery是否在ImageryLayerCollection中
const isContains = viewer.imageryLayers.contains(ArcGisImagery)
// 获取ImageryLayerCollection中的第二个影像图层
const getImagery = viewer.imageryLayers.get(1)
// 获取TileImagery在ImageryLayerCollection中的下标
const index = viewer.imageryLayers.indexOf(TileImagery)
// 将ArcGisImagery的叠加顺序向后移一位
viewer.imageryLayers.lower(ArcGisImagery)
// 将ArcGisImagery的叠加顺序移到最后一位
viewer.imageryLayers.lowerToBottom(ArcGisImagery)
// 将TileImagery的叠加顺序向前移一位
viewer.imageryLayers.raise(TileImagery)
// 将TileImagery的叠加顺序移到首位
viewer.imageryLayers.raiseToTop(TileImagery)
标注
高德地图标注
加载高德地图标注的代码如下:
viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({
url: "http://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",
}))
加载后的效果如下:
天地图标注
const tdtToekn = 'xxx'
viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({
url: `http://t0.tianditu.com/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=${tdtToekn}`,
layer: "tdtAnnoLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible",
}))
加载后的效果: