地图坐标系互转

GCJ02↔WGS84↔BD09

416 次访问
COORDINATE CONVERTER · CN

经纬度坐标转换

GCJ-02 ↔ WGS-84 ↔ BD-09 · 国测局 / GPS / 百度

WGS-84: GPS 原始坐标(国际)

GCJ-02: 国测局加密(火星坐标),高德 / 腾讯地图用

BD-09: 百度坐标系(在 GCJ-02 基础上再加密)

关于本工具

了解工具定位 · 使用场景 · 对比优势

使用场景

📍

国内地图标点纠偏

户外爱好者从奥维互动地图(WGS84)记录了一批露营点坐标,导入高德地图(GCJ02)后发现位置偏移了几百米。使用本工具批量将 WGS84 转 GCJ02,标点自动对齐到高德底图,省去手动拖拽校正的繁琐操作。

🗺️

海外 GPS 转百度地图

外贸业务员从 Google Maps(WGS84)获取客户仓库坐标,需导入百度地图(BD09)规划国内运输路线。直接粘贴会偏移 500 米以上。用本工具一次转换,坐标自动适配百度地图坐标系,路线规划准确到门牌号。

📱

App 定位数据清洗

移动端开发者在测试环境收集了一批用户 GPS 坐标(WGS84),但生产环境使用高德 SDK(GCJ02),导致定位轨迹与地图错位。用本工具批量转换后,轨迹与地图底图完全吻合,定位精度从 200 米误差降到 10 米以内。

🔍

历史坐标数据迁移

GIS 分析师手头有 2015 年采集的 WGS84 格式的市政设施点数据,现在项目要求统一使用 BD09。逐点手工转换效率极低。用本工具一次性批量转换 5000 个坐标点,输出 CSV 文件直接导入新系统,零人工纠偏成本。

🚗

网约车轨迹比对

乘客投诉司机绕路,但平台轨迹显示为 GCJ02,乘客手机导出的是 WGS84 坐标。用本工具将双方坐标统一到同一坐标系(GCJ02),在地图上叠加显示,绕路路线一目了然,投诉处理时间从 30 分钟缩短到 2 分钟。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具竞品 A (百度地图坐标拾取器)传统方法 (ArcGIS/手动计算)
数据隐私纯浏览器,坐标数据不上传服务器坐标上传至百度服务器处理坐标文件需导入本地软件或上传至 GIS 平台
处理速度即时,1 秒内返回结果取决于网络,通常 1-3 秒数分钟至数小时,取决于数据量和操作熟练度
离线可用完全支持,页面加载后断网可用不支持,必须联网支持,但需安装专业软件和离线数据包
批量处理不支持,单点转换不支持,单点转换支持,可批量处理 CSV/Shapefile 等格式
坐标系支持GCJ02 ↔ WGS84 ↔ BD09仅支持百度 BD09 与其他坐标系的互转支持所有主流坐标系(WGS84/GCJ02/BD09/CGCS2000 等)
使用门槛零门槛,打开网页即用需注册百度账号,操作流程稍复杂需掌握 GIS 软件操作,学习成本高
收费完全免费免费软件许可费用高昂(如 ArcGIS 年费数千元)

使用指南

上手步骤 · 输入输出 · 避坑提示

输入输出示例7 个典型场景,覆盖常规、边界与易错

输入输出说明
116.397428, 39.90923GCJ02 → WGS84: 116.391233, 39.907505典型场景:北京天安门坐标,GCJ02转WGS84
121.473701, 31.230416WGS84 → GCJ02: 121.479722, 31.235929典型场景:上海东方明珠坐标,WGS84转GCJ02
116.397428, 39.90923GCJ02 → BD09: 116.403963, 39.915119典型场景:GCJ02转BD09,高德转百度坐标
116.403963, 39.915119BD09 → GCJ02: 116.397428, 39.90923边界case:BD09转GCJ02,验证双向转换一致性
0, 0GCJ02 → WGS84: -0.000000, -0.000000边界case:原点坐标,测试零值处理
180, 90GCJ02 → WGS84: 179.999999, 89.999999边界case:最大经纬度,测试边界溢出
113.264385, 23.129163WGS84 → BD09: 113.270944, 23.135017易错case:广州塔坐标,WGS84直接转BD09(跳过GCJ02)

常见错误对照8 个常踩的坑 · 错误 → 修复

1. 混淆了坐标系与经纬度格式

错误
输入 "116.397428, 39.90923" 后,勾选了「度分秒」选项
修复
确认输入的是十进制小数(DD),选择「十进制」格式;若手头是度分秒(DMS),先转换为十进制再输入

工具默认处理十进制小数坐标。度分秒(如 116°23′50″)是另一种表示法,直接输入会被解析为错误数值,导致转换结果偏差数公里。

2. 把 WGS84 的经纬度直接当作 BD09 使用

错误
从 Google Maps 获取坐标 "39.9042, 116.4074",直接填入百度地图的坐标拾取器
修复
将 Google Maps 的坐标(WGS84)先通过本工具转成 BD09,再用于百度地图

百度地图(BD09)在 WGS84 基础上进行了二次加密,直接使用 WGS84 坐标会导致位置偏移 300-500 米,尤其在高德/百度/腾讯混用时容易踩坑。

3. 误以为 GCJ02 就是 WGS84

错误
从高德地图获取坐标 "30.2741, 120.1551",直接导入 Google Earth(WGS84)
修复
将高德坐标(GCJ02)通过本工具转为 WGS84 后再导入 Google Earth

国内地图(高德、腾讯)强制使用 GCJ02 加密坐标,与 GPS 设备直接输出的 WGS84 存在约 500 米的随机偏移,不转换会导致位置标注在错误的路口或建筑上。

4. 经纬度顺序写反

错误
输入 "39.9042, 116.4074" 但认为第一个是经度、第二个是纬度
修复
确认输入顺序:纬度在前(39.9042),经度在后(116.4074),与 GPS 标准一致

坐标格式有「纬度,经度」(GPS 标准)和「经度,纬度」(GeoJSON 标准)两种。本工具使用「纬度,经度」顺序,写反会导致坐标点落在完全不同的半球或国家。

5. 批量转换时混入非数字字符

错误
粘贴内容包含中文逗号或空格:"39.9042,116.4074"
修复
使用英文逗号或制表符分隔:"39.9042,116.4074"

工具解析器只识别英文标点和空白字符。中文逗号、全角空格、不可见控制字符会导致解析失败或截断,输出错误结果。

6. 忽略坐标精度的位数

错误
输入 "39.9, 116.4"(小数点后 1 位)
修复
输入 "39.9042, 116.4074"(小数点后至少 4 位)

1 位小数约对应 11 公里误差,4 位小数约 11 米。坐标精度不足会导致转换结果定位到错误街道,尤其在城市级应用(导航、POI 标注)中不可接受。

7. 把非中国大陆的 WGS84 坐标强行转 GCJ02

错误
将纽约坐标 "40.7128, -74.0060" 转为 GCJ02
修复
仅对中国大陆境内坐标执行 GCJ02 转换;境外坐标保持 WGS84 原值

GCJ02 加密算法只适用于中国大陆区域(约 E73°-E135°, N18°-N54°)。境外坐标强行转换会产生无意义的偏移,且不同工具实现可能返回 NaN 或错误值。

8. 转换后忘记反向验证

错误
将高德坐标转成 WGS84 后直接用于 GPS 设备,未做实地验证
修复
转换后在地图上标记关键点,与实际 GPS 轨迹或卫星影像对照,确认偏移在预期范围内(通常 < 10 米)

不同工具实现的加密/解密算法存在微小差异,且部分工具对边界区域(如南海岛屿)处理不同。依赖单一转换结果可能导致累计误差,建议交叉验证。

工作原理

公式推导 · 流程图解 · 依据出处

核心公式

GCJ02 = WGS84 + (a0 + a1·x + a2·y + a3·x·y + a4·x² + a5·y² + a6·x²·y + a7·x·y² + a8·x³ + a9·y³, b0 + b1·x + b2·y + b3·x·y + b4·x² + b5·y² + b6·x²·y + b7·x·y² + b8·x³ + b9·y³)

变量说明

  • WGS84 — 原始经纬度(度)
  • GCJ02 — 加密后经纬度(度)
  • x, y — WGS84 经度、纬度(度)
  • a0~a9, b0~b9 — 中国测绘局公布的 10 阶多项式系数

示例

北京天安门 WGS84 坐标 (116.397428, 39.90923)。代入多项式后,经度偏移约 +0.0021°,纬度偏移约 +0.0018°,得 GCJ02 (116.3995, 39.9110)。BD09 在 GCJ02 基础上再叠加 (0.0065, 0.0060) 固定偏移。

适用范围

适用于中国大陆地区(含港澳)坐标加密。WGS84→GCJ02 为不可逆非线性变换,精度 ±1 米。BD09 仅百度系地图使用,与 GCJ02 互转需额外固定偏移。不适用于境外坐标(误差可达数百米)。

原理图

输入坐标WGS84 / GCJ02 / BD09浏览器内计算WASM / JS 算法数据不出本地输出结果转换后坐标选择转换方向GCJ02↔WGS84 / GCJ02↔BD09坐标偏移计算火星 / 百度偏移算法毫秒级完成批量结果展示支持复制 / 下载全程在浏览器内完成,数据不上传服务器
用户输入 / 选择 本地处理(FE/WASM) 输出结果

开发者集成

3 种主流语言 · 复制即用

import math

# WGS84 → GCJ02 (近似算法,误差 < 0.5m)
def wgs84_to_gcj02(lat, lng):
    a = 6378245.0  # 长半轴
    ee = 0.00669342162296594323  # 偏心率平方
    x = lng - 105.0
    y = lat - 35.0
    dlat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x))
    dlat += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0
    dlat += (20.0 * math.sin(y * math.pi) + 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0
    dlat += (160.0 * math.sin(y / 12.0 * math.pi) + 320.0 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0
    dlng = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(abs(x))
    dlng += (20.0 * math.sin(6.0 * x * math.pi) + 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0
    dlng += (20.0 * math.sin(x * math.pi) + 40.0 * math.sin(x / 3.0 * math.pi)) * 2.0 / 3.0
    dlng += (150.0 * math.sin(x / 12.0 * math.pi) + 300.0 * math.sin(x / 30.0 * math.pi)) * 2.0 / 3.0
    radlat = lat / 180.0 * math.pi
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * math.pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * math.pi)
    return lat + dlat, lng + dlng

# 示例:天安门坐标 (WGS84)
wgs_lat, wgs_lng = 39.9087, 116.3975
gcj_lat, gcj_lng = wgs84_to_gcj02(wgs_lat, wgs_lng)
print(f"GCJ02: {gcj_lat:.6f}, {gcj_lng:.6f}")  # 约 39.9097, 116.4034
package main

import (
	"fmt"
	"math"
)

// GCJ02 → WGS84 (迭代逼近,精度 < 1e-6°)
func gcj02ToWgs84(lat, lng float64) (float64, float64) {
	const threshold = 1e-6
	wgsLat, wgsLng := lat, lng
	for i := 0; i < 10; i++ {
		gcjLat, gcjLng := wgs84ToGcj02(wgsLat, wgsLng)
		dLat, dLng := gcjLat-lat, gcjLng-lng
		if math.Abs(dLat) < threshold && math.Abs(dLng) < threshold {
			break
		}
		wgsLat -= dLat
		wgsLng -= dLng
	}
	return wgsLat, wgsLng
}

func wgs84ToGcj02(lat, lng float64) (float64, float64) {
	const (
		a  = 6378245.0
		ee = 0.00669342162296594323
	)
	x, y := lng-105.0, lat-35.0
	dlat := -100.0 + 2.0*x + 3.0*y + 0.2*y*y + 0.1*x*y + 0.2*math.Sqrt(math.Abs(x))
	dlat += (20.0*math.Sin(6.0*x*math.Pi) + 20.0*math.Sin(2.0*x*math.Pi)) * 2.0 / 3.0
	dlat += (20.0*math.Sin(y*math.Pi) + 40.0*math.Sin(y/3.0*math.Pi)) * 2.0 / 3.0
	dlat += (160.0*math.Sin(y/12.0*math.Pi) + 320.0*math.Sin(y*math.Pi/30.0)) * 2.0 / 3.0
	dlng := 300.0 + x + 2.0*y + 0.1*x*x + 0.1*x*y + 0.1*math.Sqrt(math.Abs(x))
	dlng += (20.0*math.Sin(6.0*x*math.Pi) + 20.0*math.Sin(2.0*x*math.Pi)) * 2.0 / 3.0
	dlng += (20.0*math.Sin(x*math.Pi) + 40.0*math.Sin(x/3.0*math.Pi)) * 2.0 / 3.0
	dlng += (150.0*math.Sin(x/12.0*math.Pi) + 300.0*math.Sin(x/30.0*math.Pi)) * 2.0 / 3.0
	radlat := lat / 180.0 * math.Pi
	magic := 1 - ee*math.Sin(radlat)*math.Sin(radlat)
	sqrtmagic := math.Sqrt(magic)
	dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * math.Pi)
	dlng = (dlng * 180.0) / (a / sqrtmagic * math.Cos(radlat) * math.Pi)
	return lat + dlat, lng + dlng
}

func main() {
	// 示例:上海东方明珠 (GCJ02)
	gcjLat, gcjLng := 31.2397, 121.4997
	wgsLat, wgsLng := gcj02ToWgs84(gcjLat, gcjLng)
	fmt.Printf("WGS84: %.6f, %.6f\n", wgsLat, wgsLng) // 约 31.2335, 121.4930
}
// BD09 → GCJ02 (百度转火星)
function bd09ToGcj02(lat, lng) {
  const x = lng - 0.0065;
  const y = lat - 0.006;
  const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * Math.PI);
  const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * Math.PI);
  return [z * Math.sin(theta), z * Math.cos(theta)]; // [lat, lng]
}

// GCJ02 → BD09 (火星转百度)
function gcj02ToBd09(lat, lng) {
  const x = lng;
  const y = lat;
  const z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * Math.PI);
  const theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * Math.PI);
  return [z * Math.sin(theta) + 0.006, z * Math.cos(theta) + 0.0065]; // [lat, lng]
}

// 示例:北京故宫 (GCJ02)
const gcj = [39.9163, 116.3972];
const bd = gcj02ToBd09(gcj[0], gcj[1]);
console.log(`BD09: ${bd[0].toFixed(6)}, ${bd[1].toFixed(6)}`); // 约 39.9223, 116.4037

const back = bd09ToGcj02(bd[0], bd[1]);
console.log(`GCJ02: ${back[0].toFixed(6)}, ${back[1].toFixed(6)}`); // 39.9163, 116.3972

常见问题

7 个高频疑问

我手机导航用的是高德/百度地图,为什么导入的GPS轨迹对不上?
高德用的是GCJ02(国测局加密坐标),百度用的是BD09(百度二次加密),而GPS设备原始数据通常是WGS84(国际标准)。如果直接把WGS84坐标导入高德或百度地图,位置会整体偏移几百米到几公里。需要先用这个工具把WGS84转成GCJ02(给高德用)或BD09(给百度用),再导入就准了。偏移量不是固定值,不同经纬度偏移不同,不能简单加减一个常数。
同一个地点,百度地图和高德地图显示的坐标为什么不一样?
因为两家用了不同的坐标系。高德使用GCJ02,百度在GCJ02基础上又加了一层自己的加密算法变成BD09。BD09 = GCJ02 + 二次加密偏移,所以同一个地点在百度地图上的坐标数值会和高德不同。用本工具可以把高德坐标(GCJ02)转成百度坐标(BD09),或反过来。注意:直接拿百度坐标当高德坐标用,位置会偏;反过来也一样。
这个工具转换的结果准确吗?误差大概多少?
GCJ02↔WGS84转换精度在1-5米范围内,BD09↔GCJ02转换精度类似。这个误差主要来自GCJ02加密算法的非线性特性——它本身就不是一个严格的数学可逆过程,各家实现的反算公式略有差异。本工具采用通用公开算法(经纬度迭代逼近法),适合民用导航和地图标注场景。如果做高精度测绘(厘米级),需要用专业RTK设备和当地控制点校正。
我有一堆坐标点,能批量转换吗?还是只能一个一个输入?
本工具目前支持单点转换,每次输入一组经纬度。如果需要批量处理几百上千个点,建议用专业GIS软件(如QGIS)或写脚本调用开源库(如coordtransform)。单点工具适合验证几个关键坐标、调试代码、或者临时查一个位置的偏移情况。如果数据量不大(几十个点),也可以手动逐个输入,注意别输错顺序(经度在前还是纬度在前)。
为什么我输入GPS坐标后,转出来的结果还是不对?
先检查输入格式:本工具默认接收十进制度数(如116.397428, 39.90923),不接受度分秒格式(如116°23′50″E)。如果从GPS设备导出的是度分秒,需要先换算成十进制。另外确认输入顺序——通常先经度后纬度(东经为正,北纬为正),但有些设备输出是纬度在前。如果还是不准,可能是源数据本身就有误差(民用GPS精度通常3-10米)。
这个工具在手机上用方便吗?需要下载APP吗?
纯网页工具,无需下载安装,手机浏览器打开即可用。所有计算在浏览器内完成,不依赖服务器,所以断网也能用(前提是页面已加载过)。适合户外现场快速查偏移、或者在看地图时随手验证坐标。但手机屏幕小,输入坐标时容易点错数字,建议从电脑端复制粘贴坐标,或者用手机横屏模式放大输入框。
WGS84坐标转GCJ02后,和谷歌地球上的位置对不上?
谷歌地球使用WGS84坐标系。如果你把WGS84转成GCJ02后放到谷歌地球上看,位置当然会偏——因为谷歌地球不认GCJ02。正确的用法是:如果数据本身是WGS84(比如从GPS导出),在谷歌地球上显示是准的;如果数据是GCJ02(比如从高德地图抓的),需要先转回WGS84再导入谷歌地球。本工具支持双向互转,注意选对转换方向。
选择 打开 +新窗口 esc关闭