

新闻资讯
常见问题地图应用中都涉及到一个问题就是坐标纠偏的问题,这个问题的是因为根据地方规则保密性要求不允许地图厂商使用标准的GPS坐标,而是要用国家定义的偏移标准,或者在此基础上再做算法运算,所以这就出现了三种常规的坐标标准:GPS坐标(WGS-84,国际标准,谷歌地球软件,硬件GPS模块等)、中国坐标偏移标准(GCJ-02,谷歌地图、腾讯地图、高德地图等)、百度坐标偏移标准(BD-09,仅仅百度地图采用)。由于不允许其他坐标转换成GPS坐标,所以三种坐标互换就剩4种常用转换:GPS转百度、GPS转其他、百度转其他、其他转百度,其他就是中国坐标偏移标准,目前谷歌地图、腾讯地图、高德地图都采用这个标准。

在线百度地图提供了Convertor类专门负责这个转换,只需要调用对应translate方法传入参数即可,这个转换出来的结果比较理想,缺点就是必须在线使用,毕竟算法是存储在服务器上的保密的,但是很多应用场景是离线使用的,这就需要找一个比较准确的算法做这个转换,网上流传的主要是java、c#、python等语言的版本,于是特意将其改写成了c++ Qt的版本,亲测和在线版本的运算结果基本一致,据说赤道附近可能偏差很大,但是在中国地图上偏差很小。
1 省市区域地图封装类功能特点
2 百度地图封装类功能特点
3 离线地图下载类功能特点
4 省市轮廓下载类功能特点
体验地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg 提取码:uyes 文件名:bin_map.zip
国内站点:https://gitee.com/feiyangqingyun
国际站点:https://github.com/feiyangqingyun
//常用转换就4种: GPS转百度、GPS转其他、百度转其他、其他转百度
//WGS-84: 国际标准,GPS坐标(Google Earth使用、或者GPS模块)
//GCJ-02: 中国坐标偏移标准,Google Map、高德、腾讯使用
//BD-09: 百度坐标偏移标准,Baidu Map使用
static QPointF gcj2bd(const QPointF &point);
static QPointF bd2gcj(const QPointF &point);
static double transformLng(double lng, double lat);
static double transformLat(double lng, double lat);
static QPointF wgs2gcj(const QPointF &point);
static QPointF wgs2bd(const QPointF &point);
//圆周率转换量
double x_pi = M_PI * 3000.0 / 180.0;
QPointF MapHelper::gcj2bd(const QPointF &point)
{
double x = point.x();
double y = point.y();
double z = qSqrt(x * x + y * y) + 0.00002 * qSin(y * x_pi);
double theta = qAtan2(y, x) + 0.000003 * qCos(x * x_pi);
double lng = z * qCos(theta) + 0.0065;
double lat = z * qSin(theta) + 0.006;
return QPointF(lng, lat);
}
QPointF MapHelper::bd2gcj(const QPointF &point)
{
double x = point.x() - 0.0065;
double y = point.y() - 0.006;
double z = qSqrt(x * x + y * y) - 0.00002 * qSin(y * x_pi);
double theta = qAtan2(y, x) - 0.000003 * qCos(x * x_pi);
double lng = z * qCos(theta);
double lat = z * qSin(theta);
return QPointF(lng, lat);
}
double MapHelper::transformLng(double lng, double lat)
{
double ret = 300.0 + lat + 2.0 * lng + 0.1 * lat * lat + 0.1 * lat * lng + 0.1 * qSqrt(qAbs(lat));
ret += (20.0 * qSin(6.0 * lat * M_PI) + 20.0 * qSin(2.0 * lat * M_PI)) * 2.0 / 3.0;
ret += (20.0 * qSin(lat * M_PI) + 40.0 * qSin(lat / 3.0 * M_PI)) * 2.0 / 3.0;
ret += (150.0 * qSin(lat / 12.0 * M_PI) + 300.0 * qSin(lat / 30.0 * M_PI)) * 2.0 / 3.0;
return ret;
}
double MapHelper::transformLat(double lng, double lat)
{
double ret = -100.0 + 2.0 * lat + 3.0 * lng + 0.2 * lng * lng + 0.1 * lat * lng + 0.2 * qSqrt(qAbs(lat));
ret += (20.0 * qSin(6.0 * lat * M_PI) + 20.0 * qSin(2.0 * lat * M_PI)) * 2.0 / 3.0;
ret += (20.0 * qSin(lng * M_PI) + 40.0 * qSin(lng / 3.0 * M_PI)) * 2.0 / 3.0;
ret += (160.0 * qSin(lng / 12.0 * M_PI) + 320 * qSin(lng * M_PI / 30.0)) * 2.0 / 3.0;
return ret;
}
//卫星椭球坐标投影到平面地图坐标系的投影因子
double a = 6378245.0;
//椭球的偏心率
double ee = 0.00669342162296594323;
QPointF MapHelper::wgs2gcj(const QPointF &point)
{
double x = point.x();
double y = point.y();
double lng = transformLng(y - 35.0, x - 105.0);
double lat = transformLat(y - 35.0, x - 105.0);
double rad = y / 180.0 * M_PI;
double magic = qSin(rad);
magic = 1 - ee * magic * magic;
double sqrtMagic = qSqrt(magic);
lng = x + (lng * 180.0) / (a / sqrtMagic * qCos(rad) * M_PI);
lat = y + (lat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * M_PI);
return QPointF(lng, lat);
}
QPointF MapHelper::wgs2bd(const QPointF &point)
{
//GPS转百度要经过两重转换
return gcj2bd(wgs2gcj(point));
}