GPS原始坐标转百度地图坐标(纯C代码)

举报
DS小龙哥 发表于 2022/07/05 13:24:35 2022/07/05
【摘要】 得到GPS原始坐标数据之后,想通过百度地图API接口直接显示实际定位。百度对外接口的坐标系并不是GPS采集的真实经 纬度,需要通过坐标转换接口进行转换。

一、环境介绍

GPS模块型号: 中科微电子GPS模块

GPS输出的原始数据帧:

$GNGGA,114955.000,2842.4158,N,11549.5439,E,1,05,3.8,54.8,M,0.0,M,,*4F
$GNGLL,2842.4158,N,11549.5439,E,114955.000,A,A*4D
$GPGSA,A,3,10,31,18,,,,,,,,,,5.7,3.8,4.2*37
$BDGSA,A,3,07,10,,,,,,,,,,,5.7,3.8,4.2*2A
$GPGSV,3,1,10,10,49,184,42,12,16,039,,14,54,341,,18,22,165,23*7B
$GPGSV,3,2,10,22,11,318,,25,51,055,,26,24,205,,29,13,110,*7C
$GPGSV,3,3,10,31,50,287,36,32,66,018,*7F
$BDGSV,1,1,04,03,,,07,05,,,29,07,79,246,33,10,52,232,19*62
$GNRMC,114955.000,A,2842.4158,N,11549.5439,E,0.00,44.25,061117,,,A*4D
$GNVTG,44.25,T,,M,0.00,N,0.00,K,A*14
$GNZDA,114955.000,06,11,2017,00,00*47
$GPTXT,01,01,01,ANTENNA OK*35

二、需求介绍

得到GPS原始坐标数据之后,想通过百度地图API接口直接显示实际定位。

国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ- 02,对地理位置进行首次加密。

百度坐标在此基础上,进行了BD-09二次加密措施,更加保护了个人隐私。

百度对外接口的坐标系并不是GPS采集的真实经 纬度,需要通过坐标转换接口进行转换。

三、C语言代码

下面代码在QtCreator里编写,可以将代码移植到任何支持C语言的环境中编译运行。

#include <QCoreApplication>
#include <QString>
#include <QDebug>
extern C;
{
#include <math.h>;
}

class GPS_Data
{
public:
    double lat; //纬度
    double lng; //经度
    QString GPS_Data;
};
class GPS_Data gps_data;

void GPS_ReadUasrtData();


#define M_PI  3.14159265358979324
double  a = 6378245.0;
double  ee = 0.00669342162296594323;
double  x_pi = M_PI * 3000.0 / 180.0;

double wgs2gcj_lat(double x, double y)
{
   double ret1 = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y  + 0.2 * sqrt(abs(x));
   ret1 += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x  * M_PI)) * 2.0 / 3.0;
   ret1 += (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0;
   ret1 += (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI  / 30.0)) * 2.0 / 3.0;
   return ret1;
}

double  wgs2gcj_lng(double x, double y)
{
    double ret2 = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1  * sqrt(abs(x));
    ret2 += (20.0 *sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x  * M_PI)) * 2.0 / 3.0;
    ret2 += (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0;
    ret2 += (150.0 *sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0  * M_PI)) * 2.0 / 3.0;
    return ret2;
}

void wgs2gcj(double *lat,double *lng)
{
    double dLat = wgs2gcj_lat(*lng - 105.0, *lat - 35.0);
    double dLon = wgs2gcj_lng(*lng - 105.0, *lat - 35.0);
    double radLat = *lat / 180.0 * M_PI;
    double magic = sin(radLat);
    magic = 1 - ee * magic * magic;
    double sqrtMagic = sqrt(magic);
    dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * M_PI);
    dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * M_PI);
    *lat = *lat + dLat;
    *lng = *lng + dLon;
}

void gcj2bd(double *lat,double *lng)
{
   double x = *lng, y = *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);
   *lng = z * cos(theta) + 0.0065;
   *lat = z * sin(theta) + 0.006;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    GPS_ReadUasrtData();

    //得到GPS原始坐标
    double lat=gps_data.lat;
    double lng=gps_data.lng;

    //坐标转换
    wgs2gcj(&amp;lat,&amp;lng);
    gcj2bd(&amp;lat,&amp;lng);

    //得到百度地图的坐标,可以直接在百度地图上显示
    qDebug()&lt;&lt;&quot;纬度: &quot;&lt;&lt;QString(&quot;%1&quot;).arg(lat,0,'g',13);
    qDebug()&lt;&lt;&quot;经度: &quot;&lt;&lt;QString(&quot;%1&quot;).arg(lng,0,'g',13);

    return a.exec();
}


void GPS_ReadUasrtData()
{
    /*GPS的原始数据帧*/
    gps_data.GPS_Data=&quot;$GNGGA,114955.000,2842.4158,N,11549.5439,E,1,05,3.8,54.8,M,0.0,M,,*4F&quot;
            &quot;$GNGLL,2842.4158,N,11549.5439,E,114955.000,A,A*4D&quot;
            &quot;$GPGSA,A,3,10,31,18,,,,,,,,,,5.7,3.8,4.2*37&quot;
            &quot;$BDGSA,A,3,07,10,,,,,,,,,,,5.7,3.8,4.2*2A&quot;
           &quot; $GPGSV,3,1,10,10,49,184,42,12,16,039,,14,54,341,,18,22,165,23*7B&quot;
            &quot;$GPGSV,3,2,10,22,11,318,,25,51,055,,26,24,205,,29,13,110,*7C&quot;
            &quot;$GPGSV,3,3,10,31,50,287,36,32,66,018,*7F&quot;
            &quot;$BDGSV,1,1,04,03,,,07,05,,,29,07,79,246,33,10,52,232,19*62&quot;
            &quot;$GNRMC,114955.000,A,2842.4158,N,11549.5439,E,0.00,44.25,061117,,,A*4D&quot;
            &quot;$GNVTG,44.25,T,,M,0.00,N,0.00,K,A*14&quot;
            &quot;$GNZDA,114955.000,06,11,2017,00,00*47&quot;
            &quot;$GPTXT,01,01,01,ANTENNA OK*35&quot;;

    /*解析GPS模块的数据*/
    //QString lat; //纬度
    //QString lng; //经度
    if(gps_data.GPS_Data.size()&gt;200)
    {
        int index=gps_data.GPS_Data.indexOf(&quot;$GNGGA&quot;);
        if(index&gt;=0)
        {
            QString text=gps_data.GPS_Data.mid(index);
            if(text.size()&gt;60)
            {
                QString lat=text.section(',',2,2);
                QString lng=text.section(',',4,4);
                if(lat.isEmpty()==false &amp;&amp; lng.isEmpty()==false)
                {
                    unsigned int int_data;
                    double s_Longitude,s_latitude;

                    //转换纬度
                    s_latitude=lat.toDouble();

                    s_latitude=s_latitude/100;
                    int_data=s_latitude;//得到纬度整数部分
                    s_latitude=s_latitude-int_data;//得到纬度小数部分
                    s_latitude=(s_latitude)*100;
                    gps_data.lat=int_data+(s_latitude/60.0); //得到转换后的值

                    //转换经度
                    s_Longitude=lng.toDouble();

                    s_Longitude=s_Longitude/100;
                    int_data=s_Longitude;//得到经度整数部分
                    s_Longitude=s_Longitude-int_data; //得到经度小数部分
                    s_Longitude=s_Longitude*100;

                    //gai guo le
                    gps_data.lng=int_data+(s_Longitude/60.0);

                }
            }
        }
        gps_data.GPS_Data.clear();
    }
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。