经纬志
首页 / OpenLayers / 教程

WMS 与 WMTS 服务接入

先看结论

内网 GIS 平台的底图和专题图多数以 OGC 服务发布。 WMS 按范围出图,WMTS 按瓦片编号取图,两者参数结构不同,接错的表现也很不一样。

最后验证 2026-11-03 · OpenLayers 10.3.1 · 更新 2026-10-27 · 引用本文

WMS:按请求范围返回一张图

WMS 的核心是 GetMap 请求,客户端把当前视野的地理范围发给服务端, 服务端实时渲染一张图片返回。参数里最重要的是图层名和版本:

var wmsLayer = new ol.layer.Tile({
  source: new ol.source.TileWMS({
    url: 'https://demo.mapserver.org/cgi-bin/wms',
    params: {
      'LAYERS': 'bluemarble',   // 图层名,多个用逗号分隔
      'VERSION': '1.1.1'
    },
    serverType: 'mapserver',
    crossOrigin: 'anonymous'
  })
});

TileWMS 把大范围切成 256 像素的小请求, 服务端支持 TILED=true 时命中缓存;不支持时每个瓦片都是独立渲染, 拼缝处会出现线状断裂。不能确认服务是否支持时,可以改用 ol.source.ImageWMS,一次只请求一张覆盖视野的图:

var imageLayer = new ol.layer.Image({
  source: new ol.source.ImageWMS({
    url: 'https://example.gov.cn/geoserver/plan/wms',
    params: { 'LAYERS': 'plan:parcels', 'VERSION': '1.1.1' },
    ratio: 1.1   // 多取 10% 范围,减弱拖动时的边缘空白
  })
});

常用请求参数

参数作用常见取值
LAYERS要渲染的图层工作区名前缀不可省,如 plan:parcels
STYLES服务端样式名空字符串表示默认样式
VERSION协议版本1.1.1 或 1.3.0
FORMAT返回图片格式image/png 支持透明
TRANSPARENT背景透明叠加在底图上必须为 true
TILED按瓦片请求GeoServer 支持,MapServer 不支持

这些参数都写在 params 对象里,键名大小写要与服务端约定一致。 OpenLayers 会自动追加 SERVICE=WMS、REQUEST=GetMap、 BBOX、WIDTH、HEIGHT、SRS 等必需项, 不需要手写。

1.3.0 版本的坑:WMS 1.3.0 在 EPSG:4326 下把坐标轴顺序定为 纬度在前,部分服务端严格遵循,导致返回的图上下颠倒或左右错位。 遇到这种服务,把 VERSION 固定为 1.1.1, 或改用 EPSG:3857 请求。

叠加到已有底图上

专题图通常叠在底图之上,需要满足三个条件: 专题层的 TRANSPARENT 为 true、 FORMAT 为 image/png、 服务端支持与视图一致的坐标系。

var map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({ source: new ol.source.OSM() }),
    new ol.layer.Tile({
      source: new ol.source.TileWMS({
        url: 'https://example.gov.cn/geoserver/plan/wms',
        params: {
          'LAYERS': 'plan:roads',
          'VERSION': '1.1.1',
          'FORMAT': 'image/png',
          'TRANSPARENT': true
        },
        transition: 0
      }),
      opacity: 0.8
    })
  ],
  view: new ol.View({
    center: ol.proj.fromLonLat([116.391263, 39.907359]),
    zoom: 12
  })
});

transition: 0 关闭瓦片淡入,专题图在缩放时不会出现半透明闪烁。

WMTS:按瓦片矩阵取图

WMTS 是瓦片服务,请求里带 TILEMATRIX、TILECOL、 TILEROW,客户端必须事先知道服务的瓦片矩阵集。 先看 GetCapabilities,确认 TileMatrixSet 名称和 每一级的 ScaleDenominator、TopLeftCorner。

var projection = ol.proj.get('EPSG:3857');
var projectionExtent = projection.getExtent();
var size = ol.extent.getWidth(projectionExtent) / 256;
var resolutions = [];
var matrixIds = [];

for (var z = 0; z < 18; z++) {
  resolutions[z] = size / Math.pow(2, z);
  matrixIds[z] = z;                  // 部分服务是 'EPSG:3857:0' 这种格式
}

var wmtsLayer = new ol.layer.Tile({
  source: new ol.source.WMTS({
    url: 'https://example.gov.cn/wmts',
    layer: 'img',
    matrixSet: 'EPSG:3857',
    format: 'image/png',
    style: 'default',
    projection: projection,
    tileGrid: new ol.tilegrid.WMTS({
      origin: ol.extent.getTopLeft(projectionExtent),
      resolutions: resolutions,
      matrixIds: matrixIds
    }),
    wrapX: true
  })
});

matrixIds 必须与服务端完全一致。天地图、ArcGIS Server、 GeoServer 三家的命名规则都不同,常见的还有 'EPSG:3857:0'、'0'、'GoogleMapsCompatible:0'。 填错时控制台会大量 404,地图一片空白。

RESTful 风格的 WMTS

有些服务把参数拼在路径里,而不是查询串。 把 requestEncoding 设为 'REST', 并在 url 中用花括号占位:

new ol.source.WMTS({
  url: 'https://example.gov.cn/wmts/1.0.0/{Layer}/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png',
  requestEncoding: 'REST',
  layer: 'img',
  style: 'default',
  matrixSet: 'EPSG:3857',
  format: 'image/png',
  projection: projection,
  tileGrid: tileGrid
});

跨域与图片导出

服务端没有返回 Access-Control-Allow-Origin 时, 瓦片能显示,但 canvas 会被标记为“污染”, 导出图片、截图、像素命中测试全部失败,控制台报 Tainted canvases may not be exported。

解决方式是在数据源上声明 crossOrigin: 'anonymous', 同时要求服务端开启 CORS。两者缺一不可: 客户端声明了但服务端没开,瓦片直接加载失败;服务端开了客户端没声明,画布依然被污染。

白图与错位的排查顺序

现象先查什么处理
整张白图,控制台 404图层名、工作区前缀、URL 路径用浏览器直接打开 GetCapabilities 核对
返回的是异常 XML服务端报错信息看 ServiceException 文本,多为图层名或 CRS 不支持
图有内容但整体偏移服务端声明的 CRS 与视图是否一致统一投影,或让服务端加 SRS=EPSG:3857
图上下颠倒是否为 WMS 1.3.0 + 4326降级到 1.1.1
缩放时闪烁、断层是否开启 TILED、transition关掉 TILED 或设 transition: 0
瓦片 404 但服务正常matrixIds 命名按 Capabilities 里的 TileMatrix 标识逐级写

调试捷径:在浏览器网络面板里复制一条失败的 GetMap 请求, 贴到地址栏直接访问。如果返回的是 XML 而不是图片, 错误原因就写在 XML 的 ServiceException 节点里。

引用本文

经纬志(2026)。《WMS 与 WMTS 服务接入》。https://www.jingweizhi.com/openlayers/tutorial/wms-wmts.html(访问日期 2026-11-03)。