博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在Windows Mobile和Wince(Windows Embedded CE)下使用.NET Compact Framework进行GPS NMEA data数据分析的开发...
阅读量:5025 次
发布时间:2019-06-12

本文共 15282 字,大约阅读时间需要 50 分钟。

提供GPS功能的Wince和Windows Mobile都需要一个GPS接收器(GPS Receiver)。GPS receiver就像一个收音机,他从太空中各个GPS卫星(Satellites)接收信号,通过自身的算法(一般在Firmware里面)计算出位置等信息,然后以NMEA data的格式输出。GPS receiver就是接收卫星信号转换成NMEA data的设备。

进行GPS的开发需要从GPS receiver取出NMEA data,分析出关心的数据。关心的数据包括经度(Longitude),维度(Latitude)和海拔(Altitude)等等。在Windows Mobile 5以上MS提供了GPS Intermediate Driver,开发人员不再需要自己分析NMEA data了。但是Wince5以及以下版本不提供GPS Intermediate Driver,还是需要自己分析NMEA data来取出关心的信息。本文讲述如何使用C#进行NMEA data的分析。第一眼看,分析NMEA有自己做轮子之嫌,其实了解NMEA的分析也是有好处的,由于各个生产GPS receiver的厂商在硬件工艺和算法的不一样,各个厂商都提供自己扩展的NMEA data,这些数据GPS Intermediate Driver是不支持的,需要自己分析。

NMEA 全称NMEA 0183,是电子与数据的通信规范,也就是协议。实现该协议的设备输出这种规范的数据,其他应用就可以基于这协议分析出相关的数据。NMEA开始用在航海设备上,现在广泛用在GPS设备上,这就是为什么NMEA的原始速度使用Knot(海里/小时)表示。下面是一段GPS NMEA data的范例

 

$GPRMC,
000006
,A,
3754.6240
,S,
14509.7720
,E,
010.8
,
313.1
,
010108
,
011.8
,E
*
6A
$GPGGA,
201033
,
3754.6240
,S,
14509.7720
,E,
1
,
05
,
1.7
,
91.1
,M,
-
1.1
,M,,
*
75
$GPGSA,A,
3
,,
05
,
10
,,,,
21
,,
29
,
30
,,,
2.9
,
1.7
,
1.3
*
32
$GPGSV,
3
,
3
,
12
,
29
,
74
,
163
,
41
,
30
,
53
,
337
,
40
,
31
,
09
,
266
,
00
,
37
,
00
,
000
,
00
*
78
$PGRME,
6.3
,M,
11.9
,M,
13.5
,M
*
25
$PGRMB,
0.0
,
200
,,,,K,,N,W
*
28
$PGRMM,WGS 
84
*
06

 

GPS NMEA data有以下特点:

* 每一条NMEA data的数据都是以dollar符号开头。
* 从第二个字符开始的前2个字符表示发送者(talker)和接着3个字符表示数据(message)。其中上面的talker中,GP表示通用的GPS NMEA data,而PG为特定厂商的NMEA data。
* 所有数据字段(data fields)都是使用逗号隔开(comma-delimited)。
* 最后一个数据段接着一个星号(asterisk)。
* 星号后面是两位数字的校正码(checksum),checksum的计算方法是或计算在 '$' 和 '*'之间的所有字符。
* 最后以回车换行(<CR><LF>)结尾。

有了上述规范,开发NMEA的分析器就变得十分简单,分析流程是:先接收一条NMEA语句(NMEA sentence),然后检查语句格式,检查checksum,然后再根据talker和message进行分发,使用不同的算法进行分析。下面为核心分析流程。

        
public
 
bool
 Parse(
string
 sentence)
        {
            
string
 rawData 
=
 sentence;
            
try
            {
                
if
 (
!
IsValid(sentence))
                {
                    
return
 
false
;
                }
                sentence 
=
 sentence.Substring(
1
, sentence.IndexOf(
'
*
'
-
 
1
);
                
string
[] Words 
=
 Getwords(sentence);
                
switch
 (Words[
0
])
                {
                    
case
 
"
GPRMC
"
:
                        
return
 ParseGPRMC(Words);
                    
case
 
"
GPGGA
"
:
                        
return
 ParseGPGGA(Words);
                    
case
 
"
GPGSA
"
:
                        
return
 ParseGPGSA(Words);
                    
case
 
"
GPGSV
"
:
                        
return
 ParseGPGSV(Words);
                    
default
:
                        
return
 
false
;
                }
            }
            
catch
 (Exception e)
            {
                Console.WriteLine(e.Message 
+
 rawData);
                
return
 
false
;
            }
        }

代码1

Parse为分析接口,所有从GPS Receiver接收到NMEA data全部调用这个接口进行分析。
IsValid检验该NMEA sentence是否有效。
Checksum进行Checksum运算,检验校验码是否有效。

接下来,讲述关键语句的分析。进行语句的分析,需要一个NMEA的规范手册,这个手册可以从GPS厂商下载,例如从Garmin下载

在该手册的第24页可以看到GPRMC的协议定义。

图1

根据手册的规范定义,抽取想要的信息。如下代码:

        
private
 
bool
 ParseGPRMC(
string
[] Words)
        {
            
if
 (Words[
1
].Length 
>
 
0
 
&
 Words[
9
].Length 
>
 
0
)
            {
                
int
 UtcHours 
=
 Convert.ToInt32(Words[
1
].Substring(
0
2
));
                
int
 UtcMinutes 
=
 Convert.ToInt32(Words[
1
].Substring(
2
2
));
                
int
 UtcSeconds 
=
 Convert.ToInt32(Words[
1
].Substring(
4
2
));
                
int
 UtcMilliseconds 
=
 
0
;
                
//
 Extract milliseconds if it is available
                
if
 (Words[
1
].Length 
>
 
7
)
                {
                    UtcMilliseconds 
=
 Convert.ToInt32(Words[
1
].Substring(
7
));
                }
                
int
 UtcDay 
=
 Convert.ToInt32(Words[
9
].Substring(
0
2
));
                
int
 UtcMonth 
=
 Convert.ToInt32(Words[
9
].Substring(
2
2
));
                
//
 available for this century
                
int
 UtcYear 
=
 Convert.ToInt32(Words[
9
].Substring(
4
2
)) 
+
 
2000
;
                utcDateTime 
=
 
new
 DateTime(UtcYear, UtcMonth, UtcDay, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds);
            }
            fixStatus 
=
 (Words[
2
][
0
==
 
'
A
'
?
 FixStatus.Obtained : FixStatus.Lost;
            
if
 (Words[
3
].Length 
>
 
0
 
&
 Words[
4
].Length 
==
 
1
 
&
 Words[
5
].Length 
>
 
0
 
&
 Words[
6
].Length 
==
 
1
)
            {
                latitude.Hours 
=
 
int
.Parse(Words[
3
].Substring(
0
2
));
                latitude.Minutes 
=
 
int
.Parse(Words[
3
].Substring(
2
2
));
                latitude.Seconds 
=
 Math.Round(
double
.Parse(Words[
3
].Substring(
5
4
)) 
*
 
6
 
/
 
1000.0
3
);
                
if
 (
"
S
"
 
==
 Words[
4
])
                {
                    latitude.Hours 
=
 
-
latitude.Hours;
                }
                longitude.Hours 
=
 
int
.Parse(Words[
5
].Substring(
0
3
));
                longitude.Minutes 
=
 
int
.Parse(Words[
5
].Substring(
3
2
));
                longitude.Seconds 
=
 Math.Round(
double
.Parse(Words[
5
].Substring(
6
4
)) 
*
 
6
 
/
 
1000.0
3
);
                
if
 (
"
W
"
 
==
 Words[
6
])
                {
                    longitude.Hours 
=
 
-
longitude.Hours;
                }
            }
            
if
 (Words[
8
].Length 
>
 
0
)
            {
                azimuth 
=
 
decimal
.Parse(Words[
8
], NmeaCultureInfo);
            }
            
if
 (Words[
7
].Length 
>
 
0
)
            {
                velocity 
=
 
decimal
.Parse(Words[
7
], NmeaCultureInfo) 
*
 KMpHPerKnot;
            }
            
return
 
true
;
        }

代码2

从ParseGPRMC看,传递的参数是一个string的数组,分析要做的事情就是把数组的元素根据手册翻译成需要的信息,例如字段1为UTC的日期信息,字段9为UTC的时间信息。字段2为fix信息,就是GPS是否完成了初始化的信息。字段3,4为经度,字段5,6为维度。字段7为速度。字段8为角度。

        
private
 
bool
 ParseGPGGA(
string
[] Words)
        {
            
if
 (Words[
6
].Length 
>
 
0
)
            {
                
switch
 (Convert.ToInt32(Words[
6
]))
                {
                    
case
 
0
:
                        differentialGpsType 
=
 DifferentialGpsType.NotSet;
                        
break
;
                    
case
 
1
:
                        differentialGpsType 
=
 DifferentialGpsType.SPS;
                        
break
;
                    
case
 
2
:
                        differentialGpsType 
=
 DifferentialGpsType.DSPS;
                        
break
;
                    
case
 
3
:
                        differentialGpsType 
=
 DifferentialGpsType.PPS;
                        
break
;
                    
case
 
4
:
                        differentialGpsType 
=
 DifferentialGpsType.RTK;
                        
break
;
                    
default
:
                        differentialGpsType 
=
 DifferentialGpsType.NotSet;
                        
break
;
                }
            }
            
if
 (Words[
7
].Length 
>
 
0
)
            {
                satellitesInUsed 
=
 Convert.ToInt32(Words[
7
]);
            }
            
if
 (Words[
8
].Length 
>
 
0
)
            {
                horizontalDilutionOfPrecision 
=
 Convert.ToDecimal(Words[
8
]);
            }
            
if
 (Words[
9
].Length 
>
 
0
)
            {
                altitude 
=
 Convert.ToDecimal(Words[
9
]);
            }
            
return
 
true
;
        }

代码3

分析ParseGPGGA和分析ParseGPRMC一样,从数组抽取信息,字段6为fix类型,这个参数表示使用了那些辅佐卫星或者地面信号站来提高GPS的精度。SPS为普通类型,DSPS使用了DGPS 地面信号站fix,DSPS使用了WAAS位置卫星fix(只是用在美国),PPS使用了EGNOS位置卫星fix(只是用在欧洲),RTK使用了MSAS位置卫星fix(只是用在亚洲)。字段7为使用卫星的数量。字段8为水平精度。字段9为海拔。

        
private
 
bool
 ParseGPGSA(
string
[] Words)
        {
            
if
 (Words[
1
].Length 
>
 
0
)
            {
                fixMode 
=
 Words[
1
][
0
==
 
'
A
'
 
?
 FixMode.Auto : FixMode.Manual;
            }
            
if
 (Words[
2
].Length 
>
 
0
)
            {
                
switch
 (Convert.ToInt32(Words[
2
]))
                {
                    
case
 
1
:
                        fixMethod 
=
 FixMethod.NotSet;
                        
break
;
                    
case
 
2
:
                        fixMethod 
=
 FixMethod.Fix2D;
                        
break
;
                    
case
 
3
:
                        fixMethod 
=
 FixMethod.Fix3D;
                        
break
;
                    
default
:
                        fixMethod 
=
 FixMethod.NotSet;
                        
break
;
                }
            }
            
foreach
 (GpsSatellite s 
in
 satellites.Values)
            {
                s.InUsed 
=
 
false
;
            }
            satellitesInUsed 
=
 
0
;
            
for
 (
int
 i 
=
 
0
; i 
<
 
12
++
i)
            {
                
string
 id 
=
 Words[
3
 
+
 i];
                
if
 (id.Length 
>
 
0
)
                {
                    
int
 nId 
=
 Convert.ToInt32(id);
                    
if
 (
!
satellites.ContainsKey(nId))
                    {
                        satellites[nId] 
=
 
new
 GpsSatellite();
                        satellites[nId].PRC 
=
 nId;
                    }
                    satellites[nId].InUsed 
=
 
true
;
                    
++
satellitesInUsed;
                }
            }
            
if
 (Words[
15
].Length 
>
 
0
)
            {
                positionDilutionOfPrecision 
=
 Convert.ToDecimal(Words[
15
]);
            }
            
if
 (Words[
16
].Length 
>
 
0
)
            {
                horizontalDilutionOfPrecision 
=
 Convert.ToDecimal(Words[
16
]);
            }
            
if
 (Words[
17
].Length 
>
 
0
)
            {
                verticalDilutionOfPrecision 
=
 Convert.ToDecimal(Words[
17
]);
            }
            
return
 
true
;
        }

代码4

从ParseGPGSA看,字段1为fix的状态,手工fix或者自动fix。字段2为fix的方法,2D或者3D。字段3到14共12个字段分别为在使用卫星的信息。字段15为位置精度信息。字段16为水平精度信息。字段17为垂直精度信息。

        
private
 
bool
 ParseGPGSV(
string
[] Words)
        {
            
int
 messageNumber 
=
 
0
;
            
if
 (Words[
2
].Length 
>
 
0
)
            {
                messageNumber 
=
 Convert.ToInt32(Words[
2
]);
            }
            
if
 (Words[
3
].Length 
>
 
0
)
            {
                satellitesInView 
=
 Convert.ToInt32(Words[
3
]);
            }
            
if
 (messageNumber 
==
 
0
 
||
 satellitesInView 
==
 
0
)
            {
                
return
 
false
;
            }
            
for
 (
int
 i 
=
 
1
; i 
<=
 
4
++
i)
            {
                
if
 ((Words.Length 
-
 
1
>=
 (i 
*
 
4
 
+
 
3
))
                {
                    
int
 nId 
=
 
0
;
                    
if
 (Words[i 
*
 
4
].Length 
>
 
0
)
                    {
                        
string
 id 
=
 Words[i 
*
 
4
];
                        nId 
=
 Convert.ToInt32(id);
                        
if
 (
!
satellites.ContainsKey(nId))
                        {
                            satellites[nId] 
=
 
new
 GpsSatellite();
                            satellites[nId].PRC 
=
 nId;
                        }
                        satellites[nId].InView 
=
 
true
;
                    }
                    
if
 (Words[i 
*
 
4
 
+
 
1
].Length 
>
 
0
)
                    {
                        satellites[nId].Elevation 
=
 Convert.ToInt32(Words[i 
*
 
4
 
+
 
1
]);
                    }
                    
if
 (Words[i 
*
 
4
 
+
 
2
].Length 
>
 
0
)
                    {
                        satellites[nId].Azimuth 
=
 Convert.ToInt32(Words[i 
*
 
4
 
+
 
2
]);
                    }
                    
if
 (Words[i 
*
 
4
 
+
 
3
].Length 
>
 
0
)
                    {
                        satellites[nId].SNR 
=
 Convert.ToInt32(Words[i 
*
 
4
 
+
 
3
]);
                        satellites[nId].NotTracking 
=
 
false
;
                    }
                    
else
                    {
                        satellites[nId].NotTracking 
=
 
true
;
                    }
                }
            }
            
return
 
true
;
        }

代码5

从ParseGPGSA看,这个比较特别,他把在使用的卫星信息分开多条语句output。如下:

$GPGSV,
3
,
1
,
12
,
03
,
43
,
246
,
46
,
06
,
57
,
263
,
52
,
09
,
10
,
090
,
00
,
14
,
29
,
357
,
41
*
71
$GPGSV,
3
,
2
,
12
,
15
,
12
,
140
,
00
,
16
,
10
,
307
,
00
,
18
,
59
,
140
,
00
,
19
,
20
,
224
,
00
*
75
$GPGSV,
3
,
3
,
12
,
21
,
48
,
089
,
00
,
22
,
69
,
265
,
36
,
24
,
09
,
076
,
00
,
34
,
00
,
000
,
00
*
76

字段1为一共分开多少条语句。字段2为当前语句的序号。字段3为在使用的卫星的数量。后面字段分别表示三个不同卫星的信息,取其中一个卫星来解释,字段4为卫星的ID,字段5为太空海拔,字段6为角度,字段7为信号强弱。

对于厂商的私有NMEA data也是同样的方法进行分析,根据文档的描述进行分析。下面为整个类的代码。

 

ContractedBlock.gif
ExpandedBlockStart.gif
NmeaParser
    public class NmeaParser
    {
        
public struct Coordinate
        {
            
public int Hours;
            
public int Minutes;
            
public double Seconds;
        }
        
public enum FixStatus
        {
            NotSet,
            Obtained, 
//A
            Lost //V
        }
        
public enum FixMode
        {
            Auto,   
//A
            Manual
        }
        
public enum FixMethod
        {
            NotSet,
            Fix2D,
            Fix3D
        }
        
public enum DifferentialGpsType
        {
            NotSet, 
            SPS,    
            DSPS,   
            PPS,    
            RTK     
        }
        
public class GpsSatellite
        {
            
public int PRC { getset; }
            
public int Elevation { getset; }
            
public int Azimuth { getset; }
            
public int SNR { getset; }
            
public bool InUsed { getset; }
            
public bool InView { getset; }
            
public bool NotTracking { getset; }
        }
        
private static readonly CultureInfo NmeaCultureInfo = new CultureInfo("en-US");
        
private static readonly decimal KMpHPerKnot = decimal.Parse("1.852", NmeaCultureInfo);
        
private Coordinate latitude;
        
private Coordinate longitude;
        
private decimal altitude = 0;
        
private DateTime utcDateTime;
        
private decimal velocity = 0;
        
private decimal azimuth = 0;
        
private FixStatus fixStatus;
        
private DifferentialGpsType differentialGpsType;
        
private FixMode fixMode;
        
private FixMethod fixMethod;
        
private int satellitesInView;
        
private int satellitesInUsed;
        
private readonly Dictionary<int, GpsSatellite> satellites;
        
private decimal horizontalDilutionOfPrecision = 50;
        
private decimal positionDilutionOfPrecision = 50;
        
private decimal verticalDilutionOfPrecision = 50;
        
public NmeaParser()
        {
            satellites 
= new Dictionary<int, GpsSatellite>();
        }
        
public bool Parse(string sentence)
        {
            
string rawData = sentence;
            
try
            {
                
if (!IsValid(sentence))
                {
                    
return false;
                }
                sentence 
= sentence.Substring(1, sentence.IndexOf('*'- 1);
                
string[] Words = Getwords(sentence);
                
switch (Words[0])
                {
                    
case "GPRMC":
                        
return ParseGPRMC(Words);
                    
case "GPGGA":
                        
return ParseGPGGA(Words);
                    
case "GPGSA":
                        
return ParseGPGSA(Words);
                    
case "GPGSV":
                        
return ParseGPGSV(Words);
                    
default:
                        
return false;
                }
            }
            
catch (Exception e)
            {
                Console.WriteLine(e.Message 
+ rawData);
                
return false;
            }
        }
        
private bool IsValid(string sentence)
        {
            
// GPS data can't be zero length
            if (sentence.Length == 0)
            {
                
return false;
            }
            
// first character must be a $
            if (sentence[0!= '$')
            {
                
return false;
            }
            
// GPS data can't be longer than 82 character
            if (sentence.Length > 82)
            {
                
return false;
            }
            
try
            {
                
string checksum = sentence.Substring(sentence.IndexOf('*'+ 1);
                
return Checksum(sentence, checksum);
            }
            
catch (Exception e)
            {
                Console.WriteLine(
"Checksum failure. " + e.Message);
                
return false;
            }
        }
        
private bool Checksum(string sentence, string checksumStr)
        {
            
int checksum = 0;
            
int length = sentence.IndexOf('*'- 1;
            
// go from first character upto last *
            for (int i = 1; i <= length; ++i)
            {
                checksum 
= checksum ^ Convert.ToByte(sentence[i]);
            }
            
return (checksum.ToString("X2"== checksumStr);
        }
        
// Divides a sentence into individual Words
        private static string[] Getwords(string sentence)
        {
            
return sentence.Split(',');
        }
        
private bool ParseGPRMC(string[] Words)
        {
            
if (Words[1].Length > 0 & Words[9].Length > 0)
            {
                
int UtcHours = Convert.ToInt32(Words[1].Substring(02));
                
int UtcMinutes = Convert.ToInt32(Words[1].Substring(22));
                
int UtcSeconds = Convert.ToInt32(Words[1].Substring(42));
                
int UtcMilliseconds = 0;
                
// Extract milliseconds if it is available
                if (Words[1].Length > 7)
                {
                    UtcMilliseconds 
= Convert.ToInt32(Words[1].Substring(7));
                }
                
int UtcDay = Convert.ToInt32(Words[9].Substring(02));
                
int UtcMonth = Convert.ToInt32(Words[9].Substring(22));
                
// available for this century
                int UtcYear = Convert.ToInt32(Words[9].Substring(42)) + 2000;
                utcDateTime 
= new DateTime(UtcYear, UtcMonth, UtcDay, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds);
            }
            fixStatus 
= (Words[2][0== 'A'? FixStatus.Obtained : FixStatus.Lost;
            
if (Words[3].Length > 0 & Words[4].Length == 1 & Words[5].Length > 0 & Words[6].Length == 1)
            {
                latitude.Hours 
= int.Parse(Words[3].Substring(02));
                latitude.Minutes 
= int.Parse(Words[3].Substring(22));
                latitude.Seconds 
= Math.Round(double.Parse(Words[3].Substring(54)) * 6 / 1000.03);
                
if ("S" == Words[4])
                {
                    latitude.Hours 
= -latitude.Hours;
                }
                longitude.Hours 
= int.Parse(Words[5].Substring(03));
                longitude.Minutes 
= int.Parse(Words[5].Substring(32));
                longitude.Seconds 
= Math.Round(double.Parse(Words[5].Substring(64)) * 6 / 1000.03);
                
if ("W" == Words[6])
                {
                    longitude.Hours 
= -longitude.Hours;
                }
            }
            
if (Words[8].Length > 0)
            {
                azimuth 
= decimal.Parse(Words[8], NmeaCultureInfo);
            }
            
if (Words[7].Length > 0)
            {
                velocity 
= decimal.Parse(Words[7], NmeaCultureInfo) * KMpHPerKnot;
            }
            
return true;
        }
        
private bool ParseGPGGA(string[] Words)
        {
            
if (Words[6].Length > 0)
            {
                
switch (Convert.ToInt32(Words[6]))
                {
                    
case 0:
                        differentialGpsType 
= DifferentialGpsType.NotSet;
                        
break;
                    
case 1:
                        differentialGpsType 
= DifferentialGpsType.SPS;
                        
break;
                    
case 2:
                        differentialGpsType 
= DifferentialGpsType.DSPS;
                        
break;
                    
case 3:
                        differentialGpsType 
= DifferentialGpsType.PPS;
                        
break;
                    
case 4:
                        differentialGpsType 
= DifferentialGpsType.RTK;
                        
break;
                    
default:
                        differentialGpsType 
= DifferentialGpsType.NotSet;
                        
break;
                }
            }
            
if (Words[7].Length > 0)
            {
                satellitesInUsed 
= Convert.ToInt32(Words[7]);
            }
            
if (Words[8].Length > 0)
            {
                horizontalDilutionOfPrecision 
= Convert.ToDecimal(Words[8]);
            }
            
if (Words[9].Length > 0)
            {
                altitude 
= Convert.ToDecimal(Words[9]);
            }
            
return true;
        }
        
private bool ParseGPGSA(string[] Words)
        {
            
if (Words[1].Length > 0)
            {
                fixMode 
= Words[1][0== 'A' ? FixMode.Auto : FixMode.Manual;
            }
            
if (Words[2].Length > 0)
            {
                
switch (Convert.ToInt32(Words[2]))
                {
                    
case 1:
                        fixMethod 
= FixMethod.NotSet;
                        
break;
                    
case 2:
                        fixMethod 
= FixMethod.Fix2D;
                        
break;
                    
case 3:
                        fixMethod 
= FixMethod.Fix3D;
                        
break;
                    
default:
                        fixMethod 
= FixMethod.NotSet;
                        
break;
                }
            }
            
foreach (GpsSatellite s in satellites.Values)
            {
                s.InUsed 
= false;
            }
            satellitesInUsed 
= 0;
            
for (int i = 0; i < 12++i)
            {
                
string id = Words[3 + i];
                
if (id.Length > 0)
                {
                    
int nId = Convert.ToInt32(id);
                    
if (!satellites.ContainsKey(nId))
                    {
                        satellites[nId] 
= new GpsSatellite();
                        satellites[nId].PRC 
= nId;
                    }
                    satellites[nId].InUsed 
= true;
                    
++satellitesInUsed;
                }
            }
            
if (Words[15].Length > 0)
            {
                positionDilutionOfPrecision 
= Convert.ToDecimal(Words[15]);
            }
            
if (Words[16].Length > 0)
            {
                horizontalDilutionOfPrecision 
= Convert.ToDecimal(Words[16]);
            }
            
if (Words[17].Length > 0)
            {
                verticalDilutionOfPrecision 
= Convert.ToDecimal(Words[17]);
            }
            
return true;
        }
        
private bool ParseGPGSV(string[] Words)
        {
            
int messageNumber = 0;
            
if (Words[2].Length > 0)
            {
                messageNumber 
= Convert.ToInt32(Words[2]);
            }
            
if (Words[3].Length > 0)
            {
                satellitesInView 
= Convert.ToInt32(Words[3]);
            }
            
if (messageNumber == 0 || satellitesInView == 0)
            {
                
return false;
            }
            
for (int i = 1; i <= 4++i)
            {
                
if ((Words.Length - 1>= (i * 4 + 3))
                {
                    
int nId = 0;
                    
if (Words[i * 4].Length > 0)
                    {
                        
string id = Words[i * 4];
                        nId 
= Convert.ToInt32(id);
                        
if (!satellites.ContainsKey(nId))
                        {
                            satellites[nId] 
= new GpsSatellite();
                            satellites[nId].PRC 
= nId;
                        }
                        satellites[nId].InView 
= true;
                    }
                    
if (Words[i * 4 + 1].Length > 0)
                    {
                        satellites[nId].Elevation 
= Convert.ToInt32(Words[i * 4 + 1]);
                    }
                    
if (Words[i * 4 + 2].Length > 0)
                    {
                        satellites[nId].Azimuth 
= Convert.ToInt32(Words[i * 4 + 2]);
                    }
                    
if (Words[i * 4 + 3].Length > 0)
                    {
                        satellites[nId].SNR 
= Convert.ToInt32(Words[i * 4 + 3]);
                        satellites[nId].NotTracking 
= false;
                    }
                    
else
                    {
                        satellites[nId].NotTracking 
= true;
                    }
                }
            }
            
return true;
        }
    }

 

参考文献:

 

转载于:https://www.cnblogs.com/procoder/archive/2009/05/06/Windows-Mobile-GPS-NMEA.html

你可能感兴趣的文章
PHP表单(get,post)提交方式
查看>>
使用vbs或者bat脚本修改IE浏览器安全级别和选项
查看>>
Silverlight入门
查看>>
Silverlight动态调用WEBSERVICE,WCF方法
查看>>
LeetCode 895. Maximum Frequency Stack
查看>>
模仿segmentfault 评论
查看>>
一个简单的日志函数C++
查看>>
Java 8 中如何优雅的处理集合
查看>>
IOS程序的启动过程
查看>>
连接Linux下 XAMPP集成环境中部署的禅道的数据库MariaDB
查看>>
Java操作Excel和Word
查看>>
Oracle 体系结构之ORACLE物理结构
查看>>
ORA-12538: TNS: no such protocol adapter
查看>>
盒子模型
查看>>
局域网协议
查看>>
[HNOI2012]永无乡 线段树合并
查看>>
Spring整合hibernate:3、使用XML进行声明式的事务管理
查看>>
SqlServer之Convert 函数应用格式化日期(转)
查看>>
软件测试领域中的10个生存和发展技巧
查看>>
Camera前后摄像头同时预览
查看>>