当前位置:网站首页>GPS坐标转百度地图坐标的方法
GPS坐标转百度地图坐标的方法
2022-07-03 06:02:00 【UU_Yang】
首先需要认识一下GPS的坐标系。GPS坐标系遵循WGS-84标准,在这个标准下,GPS芯片可以发出不同的数据包格式。根据其数据帧帧头的不同,GPS数据可以分类为GPGGA、GPGSA、GPGSV、GPRMC等。这些帧头标识了后续帧内数据的组成结构。通常情况下,我们所关心的定位数据如经纬度、速度、时间等均可以从GPRMC帧中获取得到。
在次我不讲解具体的帧的格式,在网上可以很容易搜到,也可以总芯片配套的接口文档找到数据帧的格式。通过解读GPRMC包,我们可以得到类似于“3040.8639,N,10405.7573,E”的位置数据,其字段含义可以在文档中找到。这里我解析的结果是:北纬30°40.8639',东经104°5.7573'。
在得到这两个数据后,我们可以试着去在地图上定位一下,我们发现多数地图定位用的是小数形式的坐标。这里我们就需要去讲如何把一个GPS的原始数据,转换为小数形式的数据。
举例:106°14'15"的转换
因为度分秒都是六十进制的
所以可以这样转换:
15/60=0.25分
(14+0.25)/60=0.2375度
106+0.2375=106.2375度
所以最后的结果是106.2375°
通过这个转换之后,我的位置坐标【北纬30°40.8639',东经104°5.7573'】就可以变成【30.681065N,104.095955E】(这个就是WGS-84的坐标)这个模样。这个坐标是GPS的物理定位,根据国际标准,需要对这个坐标进行GCJ-02偏移转换,转换后的坐标才可以在google地图、高德地图、以及腾讯地图上定位(以上三家遵循GCJ-02加密)。至于为什么要这样做,是因为加密坐标的原因。因为GCJ-02是不可逆的转换。
这里贴出由准寻WGS-84标准转换为GCJ-02的C++源码:
const double pi = 3.14159265358979324;
//
// Krasovsky 1940
//
// a = 6378245.0, 1/f = 298.3
// b = a * (1 - f)
// ee = (a^2 - b^2) / a^2;
const double a = 6378245.0;
const double ee = 0.00669342162296594323;
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;
}
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 * sqrt(abs(x));
ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * sin(y / 12.0 * pi) + 320 * sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
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 * sqrt(abs(x));
ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
/*
参数
wgLat:WGS-84纬度wgLon:WGS-84经度
返回值:
mgLat:GCJ-02纬度mgLon:GCJ-02经度
*/
void gps_transform( double wgLat, double wgLon, double& mgLat, double& mgLon)
{
if (outOfChina(wgLat, wgLon)) {
mgLat = wgLat;
mgLon = wgLon;
return;
}
double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
double radLat = wgLat / 180.0 * pi; double magic = sin(radLat);
magic = 1 - ee * magic * magic; double sqrtMagic = sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi);
mgLat = wgLat + dLat; mgLon = wgLon + dLon;
}
经过以上的转换,我们的坐标就可以在遵循GCJ-02标准的地图删定位了,这里给出大家一个比较好用的测试定位的网址:http://www.gpsspg.com/maps.htm
百度地图有些特殊,它在GCJ-02基础上又进行了一次加密,百度把这个加密标准叫做BD-09,但是这个加密并没有对外公开。但是万能的网络以及无所不能的网友总会有办法解决这类问题。这里我就贴出一个可行的转换办法,经过测试,定位很准确。
#include <math.h>
const double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
//将 GCJ-02 坐标转换成 BD-09 坐标
void bd_encrypt(double gg_lat, double gg_lon, double &bd_lat, double &bd_lon)
{
double x = gg_lon, y = gg_lat;
double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);
double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);
bd_lon = z * cos(theta) + 0.0065;
bd_lat = z * sin(theta) + 0.006;
}
void bd_decrypt(double bd_lat, double bd_lon, double &gg_lat, double &gg_lon)
{
double x = bd_lon - 0.0065, y = bd_lat - 0.006;
double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi);
double theta = atan2(y, x) - 0.000003 * cos(x * x_pi);
gg_lon = z * cos(theta);
gg_lat = z * sin(theta);
}
这样,我们的坐标也可以在百度地图上准确定位了,满心欢喜~~
另外再贴上一个比较容易解释坐标为何需要转换的图例,以方便大家理解:
国际通用的转换做法:
百度的做法:
这也解释了,为什么GPS坐标需要经过转换的原因。感谢贡献这些资料到网上的人们!
参考:
http://m.blog.csdn.net/blog/wildboy2001/39497681
http://www.haodaima.net/art/2441684
http://www.gpsspg.com/maps.htm
http://wenda.haosou.com/q/1365472754066079
http://www.geekcome.com/content-10-1464-1.html
边栏推荐
- 卷积神经网络CNN中的卷积操作详解
- 88. 合并两个有序数组
- Understand one-way hash function
- [teacher Zhao Yuqiang] index in mongodb (Part 2)
- [advanced pointer (1)] | detailed explanation of character pointer, pointer array, array pointer
- [teacher Zhao Yuqiang] Alibaba cloud big data ACP certified Alibaba big data product system
- Kubernetes notes (IV) kubernetes network
- Qt读写Excel--QXlsx插入图表5
- C 语言文件操作函数大全 (超详细)
- [video of Teacher Zhao Yuqiang's speech on wot] redis high performance cache and persistence
猜你喜欢
Loss function in pytorch multi classification
Convolution operation in convolution neural network CNN
Personal outlook | looking forward to the future from Xiaobai's self analysis and future planning
[Zhao Yuqiang] deploy kubernetes cluster with binary package
Together, Shangshui Shuo series] day 9
Exception when introducing redistemplate: noclassdeffounderror: com/fasterxml/jackson/core/jsonprocessingexception
[teacher Zhao Yuqiang] kubernetes' probe
Core principles and source code analysis of disruptor
Clickhouse learning notes (I): Clickhouse installation, data type, table engine, SQL operation
Kubernetes notes (VI) kubernetes storage
随机推荐
Bio, NiO, AIO details
[teacher Zhao Yuqiang] calculate aggregation using MapReduce in mongodb
最大似然估计,散度,交叉熵
SVN分支管理
Alibaba cloud OOS file upload
一起上水碩系列】Day 9
pytorch DataLoader实现miniBatch(未完成)
伯努利分布,二项分布和泊松分布以及最大似然之间的关系(未完成)
[video of Teacher Zhao Yuqiang's speech on wot] redis high performance cache and persistence
Txt document download save as solution
JS implements the problem of closing the current child window and refreshing the parent window
Redhat7 system root user password cracking
多线程与高并发(7)——从ReentrantLock到AQS源码(两万字大章,一篇理解AQS)
[branch and cycle] | | super long detailed explanation + code analysis + a trick game
Understand one-way hash function
Personal outlook | looking forward to the future from Xiaobai's self analysis and future planning
Jedis source code analysis (II): jediscluster module source code analysis
Clickhouse learning notes (2): execution plan, table creation optimization, syntax optimization rules, query optimization, data consistency
Installation du plug - in CAD et chargement automatique DLL, Arx
Final review (day3)