🗺️ Leaflet 加载 EPSG:4490 的 WMTS 服务踩坑记录
本文将带你快速了解 WGS84、EPSG:4490、EPSG:3857 三者的区别,并分析在使用 Leaflet 加载 EPSG:4490 的 WMTS 服务时,地图图层为何会出现偏差,并提供对应的解决思路。
🌍 坐标系基础知识
在 Web 地图开发中,理解不同坐标系的区别非常关键,尤其是当我们使用开源框架(如 Leaflet)加载来自政务或行业数据的 WMTS 服务时。
1. WGS84(地理坐标系统)
WGS84 是全球最常用的地理坐标系统,使用的是经纬度(单位:度)。它是 GPS 的基础坐标系统,也是很多 GIS 数据的参考标准。
- 表达方式:
经度 + 纬度 - 坐标单位:度(°)
- 用于描述地球上的“位置”
- 示例坐标:
(113.2644, 23.1291)
WGS84 本身并没有投影,只是一个椭球模型 + 坐标系。
2. EPSG:4490(中国常用 WGS84 坐标)
EPSG:4490 是中国国家测绘局采用的 WGS84 坐标系的地理坐标参考编号,它与 EPSG:4326(也属于 WGS84)在数值上非常接近,区别在于其测量精度和适配标准更符合中国境内要求。
- 同样使用“经纬度”
- 数据多来自政府平台(如天地图、政务 GIS 接口)
3. EPSG:3857(Web Mercator 墨卡托投影)
EPSG:3857 是 Web 地图中最常见的投影坐标系,Google Maps、OpenStreetMap、Leaflet 默认都使用它。
- 表达方式:
x, y平面坐标 - 坐标单位:米(meter)
- 是一种投影坐标,用来在二维屏幕上“近似展示球体”
- 会存在一定的形变(极地区被拉长)
❗为什么会出现偏差?
Leaflet 默认使用的是 EPSG:3857(Web Mercator 投影),而很多国内 WMTS 服务(特别是政务平台或天地图)使用的是 EPSG:4490(经纬度坐标,未投影)。
🚨 问题来源
当你将一个 EPSG:4490 的图层(如 WMTS)加载到一个 EPSG:3857 的地图容器中时,坐标并未经过投影转换,导致图层偏离正确位置(如位置偏移、中国地图偏右下)。
例如你直接写:
L.tileLayer('xxxxxx', {}).addTo(map);
🛠 解决方案:Leaflet 支持 EPSG:4490 坐标系加载 WMTS
为了解决偏移问题,我们需要让 Leaflet 地图本身工作在 EPSG:4490 坐标系统下,这样它才能正确解释 WMTS 图层和其他点位的经纬度。
✅ 实现思路
- 自定义一个符合 EPSG:4490 的 CRS(Coordinate Reference System);
- 初始化地图时,将默认的 EPSG:3857 替换为我们定义的 EPSG:4490;
- 加载 EPSG:4490 的 WMTS 图层,此时瓦片坐标、中心点坐标、矢量点位都能准确对应。
✍️ 代码实现
// ✅ 第一步:定义 EPSG:4490 投影坐标系
L.CRS.CustomEPSG4490 = L.extend({}, L.CRS.Earth, {
code: "EPSG:4490",
projection: L.Projection.LonLat,
transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5),
scale: function (zoom) {
return 256 * Math.pow(2, zoom - 1);
}
});
// ✅ 第二步:实例化地图,使用 EPSG:4490 作为坐标系统
this.map = L.map(this.target, {
zoomSnap: 0.1,
zoomDelta: 0.1,
crs: L.CRS.CustomEPSG4490, //第一步定义的坐标
wheelPxPerZoomLevel: 60,
zoomControl: false,
attributionControl: false
}).setView(
[this.initExtent.lat, this.initExtent.lng],
this.initExtent.zoom
);
wmtsLayer.addTo(map);