第08章 - 影像图层与地图服务
第08章:影像图层与地图服务
8.1 影像图层概述
8.1.1 ImageryLayer 架构
CesiumJS 支持多种影像数据源,通过 ImageryLayer 和 ImageryProvider 进行管理:
┌─────────────────────────────────────────────────────────────────┐
│ 影像图层架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ImageryLayerCollection (影像图层集合) │
│ └── ImageryLayer (影像图层) │
│ ├── ImageryProvider (影像提供者) │
│ │ ├── 请求瓦片 │
│ │ ├── 解码图片 │
│ │ └── 提供元数据 │
│ │ │
│ └── 图层属性 │
│ ├── alpha (透明度) │
│ ├── brightness (亮度) │
│ ├── contrast (对比度) │
│ ├── hue (色调) │
│ └── saturation (饱和度) │
│ │
└─────────────────────────────────────────────────────────────────┘
8.1.2 支持的影像服务类型
| 类型 | Provider 类 | 描述 |
|---|---|---|
| Cesium Ion | IonImageryProvider | Cesium 官方云服务 |
| OpenStreetMap | OpenStreetMapImageryProvider | 开放街图 |
| Bing Maps | BingMapsImageryProvider | 微软地图 |
| ArcGIS | ArcGisMapServerImageryProvider | Esri 地图服务 |
| WMS | WebMapServiceImageryProvider | OGC WMS 服务 |
| WMTS | WebMapTileServiceImageryProvider | OGC WMTS 服务 |
| TMS | TileMapServiceImageryProvider | 瓦片地图服务 |
| URL Template | UrlTemplateImageryProvider | 自定义 URL 模板 |
| Single Tile | SingleTileImageryProvider | 单张图片 |
| Google Earth | GoogleEarthEnterpriseImageryProvider | Google 企业版 |
| Mapbox | MapboxImageryProvider | Mapbox 地图 |
8.2 内置影像提供者
8.2.1 Cesium Ion 影像
// Cesium World Imagery(默认卫星影像)
const worldImagery = await Cesium.createWorldImageryAsync();
viewer.imageryLayers.addImageryProvider(worldImagery);
// 指定样式
const aerialImagery = await Cesium.createWorldImageryAsync({
style: Cesium.IonWorldImageryStyle.AERIAL // 航空影像
});
const aerialWithLabels = await Cesium.createWorldImageryAsync({
style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS // 带标签
});
const road = await Cesium.createWorldImageryAsync({
style: Cesium.IonWorldImageryStyle.ROAD // 道路图
});
// 自定义 Ion 资源
const customIonImagery = await Cesium.IonImageryProvider.fromAssetId(3954);
viewer.imageryLayers.addImageryProvider(customIonImagery);
8.2.2 OpenStreetMap
// 基本 OpenStreetMap
const osmImagery = new Cesium.OpenStreetMapImageryProvider({
url: 'https://tile.openstreetmap.org/'
});
viewer.imageryLayers.addImageryProvider(osmImagery);
// 自定义 OSM 服务器
const customOsm = new Cesium.OpenStreetMapImageryProvider({
url: 'https://a.tile.openstreetmap.org/',
maximumLevel: 19,
credit: 'OpenStreetMap contributors'
});
8.2.3 Bing Maps
// Bing Maps 航空影像
const bingAerial = await Cesium.BingMapsImageryProvider.fromUrl(
'https://dev.virtualearth.net',
{
key: 'YOUR_BING_MAPS_KEY',
mapStyle: Cesium.BingMapsStyle.AERIAL
}
);
viewer.imageryLayers.addImageryProvider(bingAerial);
// 其他样式
const bingStyles = {
AERIAL: Cesium.BingMapsStyle.AERIAL, // 航空
AERIAL_WITH_LABELS: Cesium.BingMapsStyle.AERIAL_WITH_LABELS, // 航空带标签
AERIAL_WITH_LABELS_ON_DEMAND: Cesium.BingMapsStyle.AERIAL_WITH_LABELS_ON_DEMAND,
ROAD: Cesium.BingMapsStyle.ROAD, // 道路
ROAD_ON_DEMAND: Cesium.BingMapsStyle.ROAD_ON_DEMAND,
CANVAS_DARK: Cesium.BingMapsStyle.CANVAS_DARK, // 深色
CANVAS_LIGHT: Cesium.BingMapsStyle.CANVAS_LIGHT, // 浅色
CANVAS_GRAY: Cesium.BingMapsStyle.CANVAS_GRAY, // 灰色
ORDNANCE_SURVEY: Cesium.BingMapsStyle.ORDNANCE_SURVEY, // 英国测绘
COLLINS_BART: Cesium.BingMapsStyle.COLLINS_BART // 柯林斯
};
8.2.4 ArcGIS MapServer
// ArcGIS World Imagery
const arcgisImagery = await Cesium.ArcGisMapServerImageryProvider.fromUrl(
'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
);
viewer.imageryLayers.addImageryProvider(arcgisImagery);
// ArcGIS World Street Map
const arcgisStreet = await Cesium.ArcGisMapServerImageryProvider.fromUrl(
'https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
);
// ArcGIS World Topo Map
const arcgisTopo = await Cesium.ArcGisMapServerImageryProvider.fromUrl(
'https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer'
);
// 自定义 ArcGIS 服务
const customArcgis = await Cesium.ArcGisMapServerImageryProvider.fromUrl(
'https://your-arcgis-server/arcgis/rest/services/YourService/MapServer',
{
token: 'YOUR_ARCGIS_TOKEN', // 如果需要认证
layers: '0,1,2', // 指定图层
enablePickFeatures: true // 启用要素拾取
}
);
8.3 OGC 标准服务
8.3.1 WMS(Web Map Service)
// 基本 WMS
const wmsImagery = new Cesium.WebMapServiceImageryProvider({
url: 'https://your-wms-server/wms',
layers: 'layer_name',
parameters: {
service: 'WMS',
format: 'image/png',
transparent: true
}
});
viewer.imageryLayers.addImageryProvider(wmsImagery);
// 完整配置
const advancedWms = new Cesium.WebMapServiceImageryProvider({
url: 'https://your-wms-server/wms',
layers: 'layer1,layer2', // 多图层
// WMS 参数
parameters: {
service: 'WMS',
version: '1.1.1', // 或 1.3.0
request: 'GetMap',
format: 'image/png',
transparent: true,
styles: '', // 样式
srs: 'EPSG:4326', // 坐标系(1.1.1用srs)
// crs: 'EPSG:4326', // 坐标系(1.3.0用crs)
bgcolor: '0xFFFFFF', // 背景色
exceptions: 'application/vnd.ogc.se_xml'
},
// Cesium 配置
minimumLevel: 0,
maximumLevel: 18,
// 瓦片配置
tileWidth: 256,
tileHeight: 256,
// 时间维度(如果支持)
times: undefined,
// 子域(负载均衡)
subdomains: ['a', 'b', 'c'],
// 信用信息
credit: 'Data from WMS Server',
// 拾取功能
enablePickFeatures: true,
getFeatureInfoFormats: [
new Cesium.GetFeatureInfoFormat('json', 'application/json'),
new Cesium.GetFeatureInfoFormat('xml', 'application/vnd.ogc.gml')
]
});
// 带时间维度的 WMS
const timeWms = new Cesium.WebMapServiceImageryProvider({
url: 'https://your-wms-server/wms',
layers: 'time_layer',
parameters: {
format: 'image/png',
transparent: true,
time: '2024-01-01T00:00:00Z' // 时间参数
}
});
// 动态更新时间
viewer.clock.onTick.addEventListener(function(clock) {
const isoTime = Cesium.JulianDate.toIso8601(clock.currentTime);
// 需要重新创建 provider 或使用其他方式更新
});
8.3.2 WMTS(Web Map Tile Service)
// 基本 WMTS
const wmtsImagery = new Cesium.WebMapTileServiceImageryProvider({
url: 'https://your-wmts-server/wmts',
layer: 'layer_name',
style: 'default',
tileMatrixSetID: 'EPSG:4326',
format: 'image/png'
});
viewer.imageryLayers.addImageryProvider(wmtsImagery);
// 完整配置
const advancedWmts = new Cesium.WebMapTileServiceImageryProvider({
url: 'https://your-wmts-server/wmts',
layer: 'layer_name',
style: 'default',
tileMatrixSetID: 'GoogleMapsCompatible', // 或 EPSG:3857, EPSG:4326
format: 'image/png',
// 瓦片矩阵配置
tileMatrixLabels: undefined, // 自定义级别标签
// 范围限制
rectangle: Cesium.Rectangle.fromDegrees(73, 3, 135, 54), // 中国范围
// 级别限制
minimumLevel: 0,
maximumLevel: 18,
// 时间维度
times: undefined,
// 子域
subdomains: ['a', 'b', 'c'],
// 信用
credit: 'WMTS Data'
});
// 天地图 WMTS 示例
const tiandituImagery = new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t{s}.tianditu.gov.cn/img_w/wmts?tk=YOUR_TIANDITU_KEY',
layer: 'img',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
maximumLevel: 18
});
// 天地图注记图层
const tiandituLabel = new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t{s}.tianditu.gov.cn/cia_w/wmts?tk=YOUR_TIANDITU_KEY',
layer: 'cia',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
maximumLevel: 18
});
8.3.3 TMS(Tile Map Service)
// 基本 TMS
const tmsImagery = await Cesium.TileMapServiceImageryProvider.fromUrl(
'https://your-tms-server/tiles/',
{
fileExtension: 'png'
}
);
viewer.imageryLayers.addImageryProvider(tmsImagery);
// 完整配置
const advancedTms = await Cesium.TileMapServiceImageryProvider.fromUrl(
'https://your-tms-server/tiles/',
{
fileExtension: 'png',
// 级别范围
minimumLevel: 0,
maximumLevel: 18,
// 地理范围
rectangle: Cesium.Rectangle.fromDegrees(-180, -90, 180, 90),
// 瓦片大小
tileWidth: 256,
tileHeight: 256,
// 翻转 Y 轴(某些 TMS 需要)
flipXY: false,
// 信用
credit: 'TMS Data'
}
);
8.4 自定义影像源
8.4.1 UrlTemplateImageryProvider
// 使用 URL 模板
const urlTemplateImagery = new Cesium.UrlTemplateImageryProvider({
url: 'https://your-server/{z}/{x}/{y}.png',
// 或使用函数
// url: function(x, y, level) {
// return `https://your-server/${level}/${x}/${y}.png`;
// },
minimumLevel: 0,
maximumLevel: 18,
// 子域
subdomains: ['a', 'b', 'c'],
// 范围
rectangle: Cesium.Rectangle.fromDegrees(-180, -90, 180, 90),
// 瓦片大小
tileWidth: 256,
tileHeight: 256,
// 是否有 Alpha 通道
hasAlphaChannel: true,
// 信用
credit: 'Custom Tiles'
});
// 高德地图示例
const amapImagery = new Cesium.UrlTemplateImageryProvider({
url: 'https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
subdomains: ['1', '2', '3', '4'],
maximumLevel: 18
});
// 高德路网图层
const amapRoad = new Cesium.UrlTemplateImageryProvider({
url: 'https://webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}',
subdomains: ['1', '2', '3', '4'],
maximumLevel: 18
});
// 腾讯地图示例
function getTencentUrl(x, y, level) {
const y_t = Math.pow(2, level) - 1 - y;
const m = Math.floor(x / 16);
const n = Math.floor(y_t / 16);
return `https://p2.map.gtimg.com/sateTiles/${level}/${m}/${n}/${x}_${y_t}.jpg`;
}
const tencentImagery = new Cesium.UrlTemplateImageryProvider({
url: getTencentUrl,
minimumLevel: 0,
maximumLevel: 18
});
8.4.2 SingleTileImageryProvider
// 单张图片
const singleTileImagery = new Cesium.SingleTileImageryProvider({
url: 'https://example.com/map.png',
rectangle: Cesium.Rectangle.fromDegrees(116, 39, 117, 40)
});
viewer.imageryLayers.addImageryProvider(singleTileImagery);
// 带透明通道的图片
const overlayImage = new Cesium.SingleTileImageryProvider({
url: 'overlay.png',
rectangle: Cesium.Rectangle.fromDegrees(115.5, 38.5, 116.5, 39.5)
});
const overlayLayer = viewer.imageryLayers.addImageryProvider(overlayImage);
overlayLayer.alpha = 0.7;
8.4.3 自定义 ImageryProvider
// 自定义影像提供者
class CustomImageryProvider {
constructor(options) {
this._tilingScheme = new Cesium.GeographicTilingScheme();
this._tileWidth = 256;
this._tileHeight = 256;
this._minimumLevel = options.minimumLevel || 0;
this._maximumLevel = options.maximumLevel || 18;
this._rectangle = Cesium.Rectangle.MAX_VALUE;
this._credit = new Cesium.Credit(options.credit || 'Custom Provider');
this._hasAlphaChannel = true;
this._ready = true;
this._baseUrl = options.url;
}
get tilingScheme() { return this._tilingScheme; }
get tileWidth() { return this._tileWidth; }
get tileHeight() { return this._tileHeight; }
get minimumLevel() { return this._minimumLevel; }
get maximumLevel() { return this._maximumLevel; }
get rectangle() { return this._rectangle; }
get credit() { return this._credit; }
get hasAlphaChannel() { return this._hasAlphaChannel; }
get ready() { return this._ready; }
getTileCredits(x, y, level) {
return undefined;
}
requestImage(x, y, level, request) {
const url = `${this._baseUrl}/${level}/${x}/${y}.png`;
return Cesium.ImageryProvider.loadImage(this, url);
}
pickFeatures(x, y, level, longitude, latitude) {
return undefined;
}
}
// 使用自定义提供者
const customProvider = new CustomImageryProvider({
url: 'https://your-server/tiles',
minimumLevel: 0,
maximumLevel: 18,
credit: 'My Custom Tiles'
});
viewer.imageryLayers.addImageryProvider(customProvider);
8.5 图层管理
8.5.1 ImageryLayerCollection 操作
const imageryLayers = viewer.imageryLayers;
// ===== 添加图层 =====
const layer = imageryLayers.addImageryProvider(provider);
const layerAtIndex = imageryLayers.addImageryProvider(provider, 0);
// ===== 移除图层 =====
imageryLayers.remove(layer);
imageryLayers.remove(layer, true); // 移除并销毁
imageryLayers.removeAll();
imageryLayers.removeAll(true); // 移除并销毁所有
// ===== 获取图层 =====
const length = imageryLayers.length;
const layerAt = imageryLayers.get(0);
const indexOf = imageryLayers.indexOf(layer);
const contains = imageryLayers.contains(layer);
// ===== 调整顺序 =====
imageryLayers.raise(layer); // 上移一层
imageryLayers.lower(layer); // 下移一层
imageryLayers.raiseToTop(layer); // 移到顶层
imageryLayers.lowerToBottom(layer); // 移到底层
// ===== 事件监听 =====
imageryLayers.layerAdded.addEventListener(function(layer, index) {
console.log('图层添加:', index);
});
imageryLayers.layerRemoved.addEventListener(function(layer, index) {
console.log('图层移除:', index);
});
imageryLayers.layerMoved.addEventListener(function(layer, newIndex, oldIndex) {
console.log('图层移动:', oldIndex, '->', newIndex);
});
imageryLayers.layerShownOrHidden.addEventListener(function(layer, index, show) {
console.log('图层显示/隐藏:', index, show);
});
8.5.2 ImageryLayer 属性
const layer = viewer.imageryLayers.addImageryProvider(provider);
// ===== 显示控制 =====
layer.show = true; // 显示/隐藏
// ===== 透明度 =====
layer.alpha = 1.0; // 透明度 (0-1)
// ===== 颜色调整 =====
layer.brightness = 1.0; // 亮度 (0-2, 默认1)
layer.contrast = 1.0; // 对比度 (0-2, 默认1)
layer.hue = 0.0; // 色调 (-1 到 1, 默认0)
layer.saturation = 1.0; // 饱和度 (0-2, 默认1)
layer.gamma = 1.0; // 伽马 (0.1-4, 默认1)
// ===== 滤镜 =====
layer.minificationFilter = Cesium.TextureMinificationFilter.LINEAR;
layer.magnificationFilter = Cesium.TextureMagnificationFilter.LINEAR;
// ===== 分割线显示 =====
layer.splitDirection = Cesium.SplitDirection.NONE;
// Cesium.SplitDirection.LEFT // 左侧显示
// Cesium.SplitDirection.RIGHT // 右侧显示
// ===== 夜间图层 =====
layer.nightAlpha = 1.0; // 夜间透明度
layer.dayAlpha = 1.0; // 白天透明度
// ===== 裁剪 =====
layer.cutoutRectangle = Cesium.Rectangle.fromDegrees(116, 39, 117, 40);
// ===== 颜色转换 =====
layer.colorToAlpha = new Cesium.Color(0, 0, 0, 1); // 将指定颜色转为透明
layer.colorToAlphaThreshold = 0.004;
8.5.3 图层管理器
// 影像图层管理器
class ImageryLayerManager {
constructor(viewer) {
this.viewer = viewer;
this.layers = new Map();
}
// 添加图层
async addLayer(name, provider, options = {}) {
const layer = this.viewer.imageryLayers.addImageryProvider(provider, options.index);
if (options.alpha !== undefined) layer.alpha = options.alpha;
if (options.brightness !== undefined) layer.brightness = options.brightness;
if (options.contrast !== undefined) layer.contrast = options.contrast;
if (options.show !== undefined) layer.show = options.show;
this.layers.set(name, { layer, provider, options });
return layer;
}
// 获取图层
getLayer(name) {
const info = this.layers.get(name);
return info ? info.layer : null;
}
// 设置可见性
setVisible(name, visible) {
const layer = this.getLayer(name);
if (layer) layer.show = visible;
}
// 设置透明度
setAlpha(name, alpha) {
const layer = this.getLayer(name);
if (layer) layer.alpha = alpha;
}
// 移除图层
removeLayer(name) {
const info = this.layers.get(name);
if (info) {
this.viewer.imageryLayers.remove(info.layer, true);
this.layers.delete(name);
return true;
}
return false;
}
// 切换底图
switchBaseLayer(name) {
// 隐藏所有底图
this.layers.forEach((info, layerName) => {
if (info.options.isBaseLayer) {
info.layer.show = (layerName === name);
}
});
}
// 获取所有图层名称
getLayerNames() {
return Array.from(this.layers.keys());
}
// 清除所有图层
clear() {
this.layers.forEach(info => {
this.viewer.imageryLayers.remove(info.layer, true);
});
this.layers.clear();
}
}
// 使用示例
const layerManager = new ImageryLayerManager(viewer);
// 添加底图
await layerManager.addLayer('osm', new Cesium.OpenStreetMapImageryProvider({
url: 'https://tile.openstreetmap.org/'
}), { isBaseLayer: true });
await layerManager.addLayer('satellite', await Cesium.createWorldImageryAsync(),
{ isBaseLayer: true, show: false });
// 添加叠加图层
await layerManager.addLayer('overlay', overlayProvider,
{ alpha: 0.7, isBaseLayer: false });
// 切换底图
layerManager.switchBaseLayer('satellite');
8.6 要素拾取
8.6.1 WMS GetFeatureInfo
// 启用 WMS 要素拾取
const wmsWithPick = new Cesium.WebMapServiceImageryProvider({
url: 'https://your-wms-server/wms',
layers: 'layer_name',
parameters: {
format: 'image/png',
transparent: true
},
enablePickFeatures: true,
getFeatureInfoFormats: [
new Cesium.GetFeatureInfoFormat('json', 'application/json'),
new Cesium.GetFeatureInfoFormat('xml', 'text/xml')
]
});
// 监听点击事件并获取要素信息
const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(async function(click) {
const pickedPosition = viewer.scene.pickPosition(click.position);
if (Cesium.defined(pickedPosition)) {
const cartographic = Cesium.Cartographic.fromCartesian(pickedPosition);
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
// 获取可见图层
const imageryLayers = viewer.imageryLayers;
for (let i = 0; i < imageryLayers.length; i++) {
const layer = imageryLayers.get(i);
if (layer.show && layer.imageryProvider.enablePickFeatures) {
const features = await layer.imageryProvider.pickFeatures(
click.position.x,
click.position.y,
viewer.scene.globe.ellipsoid,
cartographic
);
if (features && features.length > 0) {
console.log('拾取的要素:', features);
// 显示要素信息
displayFeatureInfo(features);
}
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
function displayFeatureInfo(features) {
features.forEach(feature => {
console.log('要素名称:', feature.name);
console.log('要素描述:', feature.description);
console.log('要素属性:', feature.properties);
});
}
8.7 本章小结
本章详细介绍了影像图层与地图服务:
- 影像架构:ImageryLayer、ImageryProvider 结构
- 内置提供者:Cesium Ion、OSM、Bing、ArcGIS
- OGC 服务:WMS、WMTS、TMS 配置
- 自定义影像:URL 模板、单张图片、自定义 Provider
- 图层管理:添加、移除、排序、属性调整
- 要素拾取:GetFeatureInfo 功能
在下一章中,我们将详细介绍地形数据处理。
8.8 思考与练习
- 实现一个底图切换控件,支持多种地图源。
- 添加天地图影像和注记图层。
- 实现图层透明度和亮度的动态调整。
- 开发 WMS 要素查询功能。
- 创建自定义影像提供者,加载本地瓦片。

浙公网安备 33010602011771号