什么是地图坐标系转换?
目前常用的地图坐标系有多种标准,几家主流地图(如百度地图,高德地图和QQ地图等)使用的坐标系标准也各不相同。
假如您有GPS坐标,想在百度地图上显示;或者有百度地图的坐标,但想在微信地图上显示,这时就需要使用一些算法或通过官方的API来转换坐标,在目标地图上正确显示。
主流地图坐标系说明
1、WGS84坐标系
WGS-84坐标系为一种大地坐标系(地心坐标系,GPS原始坐标体系),也是目前广泛使用的GPS全球卫星定位系统使用的坐标系。对应工
具“输入坐标类型”里的GPS坐标。
2、GCJ02坐标系
GCJ-02坐标系:国测局坐标,又名火星坐标系。
国测局02年发布的坐标体系,它是一种对经纬度数据的加密算法,即加入随机的偏差。
是国内最广泛使用的坐标体系,高德地图、腾讯地图都使用它
3、BD09坐标系
为百度地图坐标系,在GCJ02坐标系基础上再次加密。其中bd09ll表示百度经纬度坐标,bd09mc表示百度墨卡托米制坐标。
4、CGCS2000坐标系
国家大地坐标系。该坐标系是通过中国GPS 连续运行基准站、 空间大地控制网以及天文大地网与空间地网联合平差建立的地心大地坐标系统。
说明下、百度的地图加密原始gps地理坐标是这样的:百度地图加密的是 火星坐标系 (GCJ-02),而GCJ-02加密的是原始gps坐标系。所以从原始gps坐标,到百度地图坐标,顺序是WGS-84 --> GCJ-02 --> BD-09
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | public class BdMapUtil { /** 圆周率 */ public static double pi = 3.1415926535897932384626; public static double a = 6378245.0; public static double ee = 0.00669342162296594323; private static double x_pi = 3.14159265358979324 * 3000.0 / 180.0; /** * 得到百度地图经纬度 * * @author zr * @date 2019-09-09 * @param lat WGS-84 gps的纬度 * @param lon WGS-84 gps的经度 * @return com.construn.vehicle.message.util.Gps */ public static Gps getBd09( double lat, double lon) { //得到火星坐标经纬度 Gps gps = gps84ToGcj02(lat, lon); if (gps == null ) { return null ; } //得到百度坐标经纬度 return gcj02ToBd09(gps.getWgLat(), gps.getWgLon()); } /** * 火星坐标系 (GCJ-02)转百度地图坐标系 * * @author zr * @date 2019-09-09 * @param * @param gg_lat * @param gg_lon * @return void */ private static Gps gcj02ToBd09( double gg_lat, double gg_lon) { double x = gg_lon, y = gg_lat; 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 bd_lon = z * Math.Cos(theta) + 0.0065; double bd_lat = z * Math.Sin(theta) + 0.006; return new Gps(bd_lat, bd_lon); } /** * 84 to 火星坐标系 (GCJ-02) * * @author zr * @date 2019-09-09 * @param * @param lat * @param lon * @return void */ private static Gps gps84ToGcj02( double lat, double lon) { if (outOfChina(lat, lon)) { return null ; } double dLat = transformLat(lon - 105.0, lat - 35.0); double dLon = transformLon(lon - 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); dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * pi); double mgLat = lat + dLat; double mgLon = lon + dLon; return new Gps(mgLat, mgLon); } /** * 判断有没有超过中国区 * * @author zr * @date 2019-09-09 * @param * @param lat * @param lon * @return boolean */ private static bool outOfChina( double lat, double lon) { if (lon < 72.004 || lon > 137.8347) { return true ; } if (lat < 0.8293 || lat > 55.8271) { return true ; } return false ; } /** * 处理纬度 * * @author zr * @date 2019-09-09 * @param * @param x * @param y * @return double */ private static double transformLat( double x, double y) { double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x)); ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0; ret += (20.0 * Math.Sin(y * pi) + 40.0 * Math.Sin(y / 3.0 * pi)) * 2.0 / 3.0; ret += (160.0 * Math.Sin(y / 12.0 * pi) + 320 * Math.Sin(y * pi / 30.0)) * 2.0 / 3.0; return ret; } /** * 处理经度 * * @author zr * @date 2019-09-09 * @param * @param x * @param y * @return double */ private static double transformLon( double x, double y) { double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x)); ret += (20.0 * Math.Sin(6.0 * x * pi) + 20.0 * Math.Sin(2.0 * x * pi)) * 2.0 / 3.0; ret += (20.0 * Math.Sin(x * pi) + 40.0 * Math.Sin(x / 3.0 * pi)) * 2.0 / 3.0; ret += (150.0 * Math.Sin(x / 12.0 * pi) + 300.0 * Math.Sin(x / 30.0 * pi)) * 2.0 / 3.0; return ret; } } public class Gps { private double wgLat; private double wgLon; public Gps() { } public Gps( double _wgLat, double _wgLon) { wgLat = _wgLat; wgLon = _wgLon; } public double getWgLat() { return wgLat; } public double getWgLon() { return wgLon; } public String toString() { return "Gps{" + "wgLat=" + wgLat + ", wgLon=" + wgLon + '}' ; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!