文章目录
-
-
- 1、概述
-
- 1.1 WGS-84
- 1.2 GCJ-02
- 1.3 BD-09
- 2、坐标转换原理
- 3、GCJ02与BD09相互转换
- 4、WGS84与BD09相互转换
-
1、概述
位置纠偏:
1.1 WGS-84
原始GPS坐标。是为GPS使用全球定位系统建立的坐标系统。通过实际的硬件设备收集获得
1.2 GCJ-02
中国国家测绘局(G表示Guojia国家,C表示Cehui测绘,J表示Ju局)制定的地理信息系统的坐标系统。它是经纬度数据的加密算法,即添加随机偏差。国内出版的各种地图系统(包括电子形式)至少必须使用GCJ-02首次加密地理位置。(这种坐标用于高德、腾讯和谷歌地图中国)
1.3 BD-09
百度坐标系,在GCJ二次加密是于02坐标系。BD09LL表示百度经纬度坐标,BD09MC表示百度墨卡托米坐标。
2.坐标转换原理
详看:
3、GCJ02与BD09相互转换
private static double xPi = 3.14159265358979324 * 3000.0 / 180.0; // 摘录于:https://www.cnblogs.com/luoliuniankk/p/10028897.html public static Map gcj02ToBd09(Map map) {
System.out.println(map); double x = 0; double y = 0; x = Double.parseDouble(map.get("lng").toString()); y = Double.parseDouble(map.get("lat").toString()); double z = Math.sqrt(x * x y * y) 0.00002 * Math.sin(y * xPi);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * xPi);
map.put(tagLng,dataDigit(z * Math.cos(theta) + 0.0065));
map.put(tagLat,dataDigit(z * Math.sin(theta) + 0.0065));
return map;
}
public static Map bd09ToGcj02(Map map) {
double x = 0;
double y = 0;
x = Double.parseDouble(map.get("lng").toString());
y = Double.parseDouble(map.get("lat").toString());
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xPi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * xPi);
map.put(tagLng,dataDigit(z * Math.cos(theta)));
map.put(tagLat,dataDigit(z * Math.sin(theta)));
System.out.println(map);
return map;
}
// 保留小数点后8位
public static Double dataDigit(Double val) {
DecimalFormat df = new DecimalFormat("#.00000000");
String format = df.format(val);
return Double.valueOf(format);
}
4、WGS84与BD09相互转换
static double x_PI = 3.14159265358979324 * 3000.0 / 180.0;
static double PI = 3.1415926535897932384626;
static double a = 6378245.0;
static double ee = 0.00669342162296594323;
/** * WGS84 转换为 BD-09 */
public static Map wgs84ToBd09(Map map) {
double lng = 0;
double lat = 0;
lng = Double.valueOf(map.get("lng").toString());
lat = Double.valueOf(map.get("lat").toString());
// 第一次转换:实际上转化为 GCJ-02 坐标系
double dlat = transformlat(lng - 105.0, lat - 35.0);
double dlng = transformlng(lng - 105.0, lat - 35.0);
double radlat = lat / 180.0 * PI;
double magic = Math.sin(radlat);
magic = 1 - ee * magic * magic;
double sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
double mglat = lat + dlat;
double mglng = lng + dlng;
// 第二次转换:在GCJ-02基础上二次加密转为BD-09
double z = Math.sqrt(mglng * mglng + mglat * mglat) + 0.00002 * Math.sin(mglat * x_PI);
double theta = Math.atan2(mglat, mglng) + 0.000003 * Math.cos(mglng * x_PI);
double bd_lng = z * Math.cos(theta) + 0.0065;
double bd_lat = z * Math.sin(theta) + 0.006;
map.put(tagLng,bd_lng);
map.put(tagLat,bd_lat);
return map;
}
/** * 摘录于:https://www.cnblogs.com/fengcai/p/7479068.html * @param map * @return */
public static Map bd09ToWgs84(Map map){
double x = 0;
double y = 0;
x = Double.valueOf(map.get("lng").toString()) - 0.0065;
y = Double.valueOf(map.get("lat").toString()) - 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);
Double a = 6378245.0;
Double ee = 0.00669342162296594323;
Double dLat = transformlat(gcjLon - 105.0, gcjLat - 35.0);
Double dLon = transformlng(gcjLon - 105.0, gcjLat - 35.0);
Double radLat = gcjLat / 180.0 * PI;
Double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
Double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);
dLat = gcjLat - dLat;
dLon = gcjLon - dLon;
map.put(tagLat, dLat);
map.put(tagLng, dLon);
return map;
}
private static double transformlng(double lng, double lat) {
double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
return ret;
}
private static double transformlat(double lng, double lat) {
double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
return ret;
}
由于该文章只是对坐标系转换做了大致汇总。且摘录博文较多,故只在相关的位置给出了跳转链接作为说明,可直接跳转查看。