GNRMC解析

// GNRMC_Analysis.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string.h>
#include <stdlib.h>   
#include <stdio.h>

// http://baike.baidu.com/link?url=OVUwBFU0AmHo3G3KfjZ431T0m8aBoTn3vIegc9oFlD6ie-rxp2zyYYYyE3dIxb9XnySxKVu_tfLCII2UoNMvOK
// $GNRMC,092846.400,A,3029.7317,N,10404.1784,E,000.0,183.8,070417,,,A*73

/*
$GNRMC,
092846.400, // UTC时间,hhmmss.sss(时分秒.毫秒)格式
A, // 定位状态,A=有效定位,V=无效定位
3029.7317,N, // 纬度
10404.1784,E, // 经度
000.0, // 地面速率
183.8, // 地面航向
070417, // UTC日期
, // 磁俯角
, // 磁方向角
A*73 // 模式指示
*/

struct GNRMC_Info
{
unsigned int year;
unsigned char month;
unsigned char day;
unsigned char hour;
unsigned char Minute;
unsigned char second;

unsigned int longitude; // 经度
unsigned char longitude_suffix; // 经度半球E(东经)或W(西经)

unsigned int latitude; // 纬度
unsigned char latitude_suffix; // 纬度半球N(北半球)或S(南半球)
unsigned char position_valid; // 定位是否有效

};

int comma_split(unsigned char* pstr,char* buf,int buflen,int s,int e )
{
int i , k ;
int commaCount = 0;
int rc = -1;
i=k=0;
if( e <= s )
{
return -1;
}
while(pstr[i]!=‘\0‘)
{
if( pstr[i]==‘,‘)
{
commaCount++;
}
if( commaCount == s )
{
k = ++i;
break;
}
i++;
}

while(pstr[i]!=‘\0‘)
{
if( pstr[i]==‘,‘)
{
commaCount++;
}
if( commaCount == e )
{
if( i - k + 1 > buflen)
{
return -1;
}
memset(buf,0,sizeof(buf));
memcpy(buf,pstr+k,i-k);

rc = i - k;
buf[rc] =‘\0‘;
printf("%s\n",buf);
break;
}
i++;
}
return rc;
}

int GNRMC_Parse(unsigned char* pstr,struct GNRMC_Info* pGNRMCInfo )
{
int len = 0;
int commaCount=0;
double temp = 0;
char buf[32]={0};
// 计算字符串长度
while(pstr[len] != ‘\0‘ )
{
if( pstr[len] == ‘,‘)
{
commaCount++;
}
len++;
}
// 逗号个数是12个
if( commaCount != 12 )
{
return -1;
}
// 判断开始字符是:$GNRMC
if( ! ((pstr[0]== ‘$‘) && (pstr[1]== ‘G‘) && (pstr[2]== ‘N‘) && (pstr[3]== ‘R‘) && (pstr[4]== ‘M‘) && (pstr[5]== ‘C‘)))
{
return -1;
}
// 判断结束字符是:\r\n
if( (pstr[len-2]!= ‘\r‘) && (pstr[len-1]!= ‘\n‘) )
{
return -1;
}

// UTC时间:第1个逗号与第2个逗号之前 (eg:092846.400 hhmmss.sss )
len = comma_split(pstr,buf,sizeof(buf),1,2);
if( len < 0 )
{
return -1;
}
pGNRMCInfo->hour = (buf[0]-‘0‘)*10+(buf[1]-‘0‘);
pGNRMCInfo->Minute = (buf[2]-‘0‘)*10+(buf[3]-‘0‘);
pGNRMCInfo->second = (buf[4]-‘0‘)*10+(buf[5]-‘0‘);

// 定位状态:第2个逗号与第3个逗号之前
len = comma_split(pstr,buf,sizeof(buf),2,3);
if( len != 1 )
{
return -1;
}
pGNRMCInfo->position_valid = ((buf[0]==‘A‘ ) ?1:0) ;

// 经度
len = comma_split(pstr,buf,sizeof(buf),3,4);
if( len < 0 )
{
return -1;
}
temp = atof(buf);
temp = temp*10000;
pGNRMCInfo->longitude = temp;

// 经度半球E(东经)或W(西经)
len = comma_split(pstr,buf,sizeof(buf),4,5);
if( len != 1 )
{
return -1;
}
pGNRMCInfo->longitude_suffix = buf[0];

// 纬度
len = comma_split(pstr,buf,sizeof(buf),5,6);
if( len < 0 )
{
return -1;
}
temp = atof(buf);
temp = temp*10000;
pGNRMCInfo->latitude = temp;

// 纬度半球N(北半球)或S(南半球)
len = comma_split(pstr,buf,sizeof(buf),6,7);
if( len != 1 )
{
return -1;
}
pGNRMCInfo->latitude_suffix = buf[0];

// UTC日期:ddmmyy(日月年)格式 eg:070417
len = comma_split(pstr,buf,sizeof(buf),9,10);
if( len < 0 )
{
return -1;
}
pGNRMCInfo->day = (buf[0]-‘0‘)*10+(buf[1]-‘0‘);
pGNRMCInfo->month = (buf[2]-‘0‘)*10+(buf[3]-‘0‘);
pGNRMCInfo->year = (buf[4]-‘0‘)*10+(buf[5]-‘0‘) + 2000;

return 0;
}

int main(int argc, char* argv[])
{
struct GNRMC_Info GNRMC;
char* p= "$GNRMC,092846.400,A,3029.7317,N,10404.1784,E,000.0,183.8,070417,,,A*73\r\n";
GNRMC_Parse((unsigned char *)p,&GNRMC);

printf("时间:%d-%d-%d %d:%d:%d\n",GNRMC.year,GNRMC.month,GNRMC.day,GNRMC.hour,GNRMC.Minute,GNRMC.second);
printf("%u %c ---- %u %c 定位是否有效果:%d\n",GNRMC.longitude,GNRMC.longitude_suffix,GNRMC.latitude,GNRMC.latitude_suffix,GNRMC.position_valid);

getchar();
return 0;
}

时间: 2024-11-29 00:26:33

GNRMC解析的相关文章

GPS北斗双模技术应用开发研究--数据解析

上一篇文章大家介绍了几个重要的概念,那下面我们就来解析一下这样的双模输出log,在解析之前我们来看看各个重要标准字段的意义.笔者在实际开发中只用到了其中的四个,分别是GGA,GSA,GSV,RMC,GLL,当然还有其他一些字段,感觉有些是重复的,根据需要解析就好了.下面就分别介绍一下: $XXGGA,(1),(2),(3),(4),(5),(6),(7),(8),(9),M,(10),M,(11),(12)*hh(CR)(LF) 各部分所对应的含义为: (1)定位UTC时间:05时09分01秒

C++工程编译之“error LNK2001: 无法解析的外部符号”

今天一整天都在折腾“error LNK2001: 无法解析的外部符号”,就在头疼不已的时候,总算是找到问题原因了:各个动态链接库的编译方式必须统一才行,要不然很容易对库函数的引用产生冲突.简单来说就是,如果使用的第三方函数库编译方式采用/MD,那么主工程也应该使用/MD.我使用了libevent,而主工程默认采用/MT,所以需要忽略一大堆的函数库,我还纳闷呢,怎么会这么奇怪!!今天总算是解决了长久以来的困惑了. 下面引用一篇文章的描述:[Z]VC运行库版本不同导致链接.LIB静态库时发生重复定义

防止恶意解析——禁止通过IP直接访问网站

一.什么是恶意解析 一般情况下,要使域名能访问到网站需要两步,第一步,将域名解析到网站所在的主机,第二步,在web服务器中将域名与相应的网站绑定.但是,如果通过主机IP能直接访问某网站,那么把域名解析到这个IP也将能访问到该网站,而无需在主机上绑定,也就是说任何人将任何域名解析到这个IP就能访问到这个网站.可能您并不介意通过别人的域名访问到您的网站,但是如果这个域名是未备案域名呢?一旦被查出,封IP.拔线甚至罚款的后果都是需要您来承担的.某些别有用心的人,通过将未备案域名解析到别人的主机上,使其

.NET深入解析LINQ框架(五:IQueryable、IQueryProvider接口详解)

阅读目录: 1.环路执行对象模型.碎片化执行模型(假递归式调用) 2.N层对象执行模型(纵横向对比链式扩展方法) 3.LINQ查询表达式和链式查询方法其实都是空壳子 4.详细的对象结构图(对象的执行原理) 5.IQueryable<T>与IQueryProvider一对一的关系能否改成一对多的关系 6.完整的自定义查询 1]. 环路执行对象模型.碎片化执行模型(假递归式调用) 这个主题扯的可能有点远,但是它关系着整个LINQ框架的设计结构,至少在我还没有搞懂LINQ的本意之前,在我脑海里一直频

.NET深入解析LINQ框架(一:LINQ优雅的前奏)

阅读目录: 1.LINQ简述 2.LINQ优雅前奏的音符 2.1.隐式类型 (由编辑器自动根据表达式推断出对象的最终类型) 2.2.对象初始化器 (简化了对象的创建及初始化的过程) 2.3.Lambda表达式 (对匿名方法的改进,加入了委托签名的类型推断并很好的与表达式树的结合) 2.4.扩展方法 (允许在不修改类型的内部代码的情况下为类型添加独立的行为) 2.5.匿名类型 (由对象初始化器推断得出的类型,该类型在编译后自动创建) 2.6.表达式目录树(用数据结构表示程序逻辑代码) 3.LINQ

.NET深入解析LINQ框架(二:LINQ优雅的前奏)

阅读目录: 1.LINQ框架的主要设计模型 1.1.链式设计模式 (以流水线般的链接方式设计系统逻辑) 1.2.链式查询方法(逐步加工查询表达式中的每一个工作点) 2.LINQ框架的核心设计原理 2.1.托管语言之上的语言(LINQ查询表达式) 2.2.托管语言构造的基础(LINQ依附通用接口与查询操作符对应的方法对接) 2.3.深入IEnumerable.IEnumerable<T>.Enumerable(LINQ to Object框架的入口) 2.4.深入IQueryable.IQuer

.NET深入解析LINQ框架(三:LINQ优雅的前奏)

阅读目录: 1.动态LINQ查询(动态构建Expression<T>表达式树) 2.DLR动态语言运行时(基于CLR之上的动态语言运行时) 1].动态LINQ查询(动态构建Expression<T>表达式树) 什么是动态LINQ查询?LINQ的编写是静态的,因为C#是基于静态类型系统原理设计的,在编写时已经确定类型,也就是在编译时就已经知道将要执行什么样的查询,条件是什么.排序方式是什么等等.那么很大一部分应用场合中我们需要根据用户的选择来查询数据源,以往我们都是通过判断的方式来拼

.NET深入解析LINQ框架(六:LINQ执行表达式)

阅读目录: 1.LINQ执行表达式 在看本篇文章之前我假设您已经具备我之前分析的一些原理知识,因为这章所要讲的内容是建立在之前的一系列知识点之上的,为了保证您的阅读顺利建议您先阅读本人的LINQ系列文章的前几篇或者您已经具备比较深入的LINQ原理知识体系,防止耽误您的宝贵时间. 到目前为止我们对LINQ的执行原理已经很清楚了,从它的前期构想到它真正为我们所用都有足够的证据,但是似乎问题并没有我们想的那么简单,问题总是在我们使用中频频出现尤其是新技术的使用,当然有问题才能有进步. 一:LINQ执行

MyBatis框架中Mapper映射配置的使用及原理解析(七) MapperProxy,MapperProxyFactory

从上文<MyBatis框架中Mapper映射配置的使用及原理解析(六) MapperRegistry> 中我们知道DefaultSqlSession的getMapper方法,最后是通过MapperRegistry对象获得Mapper实例: public <T> T getMapper(Class<T> type, SqlSession sqlSession) { final MapperProxyFactory<T> mapperProxyFactory =