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()));
20 std::string payload = baseMessage->getPayload();
21 std::istringstream ss(payload);
23 std::vector<std::string> fields;
25 while (std::getline(ss, token,
',')) {
26 fields.push_back(token);
29 if (!fields.empty()) {
30 fields.erase(fields.begin());
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));
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;
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];
59 return std::unique_ptr<RMA>(
new RMA(std::move(*baseMessage),
73RMA::RMA(Message0183 baseMessage,
76 char latitudeDirection,
78 char longitudeDirection,
79 double timeDifferenceA,
80 double timeDifferenceB,
81 double speedOverGround,
83 double magneticVariation,
84 char variationDirection) noexcept
85 : Message0183(std::move(baseMessage)),
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) {}
98RMA::RMA(std::string talkerId,
101 char latitudeDirection,
103 char longitudeDirection,
104 double timeDifferenceA,
105 double timeDifferenceB,
106 double speedOverGround,
107 double trackMadeGood,
108 double magneticVariation,
109 char variationDirection)
121 variationDirection))),
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) {}
135 return std::unique_ptr<RMA>(
new RMA(*
this));
139 std::ostringstream ss;
140 ss << this->toString(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";
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_;
164std::string RMA::composeRaw(
const std::string& talkerId,
167 char latitudeDirection,
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 <<
",";
180 const double latitudeDegrees = std::floor(latitude);
181 const double latitudeMinutes = (latitude - latitudeDegrees) * 60.0;
182 const double latitudeNmea = latitudeDegrees * 100.0 + latitudeMinutes;
184 const double longitudeDegrees = std::floor(longitude);
185 const double longitudeMinutes = (longitude - longitudeDegrees) * 60.0;
186 const double longitudeNmea = longitudeDegrees * 100.0 + longitudeMinutes;
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;
199 return "$" + payloadStream.str() +
"\r\n";
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_;
Represents an NMEA 0183 sentence.
bool operator==(const Message0183 &other) const noexcept
Compares two Message0183 objects for equality based on their content and timestamp.
Represents a parsed NMEA 0183 RMA (Recommended Minimum Navigation Information) sentence.
char getStatus() const noexcept
std::string getStringContent(bool verbose) const noexcept override
Returns a human-readable string representation of the message content.
double getTimeDifferenceA() const noexcept
char getLatitudeDirection() const noexcept
double getMagneticVariation() const noexcept
double getLongitude() const noexcept
char getLongitudeDirection() const noexcept
double getLatitude() const noexcept
char getVariationDirection() const noexcept
double getTrackMadeGood() const noexcept
bool operator==(const RMA &other) const noexcept
double getSpeedOverGround() const noexcept
std::unique_ptr< nmealib::Message > clone() const override
Creates a polymorphic deep copy of this Message0183.
double getTimeDifferenceB() const noexcept
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)
#define NMEALIB_RETURN_ERROR(exceptionExpr)
bool parseNmeaCoordinate(const std::string &text, double &value) noexcept
bool parseOptionalDouble(const std::string &text, double &value) noexcept