GPS经纬度坐标转换

在淘宝买的ATGM336H
用串口工具在室外读取了下面的数据

这些字符串是GPS定位设备输出的NMEA 0183格式的数据。
NMEA 0183是一种用于在船舶、飞机和其他移动设备中传输位置、速度和时间等信息的标准协议。


$BDGSV,39,,,27*62 22:29:38.654 
$GNRMC,142939.000,A,3036.7460,K,A*23 22:29:38.754
$GNZDA,142939.000,31,03,2024,00,00*49 22:29:38.858 
$GPTXT,01,01,0
$GNGGA,142940.000,3036.74671,N,10408.54235,E,1,07,1.2,573.5,M,0.0,M,,*75 22:29:38.958 
$GNGLL,3036.74671,N,10408.54235,E,142940.000,A,A*40 22:29:39.061 
$GPGSA,A,3,05,15,20,23,29,195,,,,,,,2.2,1.2,1.9*0D 22:29:39.161 
$BDGSA,A,3,19,,,,,,,,,,,SV,3,1,09,05,33,064,32,10,,,27,13,40,04,216,37*48 22:29:39.263 -> $GPGSV,3,3,09,195,42,139,19*78 22:29:39.366
$BDGSV,1,1,04,02,,,33,09,,,29,19,45,275,33,39,,,27*5A 22:29:39.468 
$GNRMC,142940.000,A,3036.74671,N,10408.54235,E,0.00,0.00,310324,,,A*70 

比较有用的是GNGGA,有经纬度,有卫星数,有海拔之类的信息

但是他使用的数据需要转换先转换成WGS84再转换成GCJ02
而百度地图/高德地图的一般接受GCJ02

1.获取对应串口数据的经纬度(这里是C代码)

//主要是靠索引来查询找到数据
void GPSTask(void *parameter){for(;;){delay(100); String GpsMsg=Serial2.readStringUntil('\n');Serial.println(GpsMsg);int isIndex=GpsMsg.indexOf("$GNRMC");if (isIndex==-1){continue;}lon = extractLongitude(GpsMsg);lat = extractLatitude(GpsMsg);}
}// 提取经度信息
float extractLongitude(String nmea) {int pos = 0; // 找到第一个逗号的位置for (int i = 0; i < 5; i++) {pos = nmea.indexOf(",", pos) + 1; // 找到第三个逗号的位置if (pos==-1){return 0;}}String longitudeStr = nmea.substring(pos, nmea.indexOf(",", pos));if (longitudeStr==""){return 0;}float longitude = longitudeStr.toFloat();return longitude;
}// 提取纬度信息
float extractLatitude(String nmea) {int pos = 0; // 找到第一个逗号的位置for (int i = 0; i < 3; i++) {pos = nmea.indexOf(",", pos) + 1; // 找到第五个逗号的位置if (pos==-1){return 0;}}String latitudeStr = nmea.substring(pos, nmea.indexOf(",", pos));if (latitudeStr==""){return 0;}float latitude = latitudeStr.toFloat();return latitude;
}

2.将串口的数据转成WGS84

public static double[] SerialtoWGS84(String lng, String lat) {int lngIndex = lng.indexOf(".") - 2;int latIndex = lat.indexOf(".") - 2;if (lngIndex < 0 || latIndex < 0){return null;}double lngDouble1 = Double.parseDouble(lng.substring(0, lngIndex));double lngDouble2 = Double.parseDouble(lng.substring( lngIndex));double lngDouble = lngDouble1 + lngDouble2 / 60;double latDouble1 = Double.parseDouble(lat.substring(0, latIndex));double latDouble2 = Double.parseDouble(lat.substring( latIndex));double latDouble = latDouble1 + latDouble2 / 60;if (lngDouble > 0 && latDouble > 0){return new double[]{lngDouble, latDouble};}return null;}

3.将WGS84的数据转成GCJ02

 public static double ee = 0.00669342162296594323;  //偏心率平方public static double a = 6378245.0;//  # 长半轴/*** GPS84转GCJ02(火星坐标系)** @param lng_wgs WGS84坐标系的经度* @param lat_wgs WGS84坐标系纬度* @return 转换后的GCJ02下经纬度*/public static double[] WGS84toGCJ02(double lng_wgs, double lat_wgs) {if (outOfChina(lng_wgs, lat_wgs)) {return new double[]{lng_wgs, lat_wgs};}double[] GCJ02 = new double[2];double dlat = transformlat(lng_wgs - 105.0, lat_wgs - 35.0);double dlng = transformlng(lng_wgs - 105.0, lat_wgs - 35.0);double radlat = lat_wgs / 180.0 * Math.PI;double magic = Math.sin(radlat);magic = 1 - ee * magic * magic;double sqrtmagic = Math.sqrt(magic);dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * Math.PI);dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * Math.PI);double gcj_lat = lat_wgs + dlat;double gcj_lng = lng_wgs + dlng;GCJ02[0] = gcj_lng;GCJ02[1] = gcj_lat;return GCJ02;}private static double transformlat(double lng, double lat) {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));ret += (20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 *Math.sin(2.0 * lng * Math.PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lat * Math.PI) + 40.0 *Math.sin(lat / 3.0 * Math.PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(lat / 12.0 * Math.PI) + 320 *Math.sin(lat * Math.PI / 30.0)) * 2.0 / 3.0;return ret;}private static double transformlng(double lng, double lat) {double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng +0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 *Math.sin(2.0 * lng * Math.PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lng * Math.PI) + 40.0 *Math.sin(lng / 3.0 * Math.PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(lng / 12.0 * Math.PI) + 300.0 *Math.sin(lng / 30.0 * Math.PI)) * 2.0 / 3.0;return ret;}/*** 判断是否在国内,不在国内不做偏移** @param lng* @param lat* @return*/private static boolean outOfChina(double lng, double lat) {return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);}

WGS84:地球坐标系,是国际上通用的坐标系,设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系GCJ02:火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。在中国使用的地图产品使用的都必须是加密后的坐标
  1. $BDGSV,39,27*62 22:29:38.654:BDGSV表示北斗卫星的可见卫星信息,39表示总共有39颗卫星,但是这个字符串中没有提供具体的卫星信息。

  2. $GNRMC,142939.000,A,3036.7460,K,A*23 22:29:38.754:GNRMC表示推荐的最小定位信息,142939.000表示定位时间,A表示定位有效,3036.7460表示纬度,K表示速度单位为千米/小时,A表示方向有效。

  3. $GNZDA,142939.000,31,03,2024,00,00*49 22:29:38.858:GNZDA表示日期和时间信息,142939.000表示时间,31表示日期,03表示月份,2024表示年份,00表示本地时区的小时偏移量,00表示本地时区的分钟偏移量。

  4. $GPTXT,01,01,0:GPTXT表示文本信息,这个字符串中没有提供具体的文本内容。

  5. $GNGGA,142940.000,3036.74671,N,10408.54235,E,1,07,1.2,573.5,M,0.0,M,*75 22:29:38.958:GNGGA表示全球定位系统定位信息,142940.000表示定位时间,3036.74671表示纬度,N表示北纬,10408.54235表示经度,E表示东经,1表示定位质量指示,07表示使用的卫星数量,1.2表示水平精度因子,573.5表示海拔高度,M表示单位为米,0.0表示大地水准面的高度,M表示单位为米。

  6. $GNGLL,3036.74671,N,10408.54235,E,142940.000,A,A*40 22:29:39.061:GNGLL表示地理定位信息,3036.74671表示纬度,N表示北纬,10408.54235表示经度,E表示东经,142940.000表示定位时间,A表示定位有效,A表示数据来源为GPS。

  7. $GPGSA,A,3,05,15,20,23,29,195,2.2,1.2,1.9*0D 22:29:39.161:GPGSA表示GNSS DOP和活动卫星信息,A表示自动选择2D/3D定位模式,3表示定位模式为3D定位,05、15、20、23、29、195表示使用的卫星编号,2.2表示PDOP(位置精度因子),1.2表示HDOP(水平精度因子),1.9表示VDOP(垂直精度因子)。

  8. $BDGSA,A,3,19,SV,3,1,09,05,33,064,32,10,27,13,40,04,216,3748 22:29:39.263 -> $GPGSV,3,3,09,195,42,139,1978 22:29:39.366:BDGSA表示北斗卫星的DOP和活动卫星信息,A表示自动选择2D/3D定位模式,3表示定位模式为3D定位,19表示使用的卫星编号,SV表示卫星编号的开始,3表示卫星编号的数量,1、09、05、33、064、32、10、27、13、40、04、216、37表示具体的卫星编号。

  9. $BDGSV,1,1,04,02,33,09,29,19,45,275,33,39,27*5A 22:29:39.468:BDGSV表示北斗卫星的可见卫星信息,1表示总共有1颗卫星,1表示当前是第1个字符串,04表示总共有4个字符串,02、33、09、29、19、45、275、33、39、27表示具体的卫星信息。

  10. $GNRMC,142940.000,A,3036.74671,N,10408.54235,E,0.00,0.00,310324,A*70:GNRMC表示推荐的最小定位信息,142940.000表示定位时间,A表示定位有效,3036.74671表示纬度,N表示北纬,10408.54235表示经度,E表示东经,0.00表示速度,0.00表示方向,310324表示日期,A表示数据来源为GPS。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/794883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

考研回忆录【二本->211】

备考时长差不多快一年半&#xff0c;从22年的11月底开始陆陆续续地准备考研&#xff0c;因为开始的早所以整个备考过程显得压力不是很大&#xff0c;中途还去一些地方旅游&#xff0c;我不喜欢把自己绷得太紧。虽然考的不是很好&#xff0c;考完我甚至都没准备复试&#xff0c;…

12-1-CSS 常用样式属性

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 CSS 常用样式属性1 CSS 三角形2 CSS 用户界面样式2.1 什么是界面样式2.2 鼠标…

微电网优化:基于​海象优化算法(Walrus Optimization Algorithm,WOA)​的微电网优化(提供MATLAB代码)

一、微电网优化模型 微电网是一个相对独立的本地化电力单元&#xff0c;用户现场的分布式发电可以支持用电需求。为此&#xff0c;您的微电网将接入、监控、预测和控制您本地的分布式能源系统&#xff0c;同时强化供电系统的弹性&#xff0c;保障您的用电更经济。您可以在连接…

(学习日记)2024.04.02:UCOSIII第三十节:信号量

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

数据库之DDL操作(数据库,表,字段)

Data Definition Language&#xff0c;数据库定义语言&#xff0c;用来定义数据库对象&#xff08;数据库&#xff0c;表&#xff0c;字段&#xff09; 1.数据库操作 1.1查询所有数据库 show databases; 1.2查询当前数据库 show databases(); 1.3创建数据库 create da…

Ps:预览调整 32 位 HDR 图像

由于 HDR 图像的动态范围超出了标准计算机显示器的显示范围。在 Photoshop 中打开 HDR 图像时&#xff0c;图像可能会非常暗或出现褪色现象。 Photoshop 提供了专门的预览调整功能&#xff0c;以使标准显示器显示的 HDR 图像的高光和阴影不会太暗或出现褪色现象。 预览调整设置…

docker的安装及入门指令

目录 一、将docker安装到云服务器步骤 1.更新系统yum版本 2.安装所需依赖 3.添加docker仓库设置(使用的是阿里云) 4.安装docker引擎 5.启动docker并开启自动启动 6. 检查是否安装成功&#xff0c;成功会显示相应版本&#xff0c;否则安装失败 二、docker常用命令 1.从…

最优算法100例之33-数据流的中位数

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。 例如, [2,3,4] 的中位数是 3 [2,3] 的中位…

Map源码解析

基本介绍 其实HashMap底层是个什么东西我们之前也讲过, 就是一个哈希桶(差不多可以看成一个数组), 然后每一个节点又连接着链表/红黑树之类的, 下面让我们看一看具体在源码上是怎样实现的: 常量及其它 -> static final int DEFAULT_INITIAL_CAPACITY 1 << 4; //这个…

如何修改网页显示的小图标(Favicon)

目录 1. 使用自定义Favicon 2. 在vue中设置Favicon 3. 使用Vue插件设置Favicon 网页显示的小图标&#xff0c;通常称为Favicon&#xff08;Favorites Icon&#xff09;&#xff0c;是网站的标识之一&#xff0c;也是浏览器标签页上显示的图标。 1. 使用自定义Favicon 准备图…

Rust个人学习之单元测试

基础标记说明 Rust 是具备内嵌单元测试模块的。在 Rust 中&#xff0c;可以通过在源代码文件的顶部使用 #[test] 属性来标记一个函数作为测试函数。通常&#xff0c;这些测试函数位于与它们测试的源代码相同的文件中&#xff0c;但位于 mod tests 模块中。这是一个常用做法。 …

空和null是两回事

文章目录 前言 StringUtils1. 空&#xff08;empty&#xff09;&#xff1a;字符串&#xff1a;集合&#xff1a; 2. null&#xff1a;引用类型变量&#xff1a;基本类型变量&#xff1a; 3. isBlank总结&#xff1a; 前言 StringUtils 提示&#xff1a;这里可以添加本文要记录…

日志打印的学习之log4j2(二)进阶案例

日志级别简述&#xff1a; trace追踪&#xff0c;就是程序推进一下&#xff0c;可以写个trace输出debug调试&#xff0c;一般作为最低级别&#xff0c;trace基本不用。info输出重要的信息&#xff0c;使用较多warn警告&#xff0c;有些信息不是错误信息&#xff0c;但也要给程…

计算机网络——35什么是网络安全

什么是网络安全 机密性&#xff1a;只有发送方和预订的接收方能否理解传输的报文内容 发送方加密报文接收方解密报文 认证&#xff1a;发送方和接收方需要确认对方的身份报文完整性&#xff1a;发送方、接收方需要确认的报文在传输的过程中或者事后没有被改变访问控制和服务的…

如何通过C++身份证实名认证接口实现实名认证功能

线上平台使用身份核验过程是验证个人身份真实性的过程&#xff0c;对于大多数线上平台来说&#xff0c;自己去开发集成身份证实名认证接口需要耗费大量的人力、物力成本&#xff0c;对此&#xff0c;为助力有需要的企业快速实现实名认证的功能&#xff0c;翔云平台提供了身份证…

利用nginx-http-flv-module实现三种直播

目录 一、说明 二、目标 三、实现 四、直播地址 一、说明 此文在《流媒体服务器的搭建(支持hls)》《搭建nginx-http-flv-module直播系统》之后编写,很多详细内容需要参考它。 流媒体服务器的搭建(支持hls)

力扣爆刷第112天之CodeTop100五连刷46-50

力扣爆刷第112天之CodeTop100五连刷46-50 文章目录 力扣爆刷第112天之CodeTop100五连刷46-50一、148. 排序链表二、22. 括号生成三、70. 爬楼梯四、2. 两数相加五、165. 比较版本号 一、148. 排序链表 题目链接&#xff1a;https://leetcode.cn/problems/sort-list/descriptio…

数据结构——顺序表(C语言)

目录 一、顺序表概念 二、顺序表分类 1.静态顺序表 2.动态顺序表 三、顺序表的实现 1.顺序表的结构体定义 2. 顺序表初始化 3.顺序表销毁 4.顺序表的检验 5.顺序表打印 6.顺序表扩容 7.顺序表尾插与头插 8.尾删与头删 9.在pos处插入数据 10.在pos处删除数据 11.查找数据 …

端盒日记Day02

JS 本本本本本地存储 localStorage 作用&#xff1a;可以将数据永久存储在本地&#xff08;用户电脑&#xff09;&#xff0c;除非手动删除&#xff0c;否则关闭页面也会存在 特性&#xff1a;a.可多窗口&#xff08;页面&#xff09;共享&#xff08;同一浏览器可以共享&a…

若依:一个基于Spring Boot、Spring Security、JWT、Vue和Element的全部开源快速开发平台

若依后台管理系统&#xff1a;一个基于Spring Boot、Spring Security、JWT、Vue和Element的全部开源快速开发平台 一、引言 随着软件开发技术的发展&#xff0c;前后端分离的开发模式逐渐成为主流。这种模式能够提高开发效率&#xff0c;降低维护成本&#xff0c;使前后端工程…