mod formatting;
mod parsing;
use std::collections::{btree_map::Iter, BTreeMap};
use itertools::Itertools;
use crate::prelude::{Epoch, Key, MapCell, TEC};
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Record {
pub(crate) map: BTreeMap<Key, TEC>,
}
impl Record {
pub fn insert(&mut self, key: Key, tec: TEC) {
self.map.insert(key, tec);
}
pub fn iter(&self) -> Iter<'_, Key, TEC> {
self.map.iter()
}
pub fn iter_mut(&mut self) -> Box<dyn Iterator<Item = (Key, &mut TEC)> + '_> {
Box::new(self.map.iter_mut().map(|(k, v)| (*k, v)))
}
pub fn synchronous_iter(&self, epoch: Epoch) -> Box<dyn Iterator<Item = (Key, TEC)> + '_> {
Box::new(self.iter().filter_map(move |(k, v)| {
if k.epoch == epoch {
Some((*k, *v))
} else {
None
}
}))
}
pub fn synchronous_iter_mut(
&mut self,
epoch: Epoch,
) -> Box<dyn Iterator<Item = (Key, &mut TEC)> + '_> {
Box::new(self.iter_mut().filter_map(
move |(k, v)| {
if k.epoch == epoch {
Some((k, v))
} else {
None
}
},
))
}
pub fn get(&self, key: &Key) -> Option<&TEC> {
self.map.get(key)
}
pub fn get_mut(&mut self, key: &Key) -> Option<&mut TEC> {
self.map.get_mut(key)
}
pub fn from_map_cells(
fixed_altitude_km: f64,
min_latitude_ddeg: f64,
max_latitude_ddeg: f64,
min_longitude_ddeg: f64,
max_longitude_ddeg: f64,
cells: &[MapCell],
) -> Self {
let mut map = Default::default();
Self { map }
}
pub fn epochs_iter(&self) -> Box<dyn Iterator<Item = Epoch> + '_> {
Box::new(self.map.keys().map(|k| k.epoch).unique())
}
pub fn first_epoch(&self) -> Option<Epoch> {
self.epochs_iter().nth(0)
}
}
#[cfg(test)]
mod test {
use crate::prelude::*;
#[test]
#[ignore]
fn ckmg_maps_cells_repiprocal() {
let ionex = IONEX::from_gzip_file("data/IONEX/V1/CKMG0020.22I.gz").unwrap_or_else(|e| {
panic!("Failed to parse CKMG0020: {}", e);
});
let map_cells = ionex.map_cell_iter().collect::<Vec<_>>();
let record = Record::from_map_cells(
ionex.header.grid.altitude.start,
ionex.header.grid.latitude.end,
ionex.header.grid.latitude.start,
ionex.header.grid.longitude.start,
ionex.header.grid.longitude.end,
&map_cells,
);
assert_eq!(record, ionex.record);
}
#[test]
#[ignore]
fn jplg_maps_cells_repiprocal() {
let ionex = IONEX::from_gzip_file("data/IONEX/V1/jplg0010.17i.gz").unwrap_or_else(|e| {
panic!("Failed to parse CKMG0020: {}", e);
});
let map_cells = ionex.map_cell_iter().collect::<Vec<_>>();
let record = Record::from_map_cells(
ionex.header.grid.altitude.start,
ionex.header.grid.latitude.end,
ionex.header.grid.latitude.start,
ionex.header.grid.longitude.start,
ionex.header.grid.longitude.end,
&map_cells,
);
assert_eq!(record, ionex.record);
}
}