1 #include <marnav/nmea/bwr.hpp>
4 #include <marnav/nmea/io.hpp>
10 constexpr sentence_id
bwr::ID
;
11 constexpr const char * bwr::TAG
;
14 : sentence(ID
, TAG
, talker::global_positioning_system
)
18 bwr::bwr(talker talk
, fields::const_iterator first
, fields::const_iterator last
)
19 : sentence(ID
, TAG
, talk
)
21 const auto n
= std::distance(first
, last
);
22 if ((n
< 12) || (n
> 13))
23 throw std::invalid_argument
{"invalid number of fields in bwr"};
25 utils::optional
<reference
> bearing_true_ref
;
26 utils::optional
<reference
> bearing_magn_ref
;
27 utils::optional
<unit::distance
> distance_unit
;
29 read(*(first
+ 0), time_utc_
);
30 read(*(first
+ 1), lat_
);
31 read(*(first
+ 2), lat_hem_
);
32 read(*(first
+ 3), lon_
);
33 read(*(first
+ 4), lon_hem_
);
34 read(*(first
+ 5), bearing_true_
);
35 read(*(first
+ 6), bearing_true_ref
);
36 read(*(first
+ 7), bearing_mag_
);
37 read(*(first
+ 8), bearing_magn_ref
);
38 read(*(first
+ 9), distance_
);
39 read(*(first
+ 10), distance_unit
);
40 read(*(first
+ 11), waypoint_id_
);
43 read(*(first
+ 12), mode_ind_
);
45 // instead of reading data into temporary lat/lon, let's correct values afterwards
46 lat_
= correct_hemisphere(lat_
, lat_hem_
);
47 lon_
= correct_hemisphere(lon_
, lon_hem_
);
49 check_value(bearing_true_ref
, {reference::TRUE
}, "bearing true ref");
50 check_value(bearing_magn_ref
, {reference::MAGNETIC
}, "bearing magnetic ref");
51 check_value(distance_unit
, {unit::distance::nm
}, "distance unit");
54 utils::optional
<geo::longitude
> bwr::get_lon() const
56 return (lon_
&& lon_hem_
) ? lon_
: utils::optional
<geo::longitude
>{};
59 utils::optional
<geo::latitude
> bwr::get_lat() const
61 return (lat_
&& lat_hem_
) ? lat_
: utils::optional
<geo::latitude
>{};
64 void bwr::set_lat(const geo::latitude
& t
)
67 lat_hem_
= convert_hemisphere(t
);
70 void bwr::set_lon(const geo::longitude
& t
)
73 lon_hem_
= convert_hemisphere(t
);
76 void bwr::set_bearing_true(double t
) noexcept
81 void bwr::set_bearing_mag(double t
) noexcept
86 void bwr::set_distance(units::length t
)
89 throw std::invalid_argument
{"distance less than zero"};
90 distance_
= t
.get
<units::nautical_miles
>();
93 utils::optional
<units::length
> bwr::get_distance() const
100 void bwr::append_data_to(std::string
& s
) const
102 append(s
, to_string(time_utc_
));
103 append(s
, to_string(lat_
));
104 append(s
, to_string(lat_hem_
));
105 append(s
, to_string(lon_
));
106 append(s
, to_string(lon_hem_
));
107 append(s
, to_string(bearing_true_
));
108 append(s
, to_string_if(reference::TRUE
, bearing_true_
));
109 append(s
, to_string(bearing_mag_
));
110 append(s
, to_string_if(reference::MAGNETIC
, bearing_mag_
));
111 append(s
, to_string(distance_
));
112 append(s
, to_string_if(unit::distance::nm
, distance_
));
113 append(s
, to_string(waypoint_id_
));
114 append(s
, to_string(mode_ind_
));