《WebGIS EPSG:4326 与 EPSG:3857 墨卡托投影转换》

前言

很多 WebGIS 新手容易混淆地理坐标系 和投影坐标系:

  • EPSG:4326(WGS84):经纬度(lng/lat),球面坐标,单位:度
  • EPSG:3857(Web 墨卡托):平面笛卡尔坐标(x,y),单位:米,互联网瓦片地图标准(高德、OSM、谷歌瓦片都是 3857)

常见坑:

  1. 拿经纬度 4326 直接传给 3857 瓦片图层,地图上点位飞到很远;
  2. OpenLayers 加载 shp、GeoJSON 数据,投影不一致导致要素不显示;
  3. Mars2D、Cesium 底层是 4326,对接第三方瓦片服务返回 3857 米坐标,需要互相转换。

注意:EPSG:3857 也叫球形墨卡托,不考虑地球椭球,把地球当成正球体,是为互联网地图瓦片专门设计,不是测绘级精密投影。

一、EPSG:4326 和 EPSG:3857 基础概念对比

重点:Web 墨卡托有个明显缺陷:两极区域会无限拉伸,纬度 ±85.0511° 之外不再支持,所以 3857 有效纬度范围:-85.0511, 85.0511。

二、投影转换原理

4326 → 3857(经纬度转米坐标)

  1. 经度:线性换算,经度转 X;
  2. 纬度:正切双曲函数变换,球面墨卡托公式,纬度越高 Y 增长越快。

3857 → 4326(米坐标转回经纬度)

公式逆运算,平面米坐标还原成球面经纬度。

区别:GCJ02 是坐标偏移加密 ;4326↔3857 是投影数学变换,无加密,纯数学公式,没有迭代近似误差。

三、完整 JS 转换工具类

新建 projTransform.js,Vue、原生 JS、Mars2D、OpenLayers 通用。

javascript 复制代码
/**
 * EPSG:4326 <=> EPSG:3857 Web墨卡托转换
 * 4326: [lng, lat] 单位度
 * 3857: [x, y] 单位米
 */
const R = 6378137 // 地球半径,Web墨卡托采用

/**
 * EPSG:4326 转 EPSG:3857
 * @param {number} lng 经度
 * @param {number} lat 纬度
 * @returns [x, y] 米
 */
function wgs84To3857(lng, lat) {
  let x = lng * Math.PI / 180 * R
  let y = Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 180 / 2)) * R
  return [x, y]
}

/**
 * EPSG:3857 转 EPSG:4326
 * @param {number} x
 * @param {number} y
 * @returns [lng, lat] 度
 */
function wgs3857To4326(x, y) {
  let lng = x / R * 180 / Math.PI
  let lat = (2 * Math.atan(Math.exp(y / R)) - Math.PI / 2) * 180 / Math.PI
  return [lng, lat]
}

export default {
  wgs84To3857,
  wgs3857To4326
}

四、Vue 项目调用示例

javascript 复制代码
import proj from './projTransform.js'

// 西安坐标 EPSG:4326
const lng = 108.95
const lat = 34.27

// 4326转3857
const [x, y] = proj.wgs84To3857(lng, lat)
console.log('EPSG:3857 X,Y:', x, y)

// 3857转回4326
const [lng2, lat2] = proj.wgs3857To4326(x, y)
console.log('还原经纬度:', lng2, lat2)

五、结合 OpenLayers / Mars2D 实战场景

场景 1:OpenLayers 加载 3857 瓦片,业务数据是 4326 GeoJSON

OpenLayers 本身内置 proj4,推荐优先使用官方 proj4 库,不用手写公式,适合复杂项目:

javascript 复制代码
npm install proj4
javascript 复制代码
import proj4 from 'proj4'
// proj4内置支持4326、3857
const [x,y] = proj4('EPSG:4326','EPSG:3857', [lng, lat])

✅ 建议:少量点位转换可以手写上面公式;批量矢量数据、复杂投影,优先 proj4,减少手写 bug。

场景 2:Mars2D 中获取鼠标点击的 3857 平面坐标

Mars2D 获取屏幕点击,默认拿到经纬度 4326;如果对接第三方瓦片服务需要 X/Y 米坐标,调用上面转换函数。

六、开发高频踩坑点

  1. ❌ 混淆:GCJ02 偏移 ≠ 3857 投影
    GCJ02 是对 4326 经纬度加偏移;3857 是投影变换,二者完全独立,可以组合:WGS84 (4326) → GCJ02 → GCJ02 的 3857 投影。
  2. ❌ 纬度超过 ±85.05°,转换结果异常,Web 墨卡托不支持
  3. ❌ 单位搞错:4326 是度,3857 是米,打印日志经常看错
  4. ❌ GeoJSON 规范:GeoJSON 标准规定只能使用 EPSG:4326,如果你的 GeoJSON 是 3857,不符合规范,需要转成 4326 再存储
  5. ✅ 瓦片原理:TMS、XYZ 瓦片都是基于 EPSG:3857 切割

七、坐标系系列汇总(方便读者收藏)

  1. EPSG:4326:WGS84 球面经纬度(度)
  2. EPSG:3857:Web 墨卡托平面米坐标(互联网瓦片)
  3. GCJ02:国测局加密经纬度(高德腾讯)
  4. BD09:百度二次加密坐标系

项目组合举例:

高德底图 = GCJ02 + EPSG:3857 投影瓦片

天地图影像 = WGS84 EPSG:4326

八、总结

EPSG:4326 和 EPSG:3857 的投影转换是 WebGIS 基础底层能力。

简单一句话区分:4326 描述地球上球面位置(经纬度);3857 是把球面摊成平面,用于瓦片地图渲染 。

开发中记住:底图瓦片是什么投影,矢量数据就要对应投影,否则要素错位、不显示。

相关推荐
时间的情敌5 小时前
《Mars2D 快速上手,从零搭建三维 GIS 项目》
arcgis·mars2d
那年那棵树2 天前
基于WebGis的人生如旅地图系统
前端·arcgis·vue·课程设计
梅如你3 天前
全国逐年 1KM 分辨率 NDVI 植被指数数据集(2000-2024)
arcgis·gis·遥感
const_qiu4 天前
第二章 2.4:搭建 Monorepo 骨架 + 共享包 @autix/contracts
java·人工智能·arcgis
地图小课堂5 天前
Bigemap Pro 教程|如何打开Arcgis文件格式(shp、gdb、gdbtable、mdb)
arcgis
广州浮点FLOATLIC5 天前
ArcGIS Pro 批处理失败,怎样判断是脚本报错还是许可条件不满足?
arcgis·许可管理·许可证管理·许可监控
hsg777 天前
简述:ArcGIS Pro新建地图底图加载慢,选项设置方法
arcgis·建库
hsg777 天前
简述:修改ArcGIS Pro:选项-应用程序-显示-本地缓存
arcgis·建库
VX130715441229 天前
测绘资质延续申请申报材料常见退件问题及解答
搜索引擎·arcgis·全文检索