Geoserver WMTS服务在Leaflet中瓦片不显示:列索引超出范围
解决Leaflet请求WMTS瓦片时TileCol超出范围的问题
这个问题我处理过不少次,核心原因是Leaflet默认的EPSG:3857瓦片编号规则和你的Geoserver WMTS服务里自定义的grilla_3857瓦片矩阵集不兼容。Leaflet自带的EPSG:3857是面向全球范围的标准瓦片矩阵,而你的grilla_3857应该是针对特定区域定制的,两者的层级分辨率、行列号起始范围、瓦片覆盖范围都不一样,所以才会出现请求行列号超出服务允许范围的错误。
问题分析
从服务器返回的错误列39119超出范围,最小值:0,最大值:66可以看出:你当前请求的层级下,服务只允许0-66的列号,但Leaflet按照默认规则生成了39119这个极大的数值,这完全不在服务的有效行列范围内,自然拿不到瓦片。
解决方案
要解决这个问题,关键是让Leaflet使用和WMTS服务grilla_3857完全一致的瓦片矩阵参数来生成请求。这里有两种可行的方式:
方式一:手动自定义CRS(坐标参考系统)
首先你需要访问你的WMTS服务的GetCapabilities地址,提取grilla_3857瓦片矩阵集的详细参数,包括每个层级的:
TopLeftCorner(层级瓦片的左上角坐标)ScaleDenominator(比例尺)或Resolution(分辨率)MatrixWidth/MatrixHeight(该层级的总行列数)TileWidth/TileHeight(瓦片像素大小,一般是256)
然后在Leaflet中扩展默认的EPSG3857,创建匹配自定义矩阵集的CRS:
// 自定义CRS,完全匹配grilla_3857的参数 const crsGrilla3857 = L.CRS.EPSG3857.extend({ // 若你的矩阵集左上角坐标不是EPSG3857的默认值,需要修改这里的transformation transformation: new L.Transformation(1, -20037508.342789244, -1, 20037508.342789244), // 填入从GetCapabilities获取的每个层级的ScaleDenominator,顺序对应Leaflet的zoom层级 scales: [ 2000000, 1000000, 500000, // ... 依次填入所有层级的比例尺 ], tileSize: 256, // 你的服务瓦片大小,从GetCapabilities确认 }); // 初始化地图时指定自定义CRS map = L.map('map',{ zoomControl: false, crs: crsGrilla3857 }).setView([4, -72], 6); // 底图如果用标准OSM会有偏移,建议使用和自定义CRS匹配的底图,或者保留默认CRS(仅作参考) let baseMap = new L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors', crs: L.CRS.EPSG3857 }); baseMap.addTo(map); // 加载WMTS图层时指定使用自定义CRS const url = 'http://dejsoftware.com:8130/geoserver/gwc/service/wmts'; const params = [ `service=WMTS`, `request=GetTile`, `version=1.0.0`, `layer=cmd_cucuta:Orthofoto_CMD_Resumen_Rodeo_GeoTIFF`, `style=raster`, `Format=image/png`, `tilematrixset=grilla_3857`, `TileMatrix={z}`, `TileRow={y}`, `TileCol={x}` ].join("&"); let layerOrtho = new L.tileLayer(`${url}?${params}`, { crs: crsGrilla3857 }); layerOrtho.addTo(map);
方式二:使用Leaflet WMTS插件(更简便)
如果你不想手动配置CRS,可以使用专门的leaflet-wmts插件,它会自动解析WMTS的GetCapabilities文档,获取grilla_3857的所有参数,自动匹配瓦片矩阵集,避免手动配置出错:
map = L.map('map',{ zoomControl: false }).setView([4, -72], 6); let baseMap = new L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }); baseMap.addTo(map); // 使用leaflet-wmts插件加载WMTS图层 const wmtsLayer = new L.TileLayer.WMTS('http://dejsoftware.com:8130/geoserver/gwc/service/wmts', { layer: 'cmd_cucuta:Orthofoto_CMD_Resumen_Rodeo_GeoTIFF', style: 'raster', format: 'image/png', tileMatrixSet: 'grilla_3857', attribution: 'Your Custom Attribution' }); wmtsLayer.addTo(map);
注意事项
- 确保Leaflet的zoom层级和WMTS服务的
TileMatrix编号完全对应,比如服务里的TileMatrix是从0开始还是从1开始,Leaflet的zoom要匹配。 - 如果你选择手动配置CRS,一定要严格按照GetCapabilities里的参数填写,任何参数不匹配都会导致行列号错误。
内容的提问来源于stack exchange,提问作者Juan Carlos Valderrama Gonzlez
相关产品推荐
相关产品推荐

