恩山无线论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1182|回复: 2

GPS定位解析方法详解

[复制链接]
发表于 2020-5-19 16:12 | 显示全部楼层 |阅读模式
最近使用龙尚的4G模块(U9300C)做GPS定位功能!
ps:U9300C的gps天线区分了有源跟无源的!

一、首先获取GPS信息是通过AT指令获取的,这个可以参考(U9300_1_9x07平台_AT手册_V5.3.9.pdf)

二、GPS信息解析
1、通过4G模块获取到最原始的gps信息如下
  1. +GPSNMEA:
  2. $GPGGA,024922.00,3011.501542,N,12011.789043,E,1,10,0.6,41.7,M,7.0,M,,*674
  3. $GPRMC,024922.00,A,3011.501542,N,12011.789043,E,0.0,83.6,190520,4.4,W,A,V*665A
  4. $GPVTG,83.6,T,88.0,M,0.0,N,0.0,K,A*2E2B2B
  5. $GNGSA,A,2,75,76,86,87,88,,,,,,,,0.9,0.6,0.7,2*396,0.7,1*3E,,1*484,24,1*7
复制代码


2、经度和纬度信息如下
经度:12011.789043
纬度:3011.501542


3、首先将最原始的gps信息转为WGS84(GPS)坐标
参考地址如下
获取NMEA经纬度转换为百度地图API需要的数据https://blog.csdn.net/HeGuang68207/article/details/81814718

转换概率论公式如下
GPS模块输出的数据是NMEA格式,其中GPGGA字段包含我们需要的经纬度信息。
例:$GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,12.2,M,19.7,M,,0000*1F
其中 4250.5589,S,14718.5084,E 就是经度和纬度数据,其格式是
纬度:ddmm.mmmmm(度分)
经度:dddmm.mmmmm(度分)
===========================
转换概率论公式 dd.ddddd = dd + mm.mmmm/60。

===========================
转换的C语言代码如下
double gpsNameToWgs84(double lon_temp)
{
        long lon_Onenet = 0;
        int dd_int = 0;
        long mm_int = 0;
        double lon_Onenet_double = 0;

        lon_Onenet =lon_temp*100000;

        dd_int = lon_Onenet/10000000;

        mm_int = lon_Onenet%10000000;

        double long_mm = (double)mm_int/6;

        lon_Onenet_double = dd_int + (double)mm_int/60/100000;
        return lon_Onenet_double;
}



上面经度 12011.789043
120 + (11.789043)/60 = 120.19648405
---------------------------------------------------------------
上面纬度 3011.501542
30 + (11.501542)/60 = 30.19169236666667

转换以后得到的WGS84坐标(120.19648405,30.19169236666667)

4、前端使用的是百度地图,所以还需要将上面的WGS84坐标转换
参考帖子如下
百度坐标转换,以及国测局、WGS84(GPS)坐标系之间的转换札记
我这边参考的是wgs84tobd09
  1. /**
  2.      * WGS84 转换为 BD-09
  3.      * @param lng
  4.      * @param lat
  5.      * @returns {*[]}
  6.      *
  7.      */
  8.     public String  wgs84tobd09(double lng, double lat){
  9.         //第一次转换
  10.         double dlat = transformlat(lng - 105.0, lat - 35.0);
  11.         double dlng = transformlng(lng - 105.0, lat - 35.0);
  12.         double radlat = lat / 180.0 * PI;
  13.         double magic = Math.sin(radlat);
  14.         magic = 1 - ee * magic * magic;
  15.         double sqrtmagic = Math.sqrt(magic);
  16.         dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  17.         dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
  18.         double mglat = lat + dlat;
  19.         double mglng = lng + dlng;

  20.         //第二次转换
  21.         double z = Math.sqrt(mglng * mglng + mglat * mglat) + 0.00002 * Math.sin(mglat * x_PI);
  22.         double theta = Math.atan2(mglat, mglng) + 0.000003 * Math.cos(mglng * x_PI);
  23.         double bd_lng = z * Math.cos(theta) + 0.0065;
  24.         double bd_lat = z * Math.sin(theta) + 0.006;
  25.         return bd_lng+","+bd_lat;
  26.     }

  27.     private double transformlat(double lng,double lat){
  28.         double ret= -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
  29.         ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
  30.         ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
  31.         ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
  32.         return ret;
  33.     }

  34.     private double transformlng(double lng,double lat){
  35.         double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
  36.         ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
  37.         ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
  38.         ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
  39.         return ret;
  40.     }

  41. 版权声明:本文为CSDN博主「zhg_vincent」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
  42. 原文链接:https://blog.csdn.net/Vincent2014Linux/article/details/98217524
复制代码
改写成C语言以后的代码如下
  1. static double x_PI = 3.14159265358979324 * 3000.0 / 180.0;
  2. static double PI = 3.1415926535897932384626;
  3. static double a = 6378245.0;
  4. static double ee = 0.00669342162296594323;
复制代码



转换成百度地图能识别的坐标(120.20758246,30.19511710)

我的恩山、我的无线 The best wifi forum is right here.
 楼主| 发表于 2020-5-19 16:15 | 显示全部楼层
上面wgs84tobd09函数丢失,在这里补充
  1. static double x_PI = 3.14159265358979324 * 3000.0 / 180.0;
  2. static double PI = 3.1415926535897932384626;
  3. static double a = 6378245.0;
  4. static double ee = 0.00669342162296594323;
复制代码

  1. double transformlat(double lng,double lat){
  2.         double ret= -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * sqrt(abs(lng));
  3.         ret += (20.0 * sin(6.0 * lng * PI) + 20.0 * sin(2.0 * lng * PI)) * 2.0 / 3.0;
  4.         ret += (20.0 * sin(lat * PI) + 40.0 * sin(lat / 3.0 * PI)) * 2.0 / 3.0;
  5.         ret += (160.0 * sin(lat / 12.0 * PI) + 320 * sin(lat * PI / 30.0)) * 2.0 / 3.0;
  6.         return ret;
  7. }

  8. double transformlng(double lng,double lat)
  9. {
  10.         double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * sqrt(abs(lng));
  11.         ret += (20.0 * sin(6.0 * lng * PI) + 20.0 * sin(2.0 * lng * PI)) * 2.0 / 3.0;
  12.         ret += (20.0 * sin(lng * PI) + 40.0 * sin(lng / 3.0 * PI)) * 2.0 / 3.0;
  13.         ret += (150.0 * sin(lng / 12.0 * PI) + 300.0 * sin(lng / 30.0 * PI)) * 2.0 / 3.0;
  14.         return ret;
  15. }


  16. void wgs84tobd09(double lng, double lat)
  17. {
  18.         //第一次转换
  19.         double dlat = transformlat(lng - 105.0, lat - 35.0);
  20.         double dlng = transformlng(lng - 105.0, lat - 35.0);
  21.         double radlat = lat / 180.0 * PI;
  22.         double magic = sin(radlat);
  23.         magic = 1 - ee * magic * magic;
  24.         double sqrtmagic = sqrt(magic);
  25.         dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  26.         dlng = (dlng * 180.0) / (a / sqrtmagic * cos(radlat) * PI);
  27.         double mglat = lat + dlat;
  28.         double mglng = lng + dlng;

  29.         //第二次转换
  30.         double z = sqrt(mglng * mglng + mglat * mglat) + 0.00002 * sin(mglat * x_PI);
  31.         double theta = atan2(mglat, mglng) + 0.000003 * cos(mglng * x_PI);
  32.         double bd_lng = z * cos(theta) + 0.0065;
  33.         double bd_lat = z * sin(theta) + 0.006;
  34.         printf("bd_lng=%.8f,bd_lat=%.8f\n",bd_lng,bd_lat);
  35. }
复制代码
我的恩山、我的无线 The best wifi forum is right here.
发表于 2020-5-19 20:53 | 显示全部楼层
不明觉厉
我的恩山、我的无线 The best wifi forum is right here.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

欢迎大家光临恩山无线论坛上一条 /1 下一条

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )|网站地图

GMT+8, 2023-2-7 20:24

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

| 江苏省互联网有害信息举报中心 举报信箱:js12377@jschina.com.cn 举报电话:025-88802724 | 本站不良内容举报信箱:68610888@qq.com 举报电话:0519-86695797
快速回复 返回顶部 返回列表