gnss_qc/context/
sp3.rs

1use crate::{
2    context::BlobData,
3    error::Error,
4    prelude::{ProductType, QcContext, SP3},
5};
6
7use qc_traits::Merge;
8
9use std::path::Path;
10
11impl QcContext {
12    /// Add this [SP3] into current [QcContext].
13    /// File revision must be supported and must be correctly formatted
14    /// for this operation to be effective.
15    pub fn load_sp3<P: AsRef<Path>>(&mut self, path: P, sp3: SP3) -> Result<(), Error> {
16        let prod_type = ProductType::HighPrecisionOrbit;
17
18        let path_buf = path.as_ref().to_path_buf();
19
20        // extend context blob
21        if let Some(paths) = self
22            .files
23            .iter_mut()
24            .filter_map(|(prod, files)| {
25                if *prod == prod_type {
26                    Some(files)
27                } else {
28                    None
29                }
30            })
31            .reduce(|k, _| k)
32        {
33            if let Some(inner) = self.blob.get_mut(&prod_type).and_then(|k| k.as_mut_sp3()) {
34                inner.merge_mut(&sp3)?;
35                paths.push(path_buf);
36            }
37        } else {
38            self.blob.insert(prod_type, BlobData::SP3(sp3));
39            self.files.insert(prod_type, vec![path_buf]);
40        }
41        Ok(())
42    }
43
44    /// Load readable [SP3] file into this [QcContext].
45    pub fn load_sp3_file<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
46        let sp3 = SP3::from_file(&path)?;
47        self.load_sp3(path, sp3)
48    }
49
50    /// Returns true if [ProductType::HighPrecisionOrbit] are present in current [QcContext]
51    pub fn has_sp3(&self) -> bool {
52        self.sp3().is_some()
53    }
54
55    /// Returns true if any [SP3] previously loaded came with clock information.
56    pub fn sp3_has_clock(&self) -> bool {
57        if let Some(sp3) = self.sp3() {
58            sp3.has_satellite_clock_offset()
59        } else {
60            false
61        }
62    }
63
64    /// Returns reference to inner SP3 data
65    pub fn sp3(&self) -> Option<&SP3> {
66        self.data(ProductType::HighPrecisionOrbit)?.as_sp3()
67    }
68
69    /// Returns mutable reference to inner [ProductType::HighPrecisionOrbit] data
70    pub fn sp3_mut(&mut self) -> Option<&mut SP3> {
71        self.data_mut(ProductType::HighPrecisionOrbit)?.as_mut_sp3()
72    }
73
74    pub fn is_ppp_ultra_navigation_compatible(&self) -> bool {
75        // TODO: improve
76        //      verify clock().ts and obs().ts do match
77        //      and have common time frame
78        self.clock().is_some() && self.sp3_has_clock() && self.is_cpp_navigation_compatible()
79    }
80}