国内地图坐标系介绍及常见地图(百度、高德、凯立德)之间的坐标系转换

本文介绍了常见的地图坐标系,包括WGS84、GCJ-02(火星坐标)、百度坐标(BD-09)等,并提供了坐标系之间的转换算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、国内地图坐标系简介

1、  WGS84(地图坐标)

美国GPS使用的是WGS84的坐标系统。GPS系统获得的坐标系统,基本为标准的国际通用的WGS84坐标系统

2、  GCJ-02(火星坐标)

GCJ-02是由中国国家测绘局制订的地理信息系统的坐标系统。它是一种对经纬度数据的加密算法,即加入随机的偏差。国内出版的各种地图系统(包括电子形式),出于国家安全考虑,必须至少采用GCJ-02对地理位置进行首次加密

所有的电子地图所有的导航设备,都需要加入国家保密插件。第一步,地图公司测绘地图,测绘完成后,送到国家测绘局,将真实坐标的电子地图,加密成“火星坐标”,这样的地图才是可以出版和发布的,然后才可以让GPS公司处理。第二步,所有的GPS公司,只要需要汽车导航的,需要用到导航电子地图的,统统需要在软件中加入国家保密算法,将COM口读出来的真实的坐标信号,加密转换成国家要求的保密的坐标,这样,GPS导航仪和导航电子地图就可以完全匹配,GPS也就可以正常工作。

在国内发行的地图都使用GCJ02进行首次加密,
地图坐标系
百度地图百度坐标(BD-09)
腾讯搜搜地图火星坐标
图吧MapBar地图图吧坐标
高德MapABC地图API火星坐标
凯立德地图火星坐标(转为K码)

I、 百度坐标:在GCJ02基础上,进行了BD-09二次加密措施,API支持从WGS/GCJ转换成百度坐标,不支持反转。

II、凯立德K码:
a)  K码将地图分成了四块进行编码,中心点在内蒙的阿拉善左旗境内,该点的K码是7uy1yuy1y。以该点为中心分别在东西方向和南北方向画一条线当横纵(XY)坐标轴,那么第一象限(即东北方向的那块)的K码的第1位全部都是5,第2象限的K码的第一位全是6,第3、4象限的K码的第一位分别全是7、8。并且该点有4个K码,即用四个K码定位都是这一点,这四个K码分别是7uy1yuy1y、80000uy1y、500000000、6uy1y0000。   

b) K码的第2-5位表示东西方向上的坐标,第6-9位代表南北方向上的坐标。实际上K码就是一个凯立德特有的34进制数,(26个字母加10个阿拉伯数字,再去掉不用的小写L和O共34个字符),这个34进制数从左向右从低位向高位排列(我们常用的10进制是从右向左由低位向高位排列),其中第2-5位东西方向上的数每一个单位代表2.5m左右,南北方向上的数每一个单位代表实际距离3米左右。比如80000uy1y向东约2.5米的点的K码就是81000uy1y,向东约34×2.5m的点的K码就是80100uy1y

c)K码与火星坐标可相互转换。

二、坐标系转换

1、地球坐标系(WGS)到火星坐标系(GCJ-02)的转换算法

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var M_PI = 3.14159265358979324;  
  2. var a = 6378245.0;  
  3. var ee = 0.00669342162296594323;  
  4. var x_pi = M_PI * 3000.0 / 180.0;  
  5. function out_of_china(lat,  lon) {  
  6.     if (lon < 72.004 || lon > 137.8347)  
  7.         return true;  
  8.     if (lat < 0.8293 || lat > 55.8271)  
  9.         return true;  
  10.     return false;  
  11. }  
  12.   
  13. function wgs2gcj_lat(x, y) {  
  14.     var ret1 = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y  
  15.             + 0.2 * Math.sqrt(Math.abs(x));  
  16.       
  17.     ret1 += (20.0 * Math.sin(6.0 * x * M_PI) + 20.0 * Math.sin(2.0 * x  
  18.             * M_PI)) * 2.0 / 3.0;  
  19.     ret1 += (20.0 * Math.sin(y * M_PI) + 40.0 * Math.sin(y / 3.0 * M_PI)) * 2.0 / 3.0;  
  20.     ret1 += (160.0 * Math.sin(y / 12.0 * M_PI) + 320 * Math.sin(y * M_PI  
  21.             / 30.0)) * 2.0 / 3.0;  
  22.     return ret1;  
  23. }  
  24.   
  25. function wgs2gcj_lng(x, y) {  
  26.     var ret2 = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1  
  27.             * Math.sqrt(Math.abs(x));  
  28.     ret2 += (20.0 * Math.sin(6.0 * x * M_PI) + 20.0 * Math.sin(2.0 * x  
  29.             * M_PI)) * 2.0 / 3.0;  
  30.     ret2 += (20.0 * Math.sin(x * M_PI) + 40.0 * Math.sin(x / 3.0 * M_PI)) * 2.0 / 3.0;  
  31.     ret2 += (150.0 * Math.sin(x / 12.0 * M_PI) + 300.0 * Math.sin(x / 30.0  
  32.             * M_PI)) * 2.0 / 3.0;  
  33.     return ret2;  
  34. }  
  35.   
  36. function wgs2gcj(poi) {  
  37.     if (out_of_china(poi.lat, poi.lng)) {  
  38.         return poi;  
  39.     }  
  40.     var poi2 = {};  
  41.     var dLat = wgs2gcj_lat(poi.lng - 105.0, poi.lat - 35.0);  
  42.     var dLon = wgs2gcj_lng(poi.lng - 105.0, poi.lat - 35.0);  
  43.     var radLat = poi.lat / 180.0 * M_PI;  
  44.     var magic = Math.sin(radLat);  
  45.     magic = 1 - ee * magic * magic;  
  46.     var sqrtMagic = Math.sqrt(magic);  
  47.     dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * M_PI);  
  48.     dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * M_PI);  
  49.     poi2.lat = poi.lat + dLat;  
  50.     poi2.lng = poi.lng + dLon;  
  51.     return poi2;  
  52. }  


2、火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法  
  2. function gcj2bd(poi) {  
  3.     var poi2 = {};  
  4.     var x = poi.lng, y = poi.lat;  
  5.     var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);  
  6.     var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);  
  7.     poi2.lng = z * Math.cos(theta) + 0.0065;  
  8.     poi2.lat = z * Math.sin(theta) + 0.006;  
  9.     return poi2;  
  10. }  
  11.   
  12. function bd2gcj(poi) {  
  13.     var poi2 = {};  
  14.     var x = poi.lng - 0.0065, y = poi.lat - 0.006;  
  15.     var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);  
  16.     var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);  
  17.     poi2.lng = z * Math.cos(theta);  
  18.     poi2.lat = z * Math.sin(theta);  
  19.     return poi2;  
  20. }  

3、火星坐标系 (GCJ-02) 与凯立德K码 的转换算法

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var codes = "0123456789abcdefghijkmnpqrstuvwxyz";  
  2. function __decode(pch)  
  3. {  
  4.     var v = 0;  
  5.     for (var i = 3; i >= 0; --i)  
  6.         v = v * 34 + (codes.indexOf(pch.charAt(i)));  
  7.     v = v * 250 / 9;  
  8.     return v;  
  9. }  
  10.   
  11. function __encode(v)  
  12. {  
  13.     var pch = "";  
  14.     v = v * 9 / 250;  
  15.     for (var i = 0; i < 4; ++i)  
  16.     {  
  17.         pch += codes.charAt(v % 34);  
  18.         v /= 34;  
  19.     }  
  20.     return pch;  
  21. }  
  22.   
  23. function DecodeLon(k)  
  24. {  
  25.     var lon = __decode(k.substring(1, 5));  
  26.     if (k.charAt(0) == '5' || k.charAt(0) == '8')  
  27.         lon += 35000000;  
  28.     lon += 70000000;  
  29.     return lon/1000000.0;  
  30. }  
  31.   
  32. function DecodeLat(k)  
  33. {  
  34.     var lat = __decode(k.substring(5, 9));  
  35.     if (k.charAt(0) <= '6')  
  36.         lat += 35000000;  
  37.     lat += 5000000;  
  38.     return lat/1000000.0;  
  39. }  
  40.   
  41. function Encode(lat, lon)  
  42. {  
  43.     lat = parseInt(lat*1000000);  
  44.     lon = parseInt(lon*1000000);  
  45.     var k;  
  46.     lon -= 70000000;  
  47.     lat -= 5000000;  
  48.     if (lat > 35000000)  
  49.         if (lon <= 35000000)  
  50.             k = "6";  
  51.         else  
  52.             k = "5";  
  53.     else  
  54.         if (lon <= 35000000)  
  55.             k = "7";  
  56.         else  
  57.             k = "8";  
  58.     if (lon > 35000000)  
  59.         lon -= 35000000;  
  60.     if (lat > 35000000)  
  61.         lat -= 35000000;  
  62.     k += __encode(lon);  
  63.     k += __encode(lat);  
  64.     return k;  
  65. }  
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值