本文将系统比较 Cesium 和 OpenLayers 两大主流 WebGIS 库,涵盖它们的架构差异、加载地图服务的方法、参数配置以及适用场景,帮助你在项目中做出合适的选择。

📋 目录

核心概念对比

Cesium vs OpenLayers 的定位差异

维度 Cesium OpenLayers
核心定位 3D 地球可视化引擎 2D/2.5D 地图库
渲染方式 WebGL(3D 球体) Canvas/SVG(平面地图)
适用场景 三维地形、建筑模型、全球尺度 二维地图、矢量数据、局部区域
坐标系 默认 WGS84(经纬度) 支持多种投影(EPSG:3857、EPSG:4326 等)
学习曲线 较陡峭 相对平缓

Cesium 加载地图服务方法

1. 影像图层(ImageryLayer)

(1) XYZ/TMS 瓦片服务

1
2
3
4
5
6
7
8
9
10
11
// 最常见的瓦片服务,URL 中包含 {x}, {y}, {z} 占位符
const imageryProvider = new Cesium.UrlTemplateImageryProvider({
url: 'https://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=你的token',
subdomains: ['0', '1', '2', '3'], // 负载均衡的子域名
tilingScheme: new Cesium.WebMercatorTilingScheme(), // 墨卡托投影
maximumLevel: 18, // 最大缩放级别
minimumLevel: 1, // 最小缩放级别
credit: '天地图' // 版权信息
})

viewer.imageryLayers.addImageryProvider(imageryProvider)

关键参数说明:

  • url: 瓦片服务地址,{x} 列号、{y} 行号、{z} 缩放级别、{s} 子域名
  • subdomains: 多个服务器域名,分散请求压力
  • tilingScheme: 切片方案(WebMercatorTilingScheme 或 GeographicTilingScheme)
  • maximumLevel/minimumLevel: 控制加载的缩放范围

(2) WMTS 服务(OGC 标准)

1
2
3
4
5
6
7
8
9
10
11
12
const wmtsProvider = new Cesium.WebMapTileServiceImageryProvider({
url: 'http://localhost:8080/geoserver/gwc/service/wmts',
layer: 'workspace:layername', // 图层名称
style: '', // 样式名称
format: 'image/png', // 图片格式
tileMatrixSetID: 'EPSG:3857', // 矩阵集标识
tileMatrixLabels: ['EPSG:3857:0', 'EPSG:3857:1', ...], // 每级矩阵标签
maximumLevel: 18,
credit: 'GeoServer WMTS'
})

viewer.imageryLayers.addImageryProvider(wmtsProvider)

关键参数说明:

  • layer: GeoServer 或其他 WMTS 服务的图层名
  • style: 渲染样式(通常为空字符串)
  • format: 返回图片格式(png/jpeg/webp)
  • tileMatrixSetID: 坐标参考系统的矩阵集
  • tileMatrixLabels: 每个缩放级别的矩阵标识符数组

(3) WMS 服务(动态渲染)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const wmsProvider = new Cesium.WebMapServiceImageryProvider({
url: 'http://localhost:8080/geoserver/wms',
layers: 'workspace:layername', // 图层名称
parameters: {
service: 'WMS',
version: '1.1.1',
request: 'GetMap',
styles: '',
format: 'image/png',
transparent: true, // 透明背景
srs: 'EPSG:4326' // 坐标系
},
maximumLevel: 18
})

viewer.imageryLayers.addImageryProvider(wmsProvider)

关键参数说明:

  • layers: 要显示的图层(可多个,用逗号分隔)
  • parameters: WMS 请求参数,符合 OGC 标准
  • transparent: 是否透明(叠加图层时常用)
  • WMS 是动态生成图片,每次缩放/平移都会重新请求

(4) 单张图片(SingleTile)

1
2
3
4
5
6
7
8
9
10
11
12
// 适用于静态大图,如卫星云图、示意图
const singleTileProvider = new Cesium.SingleTileImageryProvider({
url: '/images/cloud.png',
rectangle: Cesium.Rectangle.fromDegrees(
73.0, // 西边界(经度)
18.0, // 南边界(纬度)
135.0, // 东边界(经度)
54.0 // 北边界(纬度)
)
})

viewer.imageryLayers.addImageryProvider(singleTileProvider)

关键参数说明:

  • rectangle: 图片覆盖的地理范围(WGS84 经纬度)
  • 适合非瓦片化的静态图像

(5) ArcGIS 服务

1
2
3
4
5
6
7
const arcgisProvider = new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer',
layers: '0', // 可选:指定子图层
enablePickFeatures: false // 禁用要素查询提升性能
})

viewer.imageryLayers.addImageryProvider(arcgisProvider)

2. 地形图层(TerrainProvider)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// (1) Cesium Ion 全球地形
viewer.terrainProvider = Cesium.createWorldTerrain({
requestWaterMask: true, // 请求水体遮罩
requestVertexNormals: true // 请求法线(用于光照效果)
})

// (2) 自定义地形服务
const terrainProvider = new Cesium.CesiumTerrainProvider({
url: 'http://localhost:8080/terrain',
requestWaterMask: true,
requestVertexNormals: true
})

viewer.terrainProvider = terrainProvider

// (3) 平坦地形(无起伏)
viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider()

3. 3D Tiles(倾斜摄影/建筑模型)

1
2
3
4
5
6
7
8
9
10
const tileset = await Cesium.Cesium3DTileset.fromUrl(
'http://localhost:8080/3dtiles/tileset.json'
)

viewer.scene.primitives.add(tileset)

// 调整位置
tileset.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(116.39, 39.9, 0)
)

OpenLayers 加载地图服务方法

1. XYZ/TMS 瓦片服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import XYZ from 'ol/source/XYZ'
import TileLayer from 'ol/layer/Tile'

const xyzLayer = new TileLayer({
source: new XYZ({
url: 'https://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=token',
subdomains: ['0', '1', '2', '3'],
maxZoom: 18,
minZoom: 1,
crossOrigin: 'anonymous' // 跨域设置
})
})

map.addLayer(xyzLayer)

关键参数说明:

  • url: 同 Cesium,支持 {x}, {y}, {z}, {-y}(TMS 标准)
  • maxZoom/minZoom: 缩放级别限制
  • crossOrigin: 处理跨域图片(’anonymous’ 或 ‘use-credentials’)

2. WMTS 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import WMTS from 'ol/source/WMTS'
import WMTSTileGrid from 'ol/tilegrid/WMTS'
import TileLayer from 'ol/layer/Tile'

const wmtsLayer = new TileLayer({
source: new WMTS({
url: 'http://localhost:8080/geoserver/gwc/service/wmts',
layer: 'workspace:layername',
matrixSet: 'EPSG:3857',
format: 'image/png',
projection: 'EPSG:3857',
tileGrid: new WMTSTileGrid({
origin: [-20037508.34, 20037508.34], // 原点
resolutions: [156543.03, 78271.52, ...], // 每级分辨率
matrixIds: ['EPSG:3857:0', 'EPSG:3857:1', ...]
}),
style: '',
wrapX: true // 水平方向重复
})
})

map.addLayer(wmtsLayer)

关键参数说明:

  • matrixSet: 矩阵集名称
  • tileGrid: 必须手动配置瓦片网格(比 Cesium 复杂)
  • resolutions: 每级缩放的分辨率数组
  • origin: 瓦片网格原点
  • wrapX: 是否水平环绕(全球地图常用)

3. WMS 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import TileWMS from 'ol/source/TileWMS'
import TileLayer from 'ol/layer/Tile'

const wmsLayer = new TileLayer({
source: new TileWMS({
url: 'http://localhost:8080/geoserver/wms',
params: {
'LAYERS': 'workspace:layername',
'TILED': true, // 启用瓦片模式
'VERSION': '1.1.1',
'FORMAT': 'image/png',
'TRANSPARENT': true
},
serverType: 'geoserver', // 服务器类型优化
crossOrigin: 'anonymous'
})
})

map.addLayer(wmsLayer)

关键参数说明:

  • params: WMS 请求参数(大写键名)
  • TILED: 是否以瓦片方式请求(true 性能更好)
  • serverType: 提示 OL 针对特定服务器优化请求

4. ImageWMS(单次请求整幅图)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import ImageWMS from 'ol/source/ImageWMS'
import ImageLayer from 'ol/layer/Image'

const imageWmsLayer = new ImageLayer({
source: new ImageWMS({
url: 'http://localhost:8080/geoserver/wms',
params: {
'LAYERS': 'workspace:layername',
'FORMAT': 'image/png'
},
ratio: 1, // 请求范围与视图范围的比例
crossOrigin: 'anonymous'
})
})

map.addLayer(imageWmsLayer)

适用场景: 小范围地图或需要完整图像的场景


5. Vector 矢量图层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import VectorSource from 'ol/source/Vector'
import VectorLayer from 'ol/layer/Vector'
import GeoJSON from 'ol/format/GeoJSON'

const vectorLayer = new VectorLayer({
source: new VectorSource({
url: 'http://localhost:8080/data/roads.geojson',
format: new GeoJSON()
}),
style: new Style({
stroke: new Stroke({ color: '#ff0000', width: 2 })
})
})

map.addLayer(vectorLayer)

参数配置详解

通用参数概念

无论是 Cesium 还是 OpenLayers,在加载地图服务时,都有以下通用参数概念:

  1. URL 模板: 定义服务地址,包含变量占位符
  2. 坐标系统: 定义地图投影方式(如 EPSG:3857、EPSG:4326)
  3. 缩放级别: 控制可见的地图缩放层级范围
  4. 跨域设置: 处理不同域名之间的资源共享
  5. 认证信息: 如 API 密钥或访问令牌

服务类型识别

当拿到一个接口地址时,可以通过以下特征判断服务类型:

  • XYZ/TMS: URL 包含 {x}/{y}/{z} 或类似变量
  • WMTS: URL 包含 “WMTS” 或 “service=wmts” 参数
  • WMS: URL 包含 “WMS” 或 “service=wms”、”request=getmap” 参数
  • ArcGIS: URL 包含 “/arcgis/“ 或 “/rest/services/“
  • 3D Tiles: URL 指向 tileset.json 文件

共性与区别总结

1. 架构设计差异

对比项 Cesium OpenLayers
图层管理 imageryLayers 数组,通过 addImageryProvider 添加 map.addLayer() 添加 Layer 对象
Provider vs Source 使用 ImageryProvider 提供数据 使用 Source + Layer 分离数据和渲染
地形支持 原生支持 3D 地形(TerrainProvider) 仅 2D,无地形概念
3D 模型 支持 3D Tiles、glTF 不支持原生 3D

2. 参数配置复杂度

服务类型 Cesium OpenLayers
XYZ ✅ 简单,只需 URL ✅ 简单,只需 URL
WMTS ⚠️ 中等,需配置 matrixSet ❌ 复杂,需手动配置 tileGrid
WMS ✅ 简单,parameters 对象 ✅ 简单,params 对象
矢量数据 较弱(Entity API) ✅ 强大(VectorLayer + Style)

3. 坐标系处理

1
2
3
4
5
6
// Cesium:默认 WGS84(EPSG:4326),无需转换
Cesium.Rectangle.fromDegrees(116.39, 39.9, 116.40, 40.0)

// OpenLayers:需要明确指定投影
import { transform } from 'ol/proj'
transform([116.39, 39.9], 'EPSG:4326', 'EPSG:3857')

4. 性能特点

特性 Cesium OpenLayers
大数据量 WebGL 加速,适合全球尺度 Canvas 渲染,局部区域更流畅
内存占用 较高(3D 纹理) 较低
移动端 较重 轻量
LOD(细节层次) 自动管理 需手动优化

如何选择合适的库?

使用 Cesium 的场景:

✅ 需要 3D 地形展示
✅ 全球尺度的可视化
✅ 倾斜摄影、BIM 模型加载
✅ 飞行漫游、视角动画
✅ 时空数据动态播放(如卫星云图)

使用 OpenLayers 的场景:

✅ 传统二维地图应用
✅ 大量矢量数据交互(编辑、查询)
✅ 需要复杂地图控件(比例尺、鹰眼)
✅ 局部区域高精度地图
✅ 对性能要求较高的移动端应用

常见问题与解决方案

1. 跨域问题

确保服务器设置 CORS 头,或在客户端使用 crossOrigin: 'anonymous' 参数。

2. Token 认证

对于需要认证的服务(如天地图),在 URL 中添加相应的 token 参数。

3. 层级不匹配

WMTS 服务的 tileMatrixLabelsmatrixIds 必须与服务端配置完全一致。

4. 透明度设置

叠加图层时设置 alpha(Cesium)或 opacity(OpenLayers)参数控制透明度。

5. 加载顺序

底图先加载,标注层后加载,确保正确的视觉层次。

通过本文的对比分析,我们可以看出 Cesium 和 OpenLayers 各有优势。选择哪个库主要取决于项目需求:如果需要三维可视化,Cesium 是首选;如果主要是二维地图应用,OpenLayers 更加灵活高效。