GPS经纬度坐标转换_$bdgsv,1,1,03,03,44,189,40,07,50,191,43,02,33,224,-程序员宅基地

技术标签: 经纬度  java  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。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_52070517/article/details/137410910

智能推荐

http-proxy-middleware onProxyRes中文数据乱码的解决方案-程序员宅基地

文章浏览阅读2.9k次。onProxyRes相关代码:option.onProxyRes = function (proxyRes: any, req: any, res: any) { // 参考:https://www.jianshu.com/p/f8ac6e813b96 const oriWriteHead = res.writeHead; const oriWrite = res.write; const oriEnd = res.end; _http-proxy-middleware onproxyres

oracle静态监听配置模板_oracle监听器模板-程序员宅基地

文章浏览阅读428次。oracle监听配置_oracle监听器模板

第三十三章:路由:路由缓存_dst_entry-程序员宅基地

路由缓存是一种存储路由信息的机制,用于提高路由决策的效率。缓存容量可以根据用户设置进行调整。缓存操作主要涉及与协议无关的部分和IPSec相关的处理。其中,最后一个实例中的方法被应用于路由决策,前面的实例用于变换。

elementPlus el-checkbox重名被同时选中及基本使用_elcheckbox 插槽-程序员宅基地

文章浏览阅读801次,点赞2次,收藏3次。然后label是对应的后台需要的id,那么你的checkIdList对应的也是id的数组了。经过了激烈的搜索之后,终于在github/element的issue中发现有人也提了类似的问题。1.显示多选的时候需要是中文显示,但是发送给后台的数据需要是id的数组。以及拿到的checkIdList是以中文名为值的数组。2.有同名的标签,导致选择的时候会被同时选中。主要是使用的时候出现了一点问题,问题如下。將一开始的代码改成这样,_elcheckbox 插槽

Caused by: org.xml.sax.SAXParseException; lineNumber: 17; columnNumber: 78; cvc-elt.1: 找不到元素 'beans'_: org.xml.sax.saxparseexception; linenumber: 8; co-程序员宅基地

文章浏览阅读7.9k次,点赞7次,收藏8次。说明在做一个springMVC的项目时出现下面的错误具体错误信息如下TypeException ReportMessageServlet.init() for servlet springmvc threw exceptionDescriptionThe server encountered an unexpected condition that prevented it fr..._: org.xml.sax.saxparseexception; linenumber: 8; columnnumber: 75; cvc-elt.1:

Casbin访问控制框架入门详解及Java案例示范-程序员宅基地

文章浏览阅读2.3w次,点赞10次,收藏30次。Casbin 是一个强大的、高效的开源访问控制框架,其权限管理机制支持多种访问控制模型。Casbin 可以:默认的请求格式为{subject, object, action}。2. 具有访问控制模型model和策略policy两个核心概念。3. 支持RBAC中的多层角色继承,不止主体可以有角色,资源也可以具有角色。4. 支持内置的超级用户 例如:root 或 administrator。超级用户可以执行任何操作而无需显式的权限声明。..._casbin

随便推点

Element-ui中的分页(pagination)组件的current-page属性不同步更新视图的坑_elementui 分页对象里面的值 跟页面不同步-程序员宅基地

文章浏览阅读7.2k次,点赞5次,收藏11次。Element-ui中的分页(pagination)组件的current-page属性不同步更新视图的坑_elementui 分页对象里面的值 跟页面不同步

build.sbt的定义格式-程序员宅基地

文章浏览阅读363次。一个简单的build.sbt文件内容如下:name := "hello" // 项目名称organization := "xxx.xxx.xxx" // 组织名称version := "0.0.1-SNAPSHOT" // 版本号scalaVersion := "2.9.2" // 使用的Scala版本号// 其它build定义其中..._build.sbt格式

X86中断-异常-APIC_x86 cpu init中断-程序员宅基地

文章浏览阅读1.5k次。文章目录1 异常向量(vector)2 高级可编程中断控制器(APIC)2.1 Local APIC(LAPIC)**寄存器**优先级中断类型中断发送流程中断接收流程2.2 IO APIC寄存器2.3 扩展xAPIC(extended APIC)x2APIC2.4 MSI(Message Signaled Interrupt)Message Address RegisterMessage Data Register优点缺点2.5 MSI-X3 中断/异常处理3.1 IDT3.2 中断/异常处理流程3.3_x86 cpu init中断

Tomcat与JDK版本对应关系,Tomcat各版本特性_java2023.2.1适配多少的tomcat-程序员宅基地

文章浏览阅读972次,点赞2次,收藏3次。文章目录 Alpha / Beta / Stable Apache Tomcat 9.x Apache Tomcat 8.x Apache Tomcat 7.x Apache Tomcat 6.x Apache Tomcat是一个开源软件实现了Java Servlet和Java Server Pages技术。不同版本的Servlet和JSP规范可使用不同版本的Apache Tomcat。Tomcat与JDK版本对应关系为:Servlet规格 JSP规范 EL规._java2023.2.1适配多少的tomcat

【解决方案】EasyGBS国标云平台助力智慧公厕系统建设-程序员宅基地

文章浏览阅读1.2k次。作为一个重要的、不可或缺的公共空间,公共厕所是必须在城市发展及其规划中确定的公共产品。而公共厕所的设施档次、保洁质量都代表着一个城市的文明程度和 "窗口”形象。公共厕所是体现人文情怀的标尺,一个小小的公厕,体现了一座城市的文明。智慧公厕是智慧城市管理系统的神经末梢,是一种新型的公共厕所信息化建设与管理模式,其借助物联网技术、传感感知技术、云计算、大数据等高新技术,结合公共厕所科学管养、智慧监测、联网管理等创新模式的要求,所整合而成的业务管理系统,能实现公共厕所查找容易、引导清晰、无味无臭、干净整洁、管养

Python常考面试题汇总(附答案)_少儿编程python面试题-程序员宅基地

文章浏览阅读760次。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python 垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。它是一个带状态的对象,调用 next 方法的时候返回容器中的下一个值,可以说任何实现了iter和 next 方法的对象都是迭代器,iter返回迭代器自身,next 返回容器中的下一个值,如果容器中没有更多元素了,则抛异常。理论上是需要被回收的。_少儿编程python面试题

推荐文章

热门文章

相关标签