nmealib 0.0.4
NMEA 0183/NMEA 2000 parsing library
Loading...
Searching...
No Matches
rma.cpp
Go to the documentation of this file.
2
5
6#include <cmath>
7#include <iomanip>
8#include <sstream>
9#include <vector>
10
11namespace nmealib {
12namespace nmea0183 {
13
14std::unique_ptr<RMA> RMA::create(std::unique_ptr<Message0183> baseMessage) {
15 std::string context = "RMA::create";
16 if (baseMessage->getSentenceType() != "RMA") {
17 NMEALIB_RETURN_ERROR(NotRMAException(context, "Expected sentence type 'RMA', got " + baseMessage->getSentenceType()));
18 }
19
20 std::string payload = baseMessage->getPayload();
21 std::istringstream ss(payload);
22 std::string token;
23 std::vector<std::string> fields;
24
25 while (std::getline(ss, token, ',')) {
26 fields.push_back(token);
27 }
28
29 if (!fields.empty()) {
30 fields.erase(fields.begin());
31 }
32
33 if (fields.size() != 11 && fields.size() != 12) {
34 NMEALIB_RETURN_ERROR(NotRMAException(context, "Invalid fields in RMA payload: expected 11 or 12, got " + std::to_string(fields.size()) + ". Payload: " + payload));
35 }
36
37 double latitude = 0.0;
38 double longitude = 0.0;
39 double timeDifferenceA = 0.0;
40 double timeDifferenceB = 0.0;
41 double speedOverGround = 0.0;
42 double trackMadeGood = 0.0;
43 double magneticVariation = 0.0;
44 if (!detail::parseNmeaCoordinate(fields[1], latitude) ||
45 !detail::parseNmeaCoordinate(fields[3], longitude) ||
46 !detail::parseOptionalDouble(fields[5], timeDifferenceA) ||
47 !detail::parseOptionalDouble(fields[6], timeDifferenceB) ||
48 !detail::parseOptionalDouble(fields[7], speedOverGround) ||
49 !detail::parseOptionalDouble(fields[8], trackMadeGood) ||
50 !detail::parseOptionalDouble(fields[9], magneticVariation)) {
51 NMEALIB_RETURN_ERROR(NmeaException(context, "Error parsing RMA fields"));
52 }
53
54 const char status = fields[0].empty() ? '\0' : fields[0][0];
55 const char latitudeDirection = fields[2].empty() ? '\0' : fields[2][0];
56 const char longitudeDirection = fields[4].empty() ? '\0' : fields[4][0];
57 const char variationDirection = fields[10].empty() ? '\0' : fields[10][0];
58
59 return std::unique_ptr<RMA>(new RMA(std::move(*baseMessage),
60 status,
61 latitude,
62 latitudeDirection,
63 longitude,
64 longitudeDirection,
65 timeDifferenceA,
66 timeDifferenceB,
67 speedOverGround,
68 trackMadeGood,
69 magneticVariation,
70 variationDirection));
71}
72
73RMA::RMA(Message0183 baseMessage,
74 char status,
75 double latitude,
76 char latitudeDirection,
77 double longitude,
78 char longitudeDirection,
79 double timeDifferenceA,
80 double timeDifferenceB,
81 double speedOverGround,
82 double trackMadeGood,
83 double magneticVariation,
84 char variationDirection) noexcept
85 : Message0183(std::move(baseMessage)),
86 status_(status),
87 latitude_(latitude),
88 latitudeDirection_(latitudeDirection),
89 longitude_(longitude),
90 longitudeDirection_(longitudeDirection),
91 timeDifferenceA_(timeDifferenceA),
92 timeDifferenceB_(timeDifferenceB),
93 speedOverGround_(speedOverGround),
94 trackMadeGood_(trackMadeGood),
95 magneticVariation_(magneticVariation),
96 variationDirection_(variationDirection) {}
97
98RMA::RMA(std::string talkerId,
99 char status,
100 double latitude,
101 char latitudeDirection,
102 double longitude,
103 char longitudeDirection,
104 double timeDifferenceA,
105 double timeDifferenceB,
106 double speedOverGround,
107 double trackMadeGood,
108 double magneticVariation,
109 char variationDirection)
110 : Message0183(*Message0183::create(composeRaw(talkerId,
111 status,
112 latitude,
113 latitudeDirection,
114 longitude,
115 longitudeDirection,
116 timeDifferenceA,
117 timeDifferenceB,
118 speedOverGround,
119 trackMadeGood,
120 magneticVariation,
121 variationDirection))),
122 status_(status),
123 latitude_(latitude),
124 latitudeDirection_(latitudeDirection),
125 longitude_(longitude),
126 longitudeDirection_(longitudeDirection),
127 timeDifferenceA_(timeDifferenceA),
128 timeDifferenceB_(timeDifferenceB),
129 speedOverGround_(speedOverGround),
130 trackMadeGood_(trackMadeGood),
131 magneticVariation_(magneticVariation),
132 variationDirection_(variationDirection) {}
133
134std::unique_ptr<nmealib::Message> RMA::clone() const {
135 return std::unique_ptr<RMA>(new RMA(*this));
136}
137
138std::string RMA::getStringContent(bool verbose) const noexcept {
139 std::ostringstream ss;
140 ss << this->toString(verbose);
141 if (verbose) {
142 ss << "\tStatus: " << status_ << "\n";
143 ss << "\tLatitude: " << latitude_ << " " << latitudeDirection_ << "\n";
144 ss << "\tLongitude: " << longitude_ << " " << longitudeDirection_ << "\n";
145 ss << "\tTime Difference A: " << timeDifferenceA_ << "\n";
146 ss << "\tTime Difference B: " << timeDifferenceB_ << "\n";
147 ss << "\tSpeed Over Ground: " << speedOverGround_ << "\n";
148 ss << "\tTrack Made Good: " << trackMadeGood_ << "\n";
149 ss << "\tMagnetic Variation: " << magneticVariation_ << " " << variationDirection_ << "\n";
150 ss << "\n";
151 } else {
152 ss << "Status=" << status_
153 << ", Lat=" << latitude_ << latitudeDirection_
154 << ", Lon=" << longitude_ << longitudeDirection_
155 << ", TDA=" << timeDifferenceA_
156 << ", TDB=" << timeDifferenceB_
157 << ", SOG=" << speedOverGround_
158 << ", Track=" << trackMadeGood_
159 << ", MagVar=" << magneticVariation_ << variationDirection_;
160 }
161 return ss.str();
162}
163
164std::string RMA::composeRaw(const std::string& talkerId,
165 char status,
166 double latitude,
167 char latitudeDirection,
168 double longitude,
169 char longitudeDirection,
170 double timeDifferenceA,
171 double timeDifferenceB,
172 double speedOverGround,
173 double trackMadeGood,
174 double magneticVariation,
175 char variationDirection) {
176 std::ostringstream payloadStream;
177 payloadStream << talkerId << "RMA,";
178 payloadStream << status << ",";
179
180 const double latitudeDegrees = std::floor(latitude);
181 const double latitudeMinutes = (latitude - latitudeDegrees) * 60.0;
182 const double latitudeNmea = latitudeDegrees * 100.0 + latitudeMinutes;
183
184 const double longitudeDegrees = std::floor(longitude);
185 const double longitudeMinutes = (longitude - longitudeDegrees) * 60.0;
186 const double longitudeNmea = longitudeDegrees * 100.0 + longitudeMinutes;
187
188 payloadStream << std::fixed << std::setprecision(4) << latitudeNmea << ",";
189 payloadStream << latitudeDirection << ",";
190 payloadStream << std::fixed << std::setprecision(4) << longitudeNmea << ",";
191 payloadStream << longitudeDirection << ",";
192 payloadStream << std::fixed << std::setprecision(1) << timeDifferenceA << ",";
193 payloadStream << std::fixed << std::setprecision(1) << timeDifferenceB << ",";
194 payloadStream << std::fixed << std::setprecision(1) << speedOverGround << ",";
195 payloadStream << std::fixed << std::setprecision(1) << trackMadeGood << ",";
196 payloadStream << std::fixed << std::setprecision(1) << magneticVariation << ",";
197 payloadStream << variationDirection;
198
199 return "$" + payloadStream.str() + "\r\n";
200}
201
202char RMA::getStatus() const noexcept { return status_; }
203double RMA::getLatitude() const noexcept { return latitude_; }
204char RMA::getLatitudeDirection() const noexcept { return latitudeDirection_; }
205double RMA::getLongitude() const noexcept { return longitude_; }
206char RMA::getLongitudeDirection() const noexcept { return longitudeDirection_; }
207double RMA::getTimeDifferenceA() const noexcept { return timeDifferenceA_; }
208double RMA::getTimeDifferenceB() const noexcept { return timeDifferenceB_; }
209double RMA::getSpeedOverGround() const noexcept { return speedOverGround_; }
210double RMA::getTrackMadeGood() const noexcept { return trackMadeGood_; }
211double RMA::getMagneticVariation() const noexcept { return magneticVariation_; }
212char RMA::getVariationDirection() const noexcept { return variationDirection_; }
213
214bool RMA::operator==(const RMA& other) const noexcept {
215 return Message0183::operator==(other) &&
216 status_ == other.status_ &&
217 latitude_ == other.latitude_ &&
218 latitudeDirection_ == other.latitudeDirection_ &&
219 longitude_ == other.longitude_ &&
220 longitudeDirection_ == other.longitudeDirection_ &&
221 timeDifferenceA_ == other.timeDifferenceA_ &&
222 timeDifferenceB_ == other.timeDifferenceB_ &&
223 speedOverGround_ == other.speedOverGround_ &&
224 trackMadeGood_ == other.trackMadeGood_ &&
225 magneticVariation_ == other.magneticVariation_ &&
226 variationDirection_ == other.variationDirection_;
227}
228
229} // namespace nmea0183
230} // namespace nmealib
Represents an NMEA 0183 sentence.
Definition nmea0183.h:98
bool operator==(const Message0183 &other) const noexcept
Compares two Message0183 objects for equality based on their content and timestamp.
Definition nmea0183.cpp:204
Represents a parsed NMEA 0183 RMA (Recommended Minimum Navigation Information) sentence.
Definition rma.h:22
char getStatus() const noexcept
Definition rma.cpp:202
std::string getStringContent(bool verbose) const noexcept override
Returns a human-readable string representation of the message content.
Definition rma.cpp:138
double getTimeDifferenceA() const noexcept
Definition rma.cpp:207
char getLatitudeDirection() const noexcept
Definition rma.cpp:204
double getMagneticVariation() const noexcept
Definition rma.cpp:211
double getLongitude() const noexcept
Definition rma.cpp:205
char getLongitudeDirection() const noexcept
Definition rma.cpp:206
double getLatitude() const noexcept
Definition rma.cpp:203
char getVariationDirection() const noexcept
Definition rma.cpp:212
double getTrackMadeGood() const noexcept
Definition rma.cpp:210
bool operator==(const RMA &other) const noexcept
Definition rma.cpp:214
double getSpeedOverGround() const noexcept
Definition rma.cpp:209
std::unique_ptr< nmealib::Message > clone() const override
Creates a polymorphic deep copy of this Message0183.
Definition rma.cpp:134
double getTimeDifferenceB() const noexcept
Definition rma.cpp:208
RMA(std::string talkerId, char status, double latitude, char latitudeDirection, double longitude, char longitudeDirection, double timeDifferenceA, double timeDifferenceB, double speedOverGround, double trackMadeGood, double magneticVariation, char variationDirection)
Definition rma.cpp:98
#define NMEALIB_RETURN_ERROR(exceptionExpr)
bool parseNmeaCoordinate(const std::string &text, double &value) noexcept
Definition parse.h:118
bool parseOptionalDouble(const std::string &text, double &value) noexcept
Definition parse.h:86