百度地圖使用 BD-09 座標體系(在 GCJ-02 基礎上再加密)。本文提供百度墨卡托座標 (BD-09) 與火星座標 (GCJ-02) 互轉的 Java 實作,核心為非線性偏移演算法。
public class BaiduCoordConverter {
private static final double X_PI = 3.14159265358979324 * 3000.0 / 180.0;
/**
* BD-09 -> GCJ-02 (解密)
*/
public static double[] bd09ToGcj02(double bdLat, double bdLon) {
double x = bdLon - 0.0065;
double y = bdLat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
double gcjLon = z * Math.cos(theta);
double gcjLat = z * Math.sin(theta);
return new double[]{gcjLat, gcjLon};
}
/**
* GCJ-02 -> BD-09 (加密)
*/
public static double[] gcj02ToBd09(double gcjLat, double gcjLon) {
double x = gcjLon, y = gcjLat;
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI);
double bdLon = z * Math.cos(theta) + 0.0065;
double bdLat = z * Math.sin(theta) + 0.006;
return new double[]{bdLat, bdLon};
}
public static void main(String[] args) {
double bdLat = 31.22997, bdLon = 121.640756;
double[] gcj = bd09ToGcj02(bdLat, bdLon);
System.out.printf("BD-09: %.6f, %.6f%n", bdLat, bdLon);
System.out.printf("GCJ-02: %.6f, %.6f%n", gcj[0], gcj[1]);
double[] bd = gcj02ToBd09(gcj[0], gcj[1]);
System.out.printf("回轉 BD-09: %.6f, %.6f%n", bd[0], bd[1]);
}
}