Skip to content

Commit f98e289

Browse files
committed
Prepare for rinex upgrade
Signed-off-by: Guillaume W. Bres <[email protected]>
1 parent ec58f1b commit f98e289

File tree

12 files changed

+249
-208
lines changed

12 files changed

+249
-208
lines changed

src/cfg.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use maud::{html, Markup, Render};
2-
use rinex::prelude::*;
32
use thiserror::Error;
43

54
use serde::{Deserialize, Serialize};
65

6+
use rinex::prelude::nav::Orbit;
7+
78
/// Configuration Error
89
#[derive(Debug, Clone, Error)]
910
pub enum Error {
@@ -53,7 +54,7 @@ pub struct QcConfig {
5354
#[serde(default)]
5455
pub report: QcReportType,
5556
#[serde(default)]
56-
pub manual_reference: Option<GroundPosition>,
57+
pub manual_rx_orbit: Option<Orbit>,
5758
#[serde(default)]
5859
/// When both SP3 and BRDC NAV are present,
5960
/// SP3 is prefered for skyplot project: set true here to
@@ -65,8 +66,8 @@ impl QcConfig {
6566
pub fn set_report_type(&mut self, report_type: QcReportType) {
6667
self.report = report_type;
6768
}
68-
pub fn set_reference_position(&mut self, pos: GroundPosition) {
69-
self.manual_reference = Some(pos.clone());
69+
pub fn set_reference_rx_orbit(&mut self, orbit: Orbit) {
70+
self.manual_rx_orbit = Some(orbit);
7071
}
7172
}
7273

@@ -81,10 +82,10 @@ impl Render for QcConfig {
8182
(self.report.to_string())
8283
}
8384
}
84-
@if let Some(position) = self.manual_reference {
85+
@if let Some(_) = self.manual_rx_orbit {
8586
tr {
8687
td {
87-
(position.render())
88+
"TODO"
8889
}
8990
}
9091
}

src/context.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ use std::{
1010
path::{Path, PathBuf},
1111
};
1212

13-
use rinex::{
14-
prelude::{Almanac, GroundPosition, Rinex, TimeScale},
15-
types::Type as RinexType,
16-
Error as RinexError,
13+
use rinex::prelude::{
14+
nav::{Almanac, Orbit},
15+
Rinex, RinexType, TimeScale,
1716
};
1817

18+
use qc_traits::{Merge, MergeError};
19+
1920
use anise::{
2021
almanac::{
2122
metaload::MetaAlmanacError,
@@ -30,7 +31,7 @@ use anise::{
3031
#[cfg(feature = "sp3")]
3132
use sp3::prelude::SP3;
3233

33-
use qc_traits::{Filter, Merge, MergeError, Preprocessing, Repair, RepairTrait};
34+
use qc_traits::{Filter, Preprocessing, Repair, RepairTrait};
3435

3536
/// Context Error
3637
#[derive(Debug, Error)]
@@ -41,14 +42,12 @@ pub enum Error {
4142
MetaAlmanac(#[from] MetaAlmanacError),
4243
#[error("planetary data error")]
4344
PlanetaryData(#[from] PlanetaryDataError),
44-
#[error("failed to extend gnss context")]
45-
ContextExtensionError(#[from] MergeError),
4645
#[error("non supported file format")]
4746
NonSupportedFileFormat,
4847
#[error("failed to determine filename")]
4948
FileNameDetermination,
50-
#[error("invalid rinex: {0}")]
51-
RinexError(#[from] RinexError),
49+
#[error("failed to extend context")]
50+
Merge(#[from] MergeError),
5251
}
5352

5453
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -667,16 +666,18 @@ impl QcContext {
667666
pub fn nav_compatible(&self) -> bool {
668667
self.observation().is_some() && self.brdc_navigation().is_some()
669668
}
669+
670670
/// True if Self is compatible with CPP positioning,
671671
/// see <https://docs.rs/gnss-rtk/latest/gnss_rtk/prelude/enum.Method.html#variant.CodePPP>
672672
pub fn cpp_compatible(&self) -> bool {
673673
// TODO: improve: only PR
674674
if let Some(obs) = self.observation() {
675-
obs.carrier().count() > 1
675+
obs.carrier_iter().count() > 1
676676
} else {
677677
false
678678
}
679679
}
680+
680681
/// [Self] cannot be True if self is compatible with PPP positioning,
681682
/// see <https://docs.rs/gnss-rtk/latest/gnss_rtk/prelude/enum.Method.html#variant.PPP>
682683
pub fn ppp_compatible(&self) -> bool {
@@ -705,21 +706,15 @@ impl QcContext {
705706
pub fn tropo_bias_model_optimization(&self) -> bool {
706707
self.has_meteo()
707708
}
709+
708710
/// Returns possible Reference position defined in this context.
709711
/// Usually the Receiver location in the laboratory.
710-
pub fn reference_position(&self) -> Option<GroundPosition> {
711-
if let Some(data) = self.observation() {
712-
if let Some(pos) = data.header.ground_position {
713-
return Some(pos);
714-
}
715-
}
716-
if let Some(data) = self.brdc_navigation() {
717-
if let Some(pos) = data.header.ground_position {
718-
return Some(pos);
719-
}
720-
}
721-
None
712+
pub fn reference_rx_orbit(&self) -> Option<Orbit> {
713+
let obs_rinex = self.observation()?;
714+
let first_epoch = obs_rinex.first_epoch()?;
715+
obs_rinex.header.rx_orbit(first_epoch, self.earth_cef)
722716
}
717+
723718
/// Apply preprocessing filter algorithm to mutable [Self].
724719
/// Filter will apply to all data contained in the context.
725720
pub fn filter_mut(&mut self, filter: &Filter) {

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![doc(html_logo_url = "https://raw.githubusercontent.com/rtk-rs/.github/master/logos/logo2.jpg")]
1+
#![doc(html_logo_url = "https://raw.githubusercontent.com/georust/meta/master/logo/logo.png")]
22
#![doc = include_str!("../README.md")]
33
#![cfg_attr(docsrs, feature(doc_cfg))]
44

@@ -25,7 +25,8 @@ pub mod prelude {
2525
pub use crate::plot::{Marker, MarkerSymbol, Mode, Plot};
2626
pub use maud::{html, Markup, Render};
2727
pub use qc_traits::{Filter, Preprocessing, Repair, RepairTrait};
28-
pub use rinex::prelude::{Almanac, Error as RinexError, Rinex};
28+
pub use rinex::prelude::nav::Almanac;
29+
pub use rinex::prelude::{Error as RinexError, Rinex};
2930
#[cfg(feature = "sp3")]
3031
pub use sp3::prelude::{Error as SP3Error, SP3};
3132
pub use std::path::Path;

src/report/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,10 @@ pub struct QcReport {
161161
impl QcReport {
162162
/// Builds a new GNSS report, ready to be rendered
163163
pub fn new(context: &QcContext, cfg: QcConfig) -> Self {
164-
let ref_position = if let Some(position) = cfg.manual_reference {
164+
let ref_position = if let Some(position) = cfg.manual_rx_orbit {
165165
Some(position)
166166
} else {
167-
context.reference_position()
167+
context.reference_rx_orbit()
168168
};
169169
let summary = QcSummary::new(&context, &cfg);
170170
let summary_only = cfg.report == QcReportType::Summary;

src/report/orbit.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rinex::{
22
navigation::Ephemeris,
3-
prelude::{Constellation, Epoch, GroundPosition, Orbit, Rinex, SV},
3+
prelude::{nav::Orbit, Constellation, Epoch, Rinex, SV},
44
};
55
use std::collections::{BTreeMap, HashMap};
66

@@ -158,13 +158,19 @@ pub struct OrbitReport {
158158
}
159159

160160
impl OrbitReport {
161-
pub fn new(ctx: &QcContext, reference: Option<GroundPosition>, force_brdc_sky: bool) -> Self {
162-
let (x0, y0, z0) = reference.unwrap_or_default().to_ecef_wgs84();
163-
let (x0_km, y0_km, z0_km) = (x0 / 1000.0, y0 / 1000.0, z0 / 1000.0);
161+
pub fn new(ctx: &QcContext, reference: Option<Orbit>, force_brdc_sky: bool) -> Self {
162+
let (x0_km, y0_km, z0_km) = match reference {
163+
Some(orbit) => {
164+
let pos_vel = orbit.to_cartesian_pos_vel();
165+
(pos_vel[0], pos_vel[1], pos_vel[2])
166+
}
167+
None => (0.0, 0.0, 0.0),
168+
};
164169

165170
// TODO: brdc needs a timeserie..
166171
#[cfg(feature = "sp3")]
167172
let brdc_skyplot = ctx.has_brdc_navigation() && ctx.has_sp3() && force_brdc_sky;
173+
168174
#[cfg(not(feature = "sp3"))]
169175
let brdc_skyplot = ctx.has_brdc_navigation();
170176

@@ -212,8 +218,9 @@ impl OrbitReport {
212218
}
213219
if brdc_skyplot {
214220
let brdc = ctx.brdc_navigation().unwrap();
221+
215222
if let Some(el_az_range) =
216-
brdc.sv_azimuth_elevation_range(sv_sp3, t, rx_orbit, &ctx.almanac)
223+
brdc.nav_azimuth_elevation_range(sv_sp3, t, rx_orbit, &ctx.almanac)
217224
{
218225
let (el_deg, az_deg) =
219226
(el_az_range.elevation_deg, el_az_range.azimuth_deg);
@@ -375,7 +382,7 @@ impl OrbitReport {
375382
if let Some(nav) = ctx.brdc_navigation() {
376383
for constellation in sp3.constellation() {
377384
if let Some(constellation) = nav
378-
.constellation()
385+
.constellations_iter()
379386
.filter(|c| *c == constellation)
380387
.reduce(|k, _| k)
381388
{

src/report/rinex/clock.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use itertools::Itertools;
22
use maud::{html, Markup, Render};
33
use qc_traits::{Filter, FilterItem, MaskOperand, Preprocessing};
4-
use rinex::prelude::{ClockProfileType, Constellation, Rinex, TimeScale, DOMES, SV};
4+
5+
use rinex::prelude::{clock::ClockProfileType, Constellation, Rinex, TimeScale, DOMES, SV};
56
use std::collections::HashMap;
67

78
use crate::report::shared::SamplingReport;
@@ -19,7 +20,7 @@ struct ConstellPage {
1920

2021
impl ConstellPage {
2122
fn new(rinex: &Rinex) -> Self {
22-
let satellites = rinex.sv().collect::<Vec<_>>();
23+
let satellites = rinex.sv_iter().collect::<Vec<_>>();
2324

2425
Self {
2526
offset_plot: {
@@ -195,7 +196,7 @@ impl ClkReport {
195196
sampling: SamplingReport::from_rinex(rnx),
196197
constellations: {
197198
let mut pages = HashMap::<Constellation, ConstellPage>::new();
198-
for constellation in rnx.constellation() {
199+
for constellation in rnx.constellations_iter() {
199200
let filter = Filter::mask(
200201
MaskOperand::Equals,
201202
FilterItem::ConstellationItem(vec![constellation]),

src/report/rinex/ionex.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub struct IonexReport {
1515
map_dimension: u8,
1616
epoch_first_map: Epoch,
1717
epoch_last_map: Epoch,
18-
sampling_interval: Duration,
18+
sampling_interval: Option<Duration>,
1919
reference: Reference,
2020
description: Option<String>,
2121
mapping: Option<MappingFunction>,
@@ -24,7 +24,7 @@ pub struct IonexReport {
2424

2525
impl IonexReport {
2626
pub fn new(rnx: &Rinex) -> Result<Self, Error> {
27-
let nb_of_maps = rnx.epoch().count();
27+
let nb_of_maps = rnx.epoch_iter().count();
2828
let header = rnx.header.ionex.as_ref().ok_or(Error::MissingIonexHeader)?;
2929
Ok(Self {
3030
nb_of_maps,
@@ -34,7 +34,7 @@ impl IonexReport {
3434
mapping: header.mapping.clone(),
3535
reference: header.reference.clone(),
3636
description: header.description.clone(),
37-
sampling_interval: rnx.dominant_sample_rate().ok_or(Error::SamplingAnalysis)?,
37+
sampling_interval: rnx.sampling_interval(),
3838
world_map: {
3939
let mut plot = Plot::world_map(
4040
"ionex_tec",
@@ -44,14 +44,17 @@ impl IonexReport {
4444
0,
4545
true,
4646
);
47+
48+
// Build one trace (1 map) per Epoch
4749
let mut buttons = Vec::<Button>::new();
48-
// one trace(=map) per Epoch
49-
for (epoch_index, epoch) in rnx.epoch().enumerate() {
50+
51+
for (epoch_index, epoch) in rnx.epoch_iter().enumerate() {
5052
let label = epoch.to_string();
53+
5154
let lat = rnx
52-
.tec()
55+
.ionex_tecu_latlong_ddeg_alt_km_iter()
5356
.filter_map(
54-
|(t, lat, _, _, _)| {
57+
|(t, _, lat, _, _)| {
5558
if t == epoch {
5659
Some(lat)
5760
} else {
@@ -60,8 +63,9 @@ impl IonexReport {
6063
},
6164
)
6265
.collect::<Vec<_>>();
66+
6367
let long = rnx
64-
.tec()
68+
.ionex_tecu_latlong_ddeg_alt_km_iter()
6569
.filter_map(
6670
|(t, _, long, _, _)| {
6771
if t == epoch {
@@ -72,12 +76,13 @@ impl IonexReport {
7276
},
7377
)
7478
.collect::<Vec<_>>();
75-
let tec = rnx
76-
.tec()
79+
80+
let tecu = rnx
81+
.ionex_tecu_latlong_ddeg_alt_km_iter()
7782
.filter_map(
78-
|(t, _, _, _, tec)| {
83+
|(t, tecu, _, _, _)| {
7984
if t == epoch {
80-
Some(tec)
85+
Some(tecu)
8186
} else {
8287
None
8388
}
@@ -88,12 +93,13 @@ impl IonexReport {
8893
let trace = Plot::density_mapbox(
8994
lat.clone(),
9095
long.clone(),
91-
tec,
96+
tecu,
9297
&label,
9398
0.6,
9499
3,
95100
epoch_index == 0,
96101
);
102+
97103
plot.add_trace(trace);
98104

99105
buttons.push(
@@ -114,6 +120,7 @@ impl IonexReport {
114120
.build(),
115121
);
116122
}
123+
117124
plot.add_custom_controls(buttons);
118125
plot
119126
},
@@ -160,10 +167,16 @@ impl Render for IonexReport {
160167
}
161168
tr {
162169
th class="is-info" {
163-
"Time Interval"
170+
"Sampling Period"
164171
}
165-
td {
166-
(self.sampling_interval.to_string())
172+
@ if let Some(sampling_interval) = &self.sampling_interval {
173+
td {
174+
(sampling_interval.to_string())
175+
}
176+
} @ else {
177+
td class="is-warning" {
178+
"Unknown"
179+
}
167180
}
168181
}
169182
tr {

0 commit comments

Comments
 (0)