一、GPS数据格式
a.GPS固定数据输出语句($GPGGA)
这是一帧GPS定位的主要数据,也是使用最广的数据。
$GPGGA 语句包括17个字段:语句标识头,世界时间,纬度,纬度半球,经度,经度半球,定位质量指示,使用卫星数量,水平精确度,海拔高度,高度单位,大地水准面高度,高度单位,差分GPS数据期限,差分参考基站标号,校验和结束标记(用回车符<CR>和换行符<LF>),分别用14个逗号进行分隔。该数据帧的结构及各字段释义如下:
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx<CR><LF>
$GPGGA:起始引导符及语句格式说明(本句为GPS定位数据);
<1> UTC时间,格式为hhmmss.sss;
<2> 纬度,格式为ddmm.mmmm(第一位是零也将传送);
<3> 纬度半球,N或S(北纬或南纬)
<4> 经度,格式为dddmm.mmmm(第一位零也将传送);
<5> 经度半球,E或W(东经或西经)
<6> 定位质量指示,0=定位无效,1=定位有效;
<7> 使用卫星数量,从00到12(第一个零也将传送)
<8> 水平精确度,0.5到99.9
<9> 天线离海平面的高度,-9999.9到9999.9米
M 指单位米
<10> 大地水准面高度,-9999.9到9999.9米
M 指单位米
<11> 差分GPS数据期限(RTCM SC-104),最后设立RTCM传送的秒数量
<12> 差分参考基站标号,从0000到1023(首位0也将传送)。
* 语句结束标志符
xx 从$开始到*之间的所有ASCII码的异或校验和
<CR> 回车
<LF> 换行
b.可视卫星状态输出语句($GPGSV)
例2:$GPGSV,2,1,08,06,33,240,45,10,36,074,47,16,21,078,44,17,36,313,42*78
标准格式: $GPGSV,(1),(2),(3),(4),(5),(6),(7),…(4),(5),(6),(7)*hh(CR)(LF)
各部分含义为:
(1)总的GSV语句电文数;2;
(2)当前GSV语句号:1;
(3)可视卫星总数:08;
(4)卫星号:06;
(5)仰角(00~90度):33度;
(6)方位角(000~359度):240度;
(7)信噪比(00~99dB):45dB(后面依次为第10,16,17号卫星的信息);
*总和校验域;
hh 总和校验数:78;
(CR)(LF)回车,换行。
注:每条语句最多包括四颗卫星的信息,每颗卫星的信息有四个数据项,即:
(4)-卫星号,(5)-仰角,(6)-方位角,(7)-信噪比。
c.当前卫星信息($GSA)
$GPGSA,<1>,<2>,<3>,<3>,,,,,<3>,<3>,<3>,<4>,<5>,<6>,<7>
<1>模式 :M = 手动, A = 自动。
<2>定位型式 1 = 未定位, 2 = 二维定位, 3 = 三维定位。
<3>PRN 数字:01 至 32 表天空使用中的卫星编号,最多可接收12颗卫星信息。
<4> PDOP位置精度因子(0.5~99.9)
<5> HDOP水平精度因子(0.5~99.9)
<6> VDOP垂直精度因子(0.5~99.9)
<7> Checksum.(检查位).
d.推荐定位信息(RMC)
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh
<1> UTC时间,hhmmss(时分秒)格式
<2> 定位状态,A=有效定位,V=无效定位
<3> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
<4> 纬度半球N(北半球)或S(南半球)
<5> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
<6> 经度半球E(东经)或W(西经)
<7> 地面速率(000.0~999.9节,前面的0也将被传输)
<8> 地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
<9> UTC日期,ddmmyy(日月年)格式
<10> 磁偏角(000.0~180.0度,前面的0也将被传输)
<11> 磁偏角方向,E(东)或W(西)
<12> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
e.地面速度信息(VTG)
$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh
<1> 以真北为参考基准的地面航向(000~359度,前面的0也将被传输)
<2> 以磁北为参考基准的地面航向(000~359度,前面的0也将被传输)
<3> 地面速率(000.0~999.9节,前面的0也将被传输)
<4> 地面速率(0000.0~1851.8公里/小时,前面的0也将被传输)
<5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
以下是本人截取到的数据中的一部分:
GPRMC解析 表示推荐使用的最小GPS数据
$GPRMC 起始标识
102220.00 UTC 时间 北京时间需要再加8小时,所以应该是18:22:20。
A 表示有效定位,如果是V就表示无效定位。
3111.90722 纬度,北纬31.119072度。
N 表示北半球,如果是S则表示南半球。
12137.51645 经度,东经121.3751645度。
E 表示东经,如果是W则表示西经。
0.000 地面速度为0。
空数据 表示方位角。
130108 UTC日期,表示2008年1月13日。
空数据 表示磁北
空数据 表示磁北方向
A 表示GPS锁定
*71 表示校验和
GPGLL解析 表示经纬度定位数据
$GPGLL 起始标识
3111.90722 纬度,北纬31.119072度。
N 表示北半球,如果是S则表示南半球。
12137.51645 经度,东经121.3751645度。
E 表示东经,如果是W则表示西经。
102219.00 UTC 时间 北京时间需要再加8小时,所以应该是18:22:19。
A 表示有效定位,如果是V就表示无效定位。
A 表示GPS锁定
*69 表示校验和
GPGSV解析 表示观测到的GPS卫星的数据
$GPGSV 起始标识
2 观测数据的行数,这里是2,因此有两行$GPGSV开头的数据。
1 观测数据的行数索引,本行为第一行。
08 观测到的卫星个数。
02 卫星编号。
34 海拔,34度。
133 方位角,133度。
37 SNR(信噪比),37dBHz。
26,78,242,46 这是卫星编号为26的卫星数据,格式同上。
06,32,275,45 这是卫星编号为06的卫星数据,格式同上。
15,68,237,43 这是卫星编号为15的卫星数据,格式同上。
*72 表示校验和
GPGSA解析 表示DOP(精度衰减因子)以及观测到的卫星编号
$GPGSA 起始标识。
A 表示自动2D/3D锁定,如果为M表示手动锁定。
3 锁定状态,表示3D锁定,如果为1表示无锁定,为2表示2D锁定。
02,26,06,15,29,21,24,,,,,, 这段为观测到的卫星编号。
2.37 表示位置DOP。
1.60 表示水平DOP。
1.75 表示垂直DOP。
*0A 表示校验和。
GPGGA解析 表示锁定的数据
$GPGGA 起始标识
102219.00 UTC 时间 北京时间需要再加8小时,所以应该是18:22:19。
3111.90722 纬度,北纬31.119072度。
N 表示北半球,如果是S则表示南半球。
12137.51645 经度,东经121.3751645度。
E 表示东经,如果是W则表示西经。
1 表示GPS锁定(2D/3D)。
07 表示被使用的卫星个数。
1.60 表示水平DOP。
11.1 海拔高度,11.1米。
M 单位米。
8.4 大地水平面高度,8.4米。
M 单位米。
空数据 表示Age of Differential Corrections,DGPS使用的参数。
*51表示校验和。
$GPVTG,,T,,M,0.000,N,0.000,K,A*23
GPVTG解析 表示速度及方位角
$GPVTG 起始标识
空数据 表示方位角
T 表示真北
空数据 表示方位角
M 表示磁北
0.000 表示速度
N 表示速度单位,节。
0.000 表示速度
K 表示速度单位,千米每小时
A 表示GPS 锁定
*23 表示校验和
二、处理GPS数据
- //获得GPS参数,先将GPS数据存在m_strRecv字符串
- //注意:由于是定时接收,所以在这个字符串的头和尾都可能存在
- // 不完整的NMEA输出字符串,在处理时要特别注意
- //返回:TRUE(格式正确);FALSE(格式错误)
- BOOL CGPSDlg::GetGPSParam()
- {
- int i,j;
- CString str,strNEMA;
- //先判断是否接收到数据
- if (m_strRecv.IsEmpty())
- return FALSE;
- //若字符串不是以'$'开头的,必须删掉这部分不完整的
- if (m_strRecv[0] != '$')
- {
- i = m_strRecv.Find('/n', 0);
- if (i == -1)
- return FALSE; //尾部未接收完整,必须等接收完后才能删除
- m_strRecv.Delete(0, i+1); //尾部已接收完整(尾部为/r/n结束),删除不完整的部分
- }
- //截取完整的NMEA-0183输出语句(m_strRecv中可能有多条语句,每条间以/r/n分隔)
- for (;;)
- {
- i = m_strRecv.Find('/n', 0);
- if (i == -1)
- break; //所有的完整输出语句都已经处理完毕,退出循环
- //截取完整的NMEA-0183输出语句
- strNEMA = m_strRecv.Left(i+1);
- m_strRecv.Delete(0, i+1);
- //下面对各种输出语句进行分别处理
- if (strNEMA.Find("$GPRMC",0) == 0)
- {
- //该输出语句中的各项以','分隔
- for (i=j=0; strNEMA[i]!='/r'; i++) //j为逗号的计数器
- {
- if (strNEMA[i] == ',')
- {
- j++;
- str = "";
- for (i++; strNEMA[i]!=','&&strNEMA[i]!='/r'; i++)
- str += strNEMA[i]; //str为某项的值
- i--;
- //对各项数据分别处理
- switch (j)
- {
- case 1: //时间(UTC)
- m_strTime = str.Left(6);
- m_strTime.Insert(2, ':');
- m_strTime.Insert(5, ':');
- break;
- case 2: //状态(A-数据有效;V-数据无效,还未定位)
- if (str == "A")
- m_strStatus = "有效数据";
- else if(str == "V")
- m_strStatus = "正在定位...";
- else
- m_strStatus = "非法数据格式";
- break;
- case 3: //纬度(ddmm.mmmm)
- str.Insert(2, "度");
- str += "分";
- m_strLatitude = str;
- break;
- case 4: //纬度指示(N-北纬;S-南纬)
- if (str == "N")
- m_strLatitude.Insert(0, "北纬");
- else
- m_strLatitude.Insert(0, "南纬");
- break;
- case 5: //经度(dddmm.mmmm)
- str.Insert(3, "度");
- str += "分";
- m_strLongitude = str;
- break;
- case 6: //经度指示(E-东经;W-西经)
- if (str == "E")
- m_strLongitude.Insert(0, "东经");
- else
- m_strLongitude.Insert(0, "西经");
- break;
- case 7: //速度(单位:节)
- m_strSpeed = str;
- break;
- case 8: //航向(单位:度)
- m_strCourse = str;
- break;
- case 9: //日期(UTC)
- m_strDate = "";
- m_strDate += "20";
- m_strDate += str[4];
- m_strDate += str[5];
- m_strDate += "-";
- m_strDate += str[2];
- m_strDate += str[3];
- m_strDate += "-";
- m_strDate += str[0];
- m_strDate += str[1];
- break;
- default:
- break;
- }
- }
- }
- }
- else if (strNEMA.Find("$GPGGA",0) == 0)
- {
- }
- else if (strNEMA.Find("$GPGSA",0) == 0)
- {
- }
- else if (strNEMA.Find("$GPGSV",0) == 0)
- {
- }
- else if (strNEMA.Find("$GPGLL",0) == 0)
- {
- }
- else if (strNEMA.Find("$GPVTG",0) == 0)
- {
- }
- else
- return FALSE; //格式错误
- }
- return TRUE;
- }上面的程序只处理了$GPRMC这种数据,其他的照着这个改一下就行了。上面的程序已经通过测试,没有问题!