G
Q
Q
and
M
E

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影像图层,在修改其alphabrightnesscontrast属性对其影像的透明度、明亮度和对比度等属性进行修改:

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

其实在上一节已经出现过ImageryLayerCollectionviewer.imageryLayers本身就是一个ImageryLayerCollection对象:

ImageryLayerCollection的方法:

ImageryLayerCollection对象有如下常用的方法:

方法名 参数 作用
containes 影像图层ImageryLayer 判断某一个ImageryLayer是否在ImageryLayerCollection中,返回truefalse
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",
}))

加载后的效果:

posted @ 2023-12-13 13:30  sy0313  阅读(516)  评论(0编辑  收藏  举报