AIS: initialization of message fields modernized.
[marnav.git] / src / marnav / ais / message_22.cpp
blob34c4802271cd0ef68b11bbf740c21ae82d64c063
1 #include "message_22.hpp"
3 #include <algorithm>
4 #include <cmath>
6 #include <marnav/ais/angle.hpp>
7 #include <marnav/utils/unique.hpp>
9 namespace marnav
11 namespace ais
14 message_22::message_22()
15 : message(ID)
19 std::unique_ptr<message> message_22::parse(const raw & bits)
21 if (bits.size() != SIZE_BITS)
22 throw std::invalid_argument{"invalid number of bits in message_22::parse"};
24 std::unique_ptr<message> result = utils::make_unique<message_22>();
25 message_22 & msg = static_cast<message_22 &>(*result);
27 msg.read_data(bits);
29 return result;
32 void message_22::read_data(const raw & bits)
34 bits.get(repeat_indicator, 6, 2);
35 bits.get(mmsi, 8, 30);
36 // spare: 38 - 39
37 bits.get(channel_a, 40, 12);
38 bits.get(channel_b, 52, 12);
39 bits.get(txrx_mode, 64, 4);
40 bits.get(power, 68, 1);
41 bits.get(addressed, 139, 1);
42 if (addressed) {
43 bits.get(mmsi_1, 69, 30);
44 bits.get(mmsi_2, 104, 30);
45 } else {
46 bits.get(ne_lon, 69, 18);
47 bits.get(ne_lat, 87, 17);
48 bits.get(sw_lon, 104, 18);
49 bits.get(sw_lat, 122, 17);
51 bits.get(band_a, 140, 1);
52 bits.get(band_b, 141, 1);
53 bits.get(zone_size, 142, 3);
54 // spare: 145 - 167
57 /// @todo possible refactoring for name_extension
58 raw message_22::get_data() const
60 raw bits{SIZE_BITS};
62 bits.set(type(), 0, 6);
63 bits.set(mmsi, 8, 30);
64 bits.set(channel_a, 40, 12);
65 bits.set(channel_b, 52, 12);
66 bits.set(txrx_mode, 64, 4);
67 bits.set(power, 68, 1);
68 if (addressed) {
69 bits.set(mmsi_1, 69, 30);
70 bits.set(mmsi_2, 104, 30);
71 } else {
72 bits.set(ne_lon, 69, 18);
73 bits.set(ne_lat, 87, 17);
74 bits.set(sw_lon, 104, 18);
75 bits.set(sw_lat, 122, 17);
77 bits.set(addressed, 139, 1);
78 bits.set(band_a, 140, 1);
79 bits.set(band_b, 141, 1);
80 bits.set(zone_size, 142, 3);
82 return bits;
85 geo::position message_22::get_position_ne() const noexcept
87 return {geo::latitude{ne_lat / (60.0 * 10.0)}, geo::longitude{ne_lon / (60.0 * 10.0)}};
90 geo::position message_22::get_position_sw() const noexcept
92 return {geo::latitude{sw_lat / (60.0 * 10.0)}, geo::longitude{sw_lon / (60.0 * 10.0)}};
95 void message_22::set_position_ne(const geo::position & t) noexcept
97 ne_lat = std::floor(60.0 * 10.0 * t.lat());
98 ne_lon = std::floor(60.0 * 10.0 * t.lon());
101 void message_22::set_position_sw(const geo::position & t) noexcept
103 sw_lat = std::floor(60.0 * 10.0 * t.lat());
104 sw_lon = std::floor(60.0 * 10.0 * t.lon());