C++怎么实现百度坐标及GCJ02与WGS84之间的转换

发布时间:2023-03-09 14:36:41 作者:iii
来源:亿速云 阅读:277

C++怎么实现百度坐标及GCJ02与WGS84之间的转换

目录

  1. 引言
  2. 坐标系简介
  3. 坐标转换原理
  4. C++实现坐标转换
  5. 代码实现
  6. 测试与验证
  7. 总结
  8. 参考文献

引言

在现代地理信息系统(GIS)和地图服务中,坐标系的转换是一个常见的需求。不同的地图服务提供商使用不同的坐标系,例如百度地图使用百度坐标系(BD-09),而高德地图和谷歌地图则使用GCJ02坐标系。此外,全球定位系统(GPS)通常使用WGS84坐标系。因此,在实际应用中,我们经常需要在这些坐标系之间进行转换。

本文将详细介绍如何在C++中实现百度坐标系、GCJ02坐标系和WGS84坐标系之间的转换。我们将首先介绍这些坐标系的基本概念,然后讨论它们之间的转换原理,最后给出C++的实现代码。

坐标系简介

WGS84坐标系

WGS84(World Geodetic System 1984)是一种全球通用的地理坐标系,广泛应用于GPS定位系统。WGS84坐标系使用经纬度表示地理位置,其坐标原点位于地球的质心。

GCJ02坐标系

GCJ02(国测局02坐标系)是中国国家测绘局制定的一种加密坐标系,也称为“火星坐标系”。GCJ02坐标系是在WGS84坐标系的基础上,通过一定的加密算法进行偏移得到的。因此,GCJ02坐标与WGS84坐标之间存在一定的偏差。

百度坐标系

百度坐标系(BD-09)是百度地图使用的一种坐标系,它是在GCJ02坐标系的基础上进行了二次加密。因此,百度坐标系与GCJ02坐标系之间也存在一定的偏差。

坐标转换原理

WGS84与GCJ02之间的转换

WGS84坐标系与GCJ02坐标系之间的转换涉及到一定的加密算法。由于GCJ02坐标系是在WGS84坐标系的基础上进行偏移得到的,因此我们需要通过逆向算法将GCJ02坐标转换回WGS84坐标。

WGS84转GCJ02

WGS84转GCJ02的转换算法主要包括以下几个步骤:

  1. 将WGS84坐标转换为弧度。
  2. 计算偏移量。
  3. 将偏移量应用到WGS84坐标上,得到GCJ02坐标。

GCJ02转WGS84

GCJ02转WGS84的转换算法与WGS84转GCJ02的算法类似,但需要进行逆向计算。具体步骤如下:

  1. 将GCJ02坐标转换为弧度。
  2. 计算偏移量。
  3. 将偏移量从GCJ02坐标中减去,得到WGS84坐标。

GCJ02与百度坐标系之间的转换

GCJ02坐标系与百度坐标系之间的转换也涉及到一定的加密算法。由于百度坐标系是在GCJ02坐标系的基础上进行二次加密得到的,因此我们需要通过逆向算法将百度坐标转换回GCJ02坐标。

GCJ02转百度坐标系

GCJ02转百度坐标系的转换算法主要包括以下几个步骤:

  1. 将GCJ02坐标转换为弧度。
  2. 计算偏移量。
  3. 将偏移量应用到GCJ02坐标上,得到百度坐标。

百度坐标系转GCJ02

百度坐标系转GCJ02的转换算法与GCJ02转百度坐标系的算法类似,但需要进行逆向计算。具体步骤如下:

  1. 将百度坐标转换为弧度。
  2. 计算偏移量。
  3. 将偏移量从百度坐标中减去,得到GCJ02坐标。

C++实现坐标转换

WGS84转GCJ02

在C++中实现WGS84转GCJ02的转换,我们需要定义一个函数,该函数接受WGS84坐标作为输入,并返回GCJ02坐标。以下是实现代码:

#include <cmath>

const double pi = 3.1415926535897932384626;
const double a = 6378245.0;
const double ee = 0.00669342162296594323;

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;
}

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;
}

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;
}

void wgs84ToGcj02(double wgsLat, double wgsLon, double &gcjLat, double &gcjLon) {
    if (outOfChina(wgsLat, wgsLon)) {
        gcjLat = wgsLat;
        gcjLon = wgsLon;
        return;
    }
    double dLat = transformLat(wgsLon - 105.0, wgsLat - 35.0);
    double dLon = transformLon(wgsLon - 105.0, wgsLat - 35.0);
    double radLat = wgsLat / 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);
    gcjLat = wgsLat + dLat;
    gcjLon = wgsLon + dLon;
}

GCJ02转WGS84

在C++中实现GCJ02转WGS84的转换,我们需要定义一个函数,该函数接受GCJ02坐标作为输入,并返回WGS84坐标。以下是实现代码:

void gcj02ToWgs84(double gcjLat, double gcjLon, double &wgsLat, double &wgsLon) {
    if (outOfChina(gcjLat, gcjLon)) {
        wgsLat = gcjLat;
        wgsLon = gcjLon;
        return;
    }
    double dLat = transformLat(gcjLon - 105.0, gcjLat - 35.0);
    double dLon = transformLon(gcjLon - 105.0, gcjLat - 35.0);
    double radLat = gcjLat / 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);
    wgsLat = gcjLat - dLat;
    wgsLon = gcjLon - dLon;
}

GCJ02转百度坐标系

在C++中实现GCJ02转百度坐标系的转换,我们需要定义一个函数,该函数接受GCJ02坐标作为输入,并返回百度坐标。以下是实现代码:

void gcj02ToBd09(double gcjLat, double gcjLon, double &bdLat, double &bdLon) {
    double x = gcjLon, y = gcjLat;
    double z = sqrt(x * x + y * y) + 0.00002 * sin(y * pi);
    double theta = atan2(y, x) + 0.000003 * cos(x * pi);
    bdLon = z * cos(theta) + 0.0065;
    bdLat = z * sin(theta) + 0.006;
}

百度坐标系转GCJ02

在C++中实现百度坐标系转GCJ02的转换,我们需要定义一个函数,该函数接受百度坐标作为输入,并返回GCJ02坐标。以下是实现代码:

void bd09ToGcj02(double bdLat, double bdLon, double &gcjLat, double &gcjLon) {
    double x = bdLon - 0.0065, y = bdLat - 0.006;
    double z = sqrt(x * x + y * y) - 0.00002 * sin(y * pi);
    double theta = atan2(y, x) - 0.000003 * cos(x * pi);
    gcjLon = z * cos(theta);
    gcjLat = z * sin(theta);
}

代码实现

WGS84与GCJ02转换代码

以下是完整的WGS84与GCJ02转换代码:

#include <cmath>
#include <iostream>

const double pi = 3.1415926535897932384626;
const double a = 6378245.0;
const double ee = 0.00669342162296594323;

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;
}

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;
}

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;
}

void wgs84ToGcj02(double wgsLat, double wgsLon, double &gcjLat, double &gcjLon) {
    if (outOfChina(wgsLat, wgsLon)) {
        gcjLat = wgsLat;
        gcjLon = wgsLon;
        return;
    }
    double dLat = transformLat(wgsLon - 105.0, wgsLat - 35.0);
    double dLon = transformLon(wgsLon - 105.0, wgsLat - 35.0);
    double radLat = wgsLat / 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);
    gcjLat = wgsLat + dLat;
    gcjLon = wgsLon + dLon;
}

void gcj02ToWgs84(double gcjLat, double gcjLon, double &wgsLat, double &wgsLon) {
    if (outOfChina(gcjLat, gcjLon)) {
        wgsLat = gcjLat;
        wgsLon = gcjLon;
        return;
    }
    double dLat = transformLat(gcjLon - 105.0, gcjLat - 35.0);
    double dLon = transformLon(gcjLon - 105.0, gcjLat - 35.0);
    double radLat = gcjLat / 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);
    wgsLat = gcjLat - dLat;
    wgsLon = gcjLon - dLon;
}

int main() {
    double wgsLat = 39.9042;
    double wgsLon = 116.4074;
    double gcjLat, gcjLon;

    wgs84ToGcj02(wgsLat, wgsLon, gcjLat, gcjLon);
    std::cout << "WGS84 to GCJ02: " << gcjLat << ", " << gcjLon << std::endl;

    double wgsLat2, wgsLon2;
    gcj02ToWgs84(gcjLat, gcjLon, wgsLat2, wgsLon2);
    std::cout << "GCJ02 to WGS84: " << wgsLat2 << ", " << wgsLon2 << std::endl;

    return 0;
}

GCJ02与百度坐标系转换代码

以下是完整的GCJ02与百度坐标系转换代码:

”`cpp #include #include

const double pi = 3.1415926535897932384626;

void gcj02ToBd09(double gcjLat, double gcjLon, double &bdLat, double &bdLon) { double x = gcjLon, y = gcjLat; double z = sqrt(x * x + y * y) + 0.00002 * sin(y * pi); double theta = atan2(y, x) + 0.000003 * cos(x * pi); bdLon = z * cos(theta) + 0.0065; bdLat = z * sin(theta) + 0.006; }

void bd09ToGcj02(double bdLat, double bdLon, double &gcjLat, double &gcjLon) { double x = bdLon - 0.0065, y = bdLat - 0.006; double z = sqrt(x * x + y * y) - 0.00002 * sin(y * pi); double theta = atan2(y, x) - 0.000003 * cos(x * pi); gcjLon = z * cos(theta); gcjLat = z * sin(theta); }

int main() { double gcjLat = 39.9042; double gcjLon = 116.4074; double bdLat, bdLon;

gcj02ToBd09(gcjLat, gcjLon, bdLat, bdLon);
std::cout << "GCJ02 to BD09: " << bdLat << ", " << bdLon << std::endl;
推荐阅读:
  1. C++怎么用winapi socket实现局域网语音通话功能
  2. C++如何实现简易通讯录管理系统

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++

上一篇:MySql多级菜单查询怎么实现

下一篇:C语言中的运算符和结合性问题怎么解决

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》