SP3 Precise GNSS Orbit and Clock parser :artificial_satellite:

Overview

SP3

crates.io Rust crates.io crates.io License License

SP3 Precise GNSS Orbit files parser.

SP3 is specifid by IGS.

The parser only supports Revisions C & D at the moment and rejects revisions A & B.

Getting started

Add "sp3" to you cargo file

[dependencies]
sp3 = "1"

Parse an SP3 file

use crate::prelude::*;
use rinex::prelude::Constellation;
use std::path::PathBuf;
use std::str::FromStr;
    
let path = PathBuf::new()
    .join(env!("CARGO_MANIFEST_DIR"))
    .join("data")
    .join("ESA0OPSRAP_20232390000_01D_15M_ORB.SP3.gz");

let sp3 = SP3::from_file(&path.to_string_lossy());
assert!(
    sp3.is_ok(),
    "failed to parse ESA0OPSRAP_20232390000_01D_15M_ORB.SP3.gz : {:?}",
    sp3.err()
);

let sp3 = sp3.unwrap();

/*
 * Test general infos
 */
assert_eq!(sp3.version, Version::C);
assert_eq!(sp3.data_type, DataType::Position);

assert_eq!(
    sp3.first_epoch(),
    Some(Epoch::from_str("2023-08-27T00:00:00 GPST").unwrap())
);

assert_eq!(sp3.nb_epochs(), 96, "bad number of epochs");
assert_eq!(sp3.coord_system, "ITRF2");
assert_eq!(sp3.orbit_type, OrbitType::BHN);
assert_eq!(sp3.time_system, TimeScale::GPST);
assert_eq!(sp3.constellation, Constellation::Mixed);
assert_eq!(sp3.agency, "ESOC");

assert_eq!(sp3.week_counter, (2277, 0.0_f64));
assert_eq!(sp3.epoch_interval, Duration::from_seconds(900.0_f64));

// browse SV positions
for (epoch, sv, (x, y, z)) in sp3.sv_position() {

}

// browse SV clock
for (epoch, sv, clock) in sp3.sv_clock() {

}

File Merge

Merge files together, for example to create a context spanning 48 hours

let folder = PathBuf::new()
    .join(env!("CARGO_MANIFEST_DIR"))
    .join("data");

let sp3_a = folder.clone()
    .join("ESA0OPSRAP_20232390000_01D_15M_ORB.SP3.gz");

let sp3_b = folder.clone()
    .join("ESA0OPSULT_20232320600_02D_15M_ORB.SP3.gz");

let sp3 = SP3::from_file(&sp3_a.to_string_lossy())
    .unwrap();

let sp3_b = SP3::from_file(&sp3_b.to_string_lossy())
    .unwrap();

let sp3 = sp3_a.merge(sp3_b);
assert!(sp3.is_ok());

Position Vector Interpolation

Interpolate SV position at desired Epoch.
In order to preserve the high (+/- 1mm precision) for SP3 datasets, we recommend using at least an interpolation order of 9 for typical SP3 files with 15' epoch intervals.

The current implementation restricts the interpolatable Epochs at [tmin, tmax] = [(N +1)/2 * τ, T(n-1) - (N +1)/2 * τ], both included, where N is the interpolation order, τ the epoch interval, and T(n-1) the last Epoch in this file.

Refer to the online API for more information

use sp3::prelude::*;
use rinex::sv;
use std::str::FromStr;
use std::path::PathBuf;
use rinex::prelude::Sv;

let path = PathBuf::new()
    .join(env!("CARGO_MANIFEST_DIR"))
    .join("data")
    .join("ESA0OPSRAP_20232390000_01D_15M_ORB.SP3.gz");

let sp3 = SP3::from_file(&path.to_string_lossy())
    .unwrap();

let epoch = Epoch::from_str("2023-08-27T00:00:00 GPST")
    .unwrap();
let interpolated = sp3.interpolate(epoch, sv!("G01"), 11);
assert!(interpolated.is_none(), "too early in this file");

let epoch = Epoch::from_str("2023-08-27T08:15:00 GPST")
   .unwrap();
let interpolated = sp3.interpolate(epoch, sv!("G01"), 11);
assert!(interpolated.is_some());
let (x, y, z) = interpolated.unwrap();
// demonstrate error is still sub cm
assert!((x - 13281.083885).abs() * 1.0E3 < 1.0E-2); // distances are expressed in km in all SP3
assert!((y - -11661.887057).abs() * 1.0E3 < 1.0E-2);
assert!((z - 19365.687261).abs() * 1.0E3 < 1.0E-2);
You might also like...
A parser combinator that is fully statically dispatched and supports both sync/async.

XParse A parser combinator that is fully statically dispatched and supports both sync & async parsing. How to use An example of a very simple JSON par

A device-tree source parser, analyzer and language server.

Ginko A device-tree source parser, analyzer and language server. The main goal of this project is to make working with device-trees easy. For example,

Shiva library: Implementation in Rust of a parser and generator for documents of any type
Shiva library: Implementation in Rust of a parser and generator for documents of any type

Shiva Shiva library: Implementation in Rust of a parser and generator for documents of any type Features Common Document Model (CDM) for all document

A full featured, fast Command Line Argument Parser for Rust

clap Command Line Argument Parser for Rust It is a simple-to-use, efficient, and full-featured library for parsing command line arguments and subcomma

Docopt for Rust (command line argument parser).

THIS CRATE IS UNMAINTAINED This crate is unlikely to see significant future evolution. The primary reason to choose this crate for a new project is if

A minimal argument parser

Pieces An argument parser built with control in mind. Parsing The results you get are dependent on what order you parse in. If you want to say only pa

A full featured, fast Command Line Argument Parser for Rust

clap Command Line Argument Parser for Rust It is a simple-to-use, efficient, and full-featured library for parsing command line arguments and subcomma

Simple command line flag parser for rust.

easy_flag Simple command line flag parser for rust. use easy_flag::FlagSet; fn main() - Result(), String{ let mut help = false; let mut my

Parser for CARGO_ENCODED_RUSTFLAGS

Parser for CARGO_ENCODED_RUSTFLAGS CARGO_ENCODED_RUSTFLAGS is one of the environment variables provided by Cargo to build scripts. It synthesizes seve

Releases(v1.0.0)
Owner
gwbres
@oscimp, @georust
gwbres
Ergonomic and precise error handling provided by error sets. Inspired by Zig's error set type.

Error Set Error Set simplifies error management by providing a streamlined method for defining errors and easily converting between them. Resultingly,

Henry 61 Jul 24, 2024
ergonomic and precise error handling built atop type-level set arithmetic

terrors - the Rust error handling library Handling errors means taking a set of possible error types, removing the ones that are locally addressible,

Komora 190 Jul 27, 2024
Kit-kat clock utility rewritten in Rust using minifb

kitkat clock in Rust This is the plan9 cat clock utility rewritten in rust with minifb crate. $ kitkat --help Usage: kitkat [--hook|--crazy|--offset O

Manos Pitsidianakis 18 Oct 19, 2022
A terminal clock that uses 7-segment display characters

Seven-segment clock (7clock) 7clock.3.mp4 This is a clock for terminals that uses the Unicode seven-segment display characters added in Unicode 13.0.

Wesley Moore 4 Nov 11, 2022
A language parser tool to build recursive descent top down parser.

lang-pt A language parser tool to generate recursive descent top down parser. Overview Parsers written for the languages like Javascript are often cus

Creative Forest 7 Jan 4, 2023
Pure-Rust rewrite of the Linux fontconfig library (no system dependencies) - using ttf-parser and allsorts

rust-fontconfig Pure-Rust rewrite of the Linux fontconfig library (no system dependencies) - using allsorts as a font parser in order to parse .woff,

Felix Schütt 28 Oct 29, 2022
lemmy-help is a emmylua parser as well as a CLI which takes that parsed tree and converts it into vim help docs.

lemmy-help is a emmylua parser as well as a CLI which takes that parsed tree and converts it into vim help docs.

Vikas Raj 117 Jan 3, 2023
A simple, lightweight and extensible command line argument parser for rust codebases

A simple, lightweight and extensible command line argument parser for rust codebases. This crate aims to provide you with an easy-to-use and extensibl

Victor Ndaba 20 Nov 12, 2022
A parser and evaluator of spreadsheet-like formulas

Formula A parser and evaluator of spreadsheet-like formulas Formula is in its early stages, so it's better to be used cautiously. So far we have the f

Omid Rad 5 Dec 18, 2022
A parser and matcher for route patterns in Rust 🦀

Route Pattern A parser and matcher for a popular way to create route patterns. Patterns like these that include regular expressions, delimited in this

Dotan J. Nahum 3 Nov 24, 2022