NMEA的GPGGA数据包解析 字符转数字

1 篇文章 0 订阅
1 篇文章 0 订阅

GPGGA是NMEA协议下的数据包,是GPS数据输出格式语句,是一帧GPS定位的主要数据,也是NMEA格式使用最广的数据之一。该语句包括17个字段。

例如
	$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh<CR><LF>
	$GPGGA,021850.00,2233.51747,N,11356.58160,E,1,09,0.97,69.2,M,-2.7,M,,*7A

<1> UTC时间,hhmmss(时分秒)格式
<2>纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
<3> 纬度半球N(北半球)或S(南半球)
<4> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
<5> 经度半球E(东经)或W(西经)
<6> GPS状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算 只有为1的时候为有效定位数据
<7> 正在使用解算位置的卫星数量(00~12)(前面的0也将被传输)
<8> HDOP水平精度因子(0.5~99.9)
<9> 海拔高度(-9999.9~99999.9)
<10> 地球椭球面相对大地水准面的高度
<11> 差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
<12> 差分站ID号0000~1023(前面的0也将被传输,如果不是差分定位将为空)
<13> 检验值

读取数据

纬度计算:2238.5260
(1) 2238.5260 ÷ 100 = 22(向下取整)
(2)385260 ÷ 60 = 6421
得到以°的纬度坐标22.6421°
经度同操作

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>

using std::string;
double getnum(const char *str, int star, int end)
{
	int len = end - star, index;
	double answer = 0, answer2= 0, answer3 = 0;
	bool flag = true;
	for (int i = star; i < end + 1 ; i++)
	{
		//printf("char = %c, answer = %.4f, answer2 = %.4f\n", str[i], answer, answer2);
		if (str[i] == '.')
		{
			flag = false;
			index = i + 1;
			continue;
		}
		if (flag)
		{
			answer = answer * 10 + (str[i] - '0');
		}
		else 
		{
			answer2 = answer2 * 0.1 + (str[end - (i - index)] - '0');
		}
	}
	answer2 = answer2 * 0.1;
	answer3 = int(answer) % 100;
	answer = floor(answer / 100);
	printf("answer2 = %f , answer3 = %f\n", answer2, answer3);
	answer2 = (answer3+ answer2) / 60;
	return answer = answer + answer2;

}
int main()
{
    std::cout << "Hello World!\n";
	const char* GPGGA = "$GPGGA,054514.000,2238.5260,N,11401.9686,E,1,7,1.27,89.2,M,-2.3,M,,*7F";
	uint8_t *p1;
	int len;
	len = strlen(GPGGA);
	p1 = (uint8_t*)strstr((const char *)GPGGA, "GPGGA"); // 查找字符串第一次出现“GPGGA”的位置
	if (p1 == NULL)
	{
		printf("data is error!\n");
	}
	else
	{
		int sum = GPGGA[1];
		for (int i = 2; i < len - 5; i++)
		{
			sum ^= GPGGA[i];
		}
		char buf[2];
		int k = sum / 16;
		printf("k = %d\n", k);
		if (k > 9 && k < 16)
		{
			buf[0] = k - 9 + 'A';
		}
		else
		{
			buf[1] = k - 9 + '0';
		}
		int m = sum % 16;
		printf("m = %d\n", m);
		if (m > 9 && m < 16)
		{
			buf[1] = m - 9 + 'A';
		}
		else
		{
			buf[1] = m - 9 + '0';
		}
		if (GPGGA[len - 4] == buf[0] || GPGGA[len - 3] == buf[1])
		{
			printf("无效\n");
		}
		else
		{
			int count = 0, save[20];//找到每一个逗号的位置  存储坐标
			for (int j = 0; j < len; j++)
			{
				if (GPGGA[j] == ',')
				{
					save[count] = j + 1;
					count++;
				}
			}
			double latitude = 0, longitude = 0;
			latitude = getnum(GPGGA, save[1], save[2] - 2);
			printf("latitude = %.6f \n", latitude);
			longitude = getnum(GPGGA, save[3], save[4] - 2);
			printf("longitude = %.6f\n", longitude);
		}
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Acnidouwo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值