GPS Library  0.1
GPS driver and NMEA parser
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
NMEAInfo.cpp
Go to the documentation of this file.
1 #include "NMEAInfo.h"
2 
3 #include <stdlib.h>
4 #include <string.h>
5 #include <math.h>
6 
7 using namespace NMEA;
8 
9 void Position::Update(void)
10 {
11  if (up2date)
12  return;
13 
14  static long integers[] = { 100000L, 1000000L, 6000000L, 60000000L, 600000000L, 0L };
15  static long fractions[] = { 10000L, 1000L, 100L, 10L, 1L, 0L };
16  long * multiplier;
17 
18  // It must have a dot:
19  const char * dot = strchr(myFormat, '.');
20  if (dot == NULL)
21  throw EX::Error("NMEA angle format error");
22 
23  rawValue = 0;
24 
25  multiplier = fractions;
26  for (const char * fraction = dot+1; *fraction && *multiplier; ++fraction, ++multiplier) {
27  if (!isdigit(*fraction))
28  throw EX::Error("NMEA angle: non-decimal fraction");
29  rawValue += (long)(*fraction - '0') * *multiplier;
30  }
31 
32  multiplier = integers;
33  for (const char * integer = dot-1; integer >= myFormat && *multiplier; --integer, ++multiplier) {
34  if (!isdigit(*integer))
35  throw EX::Error("NMEA angle: non-decimal integer");
36  rawValue += (long)(*integer - '0') * *multiplier;
37  }
38 
39  if (negative)
40  rawValue = -rawValue;
41 
42  up2date = true;
43 }
44 
45 float FloatData::toFloat(void)
46 {
47  if (!up2date) {
48  value = ToFloat(format);
49  up2date = true;
50  }
51 
52  return value;
53 }
54 
56 {
57  if (!up2date) {
58  value = ToFloat(format);
59  if (direction && *direction == 'W')
60  value = -value;
61  up2date = true;
62  }
63 
64  return value;
65 }
66 
68 {
69  if (!up2date) {
71  up2date = true;
72  }
73 
74  return value;
75 }
76 
77 Time::Time(const char * format)
78 {
79  day = 0;
80  hour = ToInt(format, 2);
81  format += 2;
82  minute = ToInt(format, 2);
83  format += 2;
84  second = ToFloat(format);
85 }
86 
87 Date::Date(const char * format)
88 {
89  day = ToInt(format, 2);
90  format += 2;
91  month = ToInt(format, 2);
92  format += 2;
93  year = ToInt(format, 2) + 2000;
94 }
95 
96 int NMEA::ToInt(const char * format, int digits)
97 {
98  if (!format)
99  return 0;
100  int result;
101  for (result = 0; *format && digits > 0; --digits, ++format) {
102  if (!isdigit(*format))
103  throw EX::Error("NMEA time: non-decimal character");
104  result *= 10;
105  result += *format - '0';
106  }
107  return result;
108 }
109 
110 float NMEA::ToFloat(const char * format)
111 {
112  if (!format || !*format)
113  return 0.0;
114  const char * dot = strchr(format, '.');
115  if (!dot)
116  dot = strchr(format, ',');
117  float result = 0.0;
118  float multiplier = 0.1;
119  if (dot) {
120  for (const char * frac = dot+1; *frac; ++frac) {
121  if (!isdigit(*frac))
122  throw EX::Error("NMEA: invalid character in fractional part of float");
123  result += multiplier * (*frac - '0');
124  multiplier /= 10.0;
125  }
126  } else {
127  dot = format + strlen(format);
128  }
129  multiplier = 1.0;
130  for (--dot; dot >= format; --dot) {
131  if (!isdigit(*dot))
132  throw EX::Error("NMEA: invalid character in integer part of float");
133  result += multiplier * (*dot - '0');
134  multiplier *= 10.0;
135  }
136  return result;
137 }
138 
139 float NMEA::ToMeter(const char * format, const char * unit)
140 {
141  float result = NMEA::ToFloat(format);
142 
143  if (!unit)
144  return result;
145 
146  switch (*unit) {
147  case 'M':
148  // Nothing to do
149  break;
150  case 'N':
151  result *= 1852.0;
152  break;
153  default:
154  throw EX::Error((std::string("Bad unit (M/N): ") + format + "/" + unit).c_str());
155  break;
156  }
157 
158  return result;
159 }
160 
161 /* * * * * * * * * * * * * End - of - File * * * * * * * * * * * * * * */