sidereon_core/rtcm/
station.rs1use crate::error::{Error, Result};
15
16use super::bits::{BitReader, BitWriter};
17use super::DecodeResult;
18
19const ECEF_SCALE_M: f64 = 0.0001;
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub struct StationCoordinates {
25 pub message_number: u16,
27 pub reference_station_id: u16,
29 pub itrf_realization_year: u8,
31 pub gps_indicator: bool,
33 pub glonass_indicator: bool,
35 pub galileo_indicator: bool,
37 pub reference_station_indicator: bool,
39 pub ecef_x: i64,
41 pub single_receiver_oscillator: bool,
43 pub reserved: bool,
45 pub ecef_y: i64,
47 pub quarter_cycle_indicator: u8,
49 pub ecef_z: i64,
51 pub antenna_height: Option<u16>,
54}
55
56impl StationCoordinates {
57 pub fn x_m(&self) -> f64 {
59 self.ecef_x as f64 * ECEF_SCALE_M
60 }
61
62 pub fn y_m(&self) -> f64 {
64 self.ecef_y as f64 * ECEF_SCALE_M
65 }
66
67 pub fn z_m(&self) -> f64 {
69 self.ecef_z as f64 * ECEF_SCALE_M
70 }
71
72 pub fn antenna_height_m(&self) -> Option<f64> {
74 self.antenna_height.map(|h| f64::from(h) * ECEF_SCALE_M)
75 }
76
77 pub fn decode(body: &[u8]) -> Result<Self> {
79 Self::decode_inner(body).map_err(Into::into)
80 }
81
82 pub(crate) fn decode_inner(body: &[u8]) -> DecodeResult<Self> {
83 let mut r = BitReader::new(body);
84 let message_number = r.u(12)? as u16;
85 if message_number != 1005 && message_number != 1006 {
86 return Err(Error::Parse(format!(
87 "message {message_number} is not station coordinates 1005/1006"
88 ))
89 .into());
90 }
91 let reference_station_id = r.u(12)? as u16;
92 let itrf_realization_year = r.u(6)? as u8;
93 let gps_indicator = r.flag()?;
94 let glonass_indicator = r.flag()?;
95 let galileo_indicator = r.flag()?;
96 let reference_station_indicator = r.flag()?;
97 let ecef_x = r.i(38)?;
98 let single_receiver_oscillator = r.flag()?;
99 let reserved = r.flag()?;
100 let ecef_y = r.i(38)?;
101 let quarter_cycle_indicator = r.u(2)? as u8;
102 let ecef_z = r.i(38)?;
103 let antenna_height = if message_number == 1006 {
104 Some(r.u(16)? as u16)
105 } else {
106 None
107 };
108
109 Ok(Self {
110 message_number,
111 reference_station_id,
112 itrf_realization_year,
113 gps_indicator,
114 glonass_indicator,
115 galileo_indicator,
116 reference_station_indicator,
117 ecef_x,
118 single_receiver_oscillator,
119 reserved,
120 ecef_y,
121 quarter_cycle_indicator,
122 ecef_z,
123 antenna_height,
124 })
125 }
126
127 pub fn encode(&self) -> Vec<u8> {
129 let mut w = BitWriter::new();
130 w.push_u(u64::from(self.message_number), 12);
131 w.push_u(u64::from(self.reference_station_id), 12);
132 w.push_u(u64::from(self.itrf_realization_year), 6);
133 w.push_flag(self.gps_indicator);
134 w.push_flag(self.glonass_indicator);
135 w.push_flag(self.galileo_indicator);
136 w.push_flag(self.reference_station_indicator);
137 w.push_i(self.ecef_x, 38);
138 w.push_flag(self.single_receiver_oscillator);
139 w.push_flag(self.reserved);
140 w.push_i(self.ecef_y, 38);
141 w.push_u(u64::from(self.quarter_cycle_indicator), 2);
142 w.push_i(self.ecef_z, 38);
143 if let Some(height) = self.antenna_height {
144 w.push_u(u64::from(height), 16);
145 }
146 w.into_bytes()
147 }
148}