前言
很多 WebGIS 新手容易混淆地理坐标系 和投影坐标系:
- EPSG:4326(WGS84):经纬度(lng/lat),球面坐标,单位:度
- EPSG:3857(Web 墨卡托):平面笛卡尔坐标(x,y),单位:米,互联网瓦片地图标准(高德、OSM、谷歌瓦片都是 3857)
常见坑:
- 拿经纬度 4326 直接传给 3857 瓦片图层,地图上点位飞到很远;
- OpenLayers 加载 shp、GeoJSON 数据,投影不一致导致要素不显示;
- Mars2D、Cesium 底层是 4326,对接第三方瓦片服务返回 3857 米坐标,需要互相转换。
注意:EPSG:3857 也叫球形墨卡托,不考虑地球椭球,把地球当成正球体,是为互联网地图瓦片专门设计,不是测绘级精密投影。
一、EPSG:4326 和 EPSG:3857 基础概念对比

重点:Web 墨卡托有个明显缺陷:两极区域会无限拉伸,纬度 ±85.0511° 之外不再支持,所以 3857 有效纬度范围:-85.0511, 85.0511。
二、投影转换原理
4326 → 3857(经纬度转米坐标)
- 经度:线性换算,经度转 X;
- 纬度:正切双曲函数变换,球面墨卡托公式,纬度越高 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 米坐标,调用上面转换函数。
六、开发高频踩坑点
- ❌ 混淆:GCJ02 偏移 ≠ 3857 投影
GCJ02 是对 4326 经纬度加偏移;3857 是投影变换,二者完全独立,可以组合:WGS84 (4326) → GCJ02 → GCJ02 的 3857 投影。 - ❌ 纬度超过 ±85.05°,转换结果异常,Web 墨卡托不支持
- ❌ 单位搞错:4326 是度,3857 是米,打印日志经常看错
- ❌ GeoJSON 规范:GeoJSON 标准规定只能使用 EPSG:4326,如果你的 GeoJSON 是 3857,不符合规范,需要转成 4326 再存储
- ✅ 瓦片原理:TMS、XYZ 瓦片都是基于 EPSG:3857 切割
七、坐标系系列汇总(方便读者收藏)
- EPSG:4326:WGS84 球面经纬度(度)
- EPSG:3857:Web 墨卡托平面米坐标(互联网瓦片)
- GCJ02:国测局加密经纬度(高德腾讯)
- BD09:百度二次加密坐标系
项目组合举例:
高德底图 = GCJ02 + EPSG:3857 投影瓦片
天地图影像 = WGS84 EPSG:4326
八、总结
EPSG:4326 和 EPSG:3857 的投影转换是 WebGIS 基础底层能力。
简单一句话区分:4326 描述地球上球面位置(经纬度);3857 是把球面摊成平面,用于瓦片地图渲染 。
开发中记住:底图瓦片是什么投影,矢量数据就要对应投影,否则要素错位、不显示。