nmealib 0.0.4
NMEA 0183/NMEA 2000 parsing library
Loading...
Searching...
No Matches
gll.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<GLL> GLL::create(std::unique_ptr<Message0183> baseMessage) {
15 std::string context = "GLL::create";
16 if (baseMessage->getSentenceType() != "GLL") {
17 NMEALIB_RETURN_ERROR(NotGLLException(context, "Expected sentence type 'GLL', got " + baseMessage->getSentenceType()));
18 }
19
20 // Parse the payload to extract GLL-specific fields
21 std::string payload = baseMessage->getPayload();
22 std::istringstream ss(payload);
23 std::string token;
24 std::vector<std::string> fields;
25
26 while (std::getline(ss, token, ',')) {
27 fields.push_back(token);
28 }
29
30 if (!payload.empty() && payload.back() == ',') {
31 fields.push_back("");
32 }
33
34 // Drop first element which is the sentence type (e.g. "GPGLL")
35 if (!fields.empty()) {
36 fields.erase(fields.begin());
37 }
38
39 if (fields.size() != 6 && fields.size() != 7) {
40 NMEALIB_RETURN_ERROR(NotGLLException(context, "Insufficient fields in GLL payload: expected 6 or 7, got " + std::to_string(fields.size()) + ". Payload: " + payload));
41 }
42
43 double latitude = 0.0;
44 double longitude = 0.0;
45 double timestamp = 0.0;
46 if (!detail::parseNmeaCoordinate(fields[0], latitude) ||
47 !detail::parseNmeaCoordinate(fields[2], longitude) ||
48 !detail::parseOptionalDouble(fields[4], timestamp)) {
49 NMEALIB_RETURN_ERROR(NmeaException(context, "Error parsing GLL fields"));
50 }
51
52 char latitudeDirection = fields[1].empty() ? '\0' : fields[1][0];
53 char longitudeDirection = fields[3].empty() ? '\0' : fields[3][0];
54 char status = fields[5].empty() ? '\0' : fields[5][0];
55 char modeIndicator = (fields.size() > 6 && !fields[6].empty()) ? fields[6][0] : '\0';
56
57 return std::unique_ptr<GLL>(new GLL(std::move(*baseMessage),
58 latitude,
59 latitudeDirection,
60 longitude,
61 longitudeDirection,
62 timestamp,
63 status,
64 modeIndicator));
65}
66
67GLL::GLL(Message0183 baseMessage,
68 double latitude,
69 char latitudeDirection,
70 double longitude,
71 char longitudeDirection,
72 double timestamp,
73 char status,
74 char modeIndicator) noexcept
75 : Message0183(std::move(baseMessage)),
76 latitude_(latitude),
77 latitudeDirection_(latitudeDirection),
78 longitude_(longitude),
79 longitudeDirection_(longitudeDirection),
80 utcTime_(timestamp),
81 status_(status),
82 modeIndicator_(modeIndicator) {}
83
84GLL::GLL(std::string talkerId,
85 double latitude,
86 char latitudeDirection,
87 double longitude,
88 char longitudeDirection,
89 double timestamp,
90 char status,
91 char modeIndicator)
92 : Message0183(*Message0183::create(composeRaw(talkerId,
93 latitude,
94 latitudeDirection,
95 longitude,
96 longitudeDirection,
97 timestamp,
98 status,
99 modeIndicator))),
100 latitude_(latitude),
101 latitudeDirection_(latitudeDirection),
102 longitude_(longitude),
103 longitudeDirection_(longitudeDirection),
104 utcTime_(timestamp),
105 status_(status),
106 modeIndicator_(modeIndicator) {}
107
108std::unique_ptr<nmealib::Message> GLL::clone() const {
109 return std::unique_ptr<GLL>(new GLL(*this));
110}
111
112std::string GLL::getStringContent(bool verbose) const noexcept {
113 std::ostringstream ss;
114 ss << this->toString(verbose);
115 std::ostringstream latStream;
116 latStream << std::setprecision(10) << latitude_;
117 const std::string latitudeStr = latStream.str();
118
119 std::ostringstream lonStream;
120 lonStream << std::setprecision(10) << longitude_;
121 const std::string longitudeStr = lonStream.str();
122
123 if (verbose) {
124 ss << "\tLatitude: " << latitudeStr << " " << latitudeDirection_ << "\n";
125 ss << "\tLongitude: " << longitudeStr << " " << longitudeDirection_ << "\n";
126 ss << "\tTimestamp: " << utcTime_ << "\n";
127 ss << "\tStatus: " << status_ << "\n";
128 ss << "\tMode Indicator: " << modeIndicator_;
129 ss << "\n";
130 } else {
131 ss << "Lat=" << latitudeStr << latitudeDirection_
132 << ", Lon=" << longitudeStr << longitudeDirection_
133 << ", Time=" << utcTime_
134 << ", Status=" << status_
135 << ", Mode=" << modeIndicator_;
136 }
137 return ss.str();
138}
139
140std::string GLL::composeRaw(const std::string& talkerId,
141 double latitude,
142 char latitudeDirection,
143 double longitude,
144 char longitudeDirection,
145 double timestamp,
146 char status,
147 char modeIndicator) {
148 std::ostringstream payloadStream;
149 payloadStream << talkerId << "GLL,";
150
151 double latitudeDegrees = std::floor(latitude);
152 double latitudeMinutes = (latitude - latitudeDegrees) * 60.0;
153 double latitudeNmea = latitudeDegrees * 100.0 + latitudeMinutes; // ddmm.mmmm
154
155 double longitudeDegrees = std::floor(longitude);
156 double longitudeMinutes = (longitude - longitudeDegrees) * 60.0;
157 double longitudeNmea = longitudeDegrees * 100.0 + longitudeMinutes; // dddmm.mmmm
158
159 payloadStream << std::fixed << std::setprecision(6) << std::setw(10) << std::setfill('0') << latitudeNmea << ",";
160 payloadStream << latitudeDirection << ",";
161 payloadStream << std::fixed << std::setprecision(6) << std::setw(11) << std::setfill('0') << longitudeNmea << ",";
162 payloadStream << longitudeDirection << ",";
163 payloadStream << std::fixed << std::setprecision(2) << std::setw(9) << std::setfill('0') << timestamp << ",";
164 payloadStream << status << ",";
165 payloadStream << modeIndicator;
166
167 std::string payload = payloadStream.str();
168 return "$" + payload + "\r\n";
169}
170
171double GLL::getLatitude() const noexcept {
172 return latitude_;
173}
174
175char GLL::getLatitudeDirection() const noexcept {
176 return latitudeDirection_;
177}
178
179double GLL::getLongitude() const noexcept {
180 return longitude_;
181}
182
183char GLL::getLongitudeDirection() const noexcept {
184 return longitudeDirection_;
185}
186
187double GLL::getUtcTime() const noexcept {
188 return utcTime_;
189}
190
191char GLL::getStatus() const noexcept {
192 return status_;
193}
194
195char GLL::getModeIndicator() const noexcept {
196 return modeIndicator_;
197}
198
199bool GLL::operator==(const GLL& other) const noexcept {
200 return Message0183::operator==(other);
201}
202
203} // namespace nmea0183
204} // namespace nmealib
Represents a parsed NMEA 0183 GLL (Geographic Position - Latitude/Longitude) sentence.
Definition gll.h:36
double getUtcTime() const noexcept
Get UTC time in hhmmss.ss numeric form.
Definition gll.cpp:187
double getLatitude() const noexcept
Get latitude in decimal degrees.
Definition gll.cpp:171
std::unique_ptr< nmealib::Message > clone() const override
Create a polymorphic copy of this GLL message.
Definition gll.cpp:108
char getLongitudeDirection() const noexcept
Get longitude hemisphere indicator ('E' or 'W').
Definition gll.cpp:183
std::string getStringContent(bool verbose) const noexcept override
Return a human-readable string representation of this message.
Definition gll.cpp:112
char getLatitudeDirection() const noexcept
Get latitude hemisphere indicator ('N' or 'S').
Definition gll.cpp:175
GLL(std::string talkerId, double latitude, char latitudeDirection, double longitude, char longitudeDirection, double timestamp, char status, char modeIndicator)
Construct a GLL message from individual field values.
Definition gll.cpp:84
bool operator==(const GLL &other) const noexcept
Compare two GLL messages for equality.
Definition gll.cpp:199
double getLongitude() const noexcept
Get longitude in decimal degrees.
Definition gll.cpp:179
char getStatus() const noexcept
Get status indicator (typically 'A' or 'V').
Definition gll.cpp:191
char getModeIndicator() const noexcept
Get mode indicator character.
Definition gll.cpp:195
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
#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