NMEA: remove deprecated type talker_id
[marnav.git] / src / marnav / nmea / rmc.cpp
blob59b0dbe5cb88b718984793caf8790b0e4bb5fdfb
1 #include <marnav/nmea/rmc.hpp>
2 #include "checks.hpp"
3 #include "convert.hpp"
4 #include <marnav/nmea/io.hpp>
5 #include <stdexcept>
7 namespace marnav
9 namespace nmea
11 constexpr sentence_id rmc::ID;
12 constexpr const char * rmc::TAG;
14 rmc::rmc()
15 : sentence(ID, TAG, talker::global_positioning_system)
19 rmc::rmc(talker talk, fields::const_iterator first, fields::const_iterator last)
20 : sentence(ID, TAG, talk)
22 // before and after NMEA 2.3
23 const auto size = std::distance(first, last);
24 if ((size < 11) || (size > 12))
25 throw std::invalid_argument{"invalid number of fields in rmc"};
27 read(*(first + 0), time_utc_);
28 read(*(first + 1), status_);
29 read(*(first + 2), lat_);
30 read(*(first + 3), lat_hem_);
31 read(*(first + 4), lon_);
32 read(*(first + 5), lon_hem_);
33 read(*(first + 6), sog_);
34 read(*(first + 7), heading_);
35 read(*(first + 8), date_);
36 read(*(first + 9), mag_);
37 read(*(first + 10), mag_hem_);
39 // NMEA 2.3 or newer
40 if (size > 11)
41 read(*(first + 11), mode_ind_);
43 // instead of reading data into temporary lat/lon, let's correct values afterwards
44 lat_ = correct_hemisphere(lat_, lat_hem_);
45 lon_ = correct_hemisphere(lon_, lon_hem_);
48 utils::optional<geo::longitude> rmc::get_lon() const
50 return (lon_ && lon_hem_) ? lon_ : utils::optional<geo::longitude>{};
53 utils::optional<geo::latitude> rmc::get_lat() const
55 return (lat_ && lat_hem_) ? lat_ : utils::optional<geo::latitude>{};
58 void rmc::set_lat(const geo::latitude & t)
60 lat_ = t;
61 lat_hem_ = convert_hemisphere(t);
64 void rmc::set_lon(const geo::longitude & t)
66 lon_ = t;
67 lon_hem_ = convert_hemisphere(t);
70 void rmc::set_mag(double t, direction h)
72 check_value(h, {direction::east, direction::west}, "mag var hemisphere");
73 mag_ = t;
74 mag_hem_ = h;
77 utils::optional<units::velocity> rmc::get_sog() const
79 if (!sog_)
80 return {};
81 return {*sog_};
84 void rmc::set_sog(units::velocity t)
86 if (t.value() < 0.0)
87 throw std::invalid_argument{"invalid argument, SOG less than zero"};
88 sog_ = t.get<units::knots>();
91 void rmc::append_data_to(std::string & s) const
93 append(s, to_string(time_utc_));
94 append(s, to_string(status_));
95 append(s, to_string(lat_));
96 append(s, to_string(lat_hem_));
97 append(s, to_string(lon_));
98 append(s, to_string(lon_hem_));
99 append(s, to_string(sog_));
100 append(s, to_string(heading_));
101 append(s, to_string(date_));
102 append(s, to_string(mag_));
103 append(s, to_string(mag_hem_));
104 append(s, to_string(mode_ind_));