# GNSS
[](https://github.com/nav-solutions/gnss/actions/workflows/rust.yml)
[](https://github.com/nav-solutions/gnss/actions/workflows/daily.yml)
[](https://crates.io/crates/gnss-rs)
[](https://docs.rs/gnss-rs)
[](https://discord.gg/EqhEBXBmJh)
[](https://github.com/nav-solutions/qc-traits/blob/main/LICENSE)
High level definitions to work with GNSS in Rust or Python
+ Space Vehicles definitions: `SV`
+ GNSS Constellations: `Constellation`
+ GNSS Timescales: `Constellation.timescale()`
+ Python casts using `python` feature
## Getting started
Add "gnss" to your Cargo.toml
```toml
gnss-rs = "2"
```
## Features
- `std`: this library is no-std compatible by default.
- `sbas`: activates the detailed SBAS database, for more information about SBAS vehicles.
This feature requires `std` library.
- `domes`: defines the DOMES reference site number.
This feature does not require `std` library.
- `cospar`: defines the COSPAR satellite launch number
This feature requires `std` library.
## Constellation database
This library defines both constellations (single enum) and satellites (SV structure) from these constellations.
```rust
use std::str::FromStr;
use gnss_rs::prelude::*;
use hifitime::{TimeScale, Epoch};
// It is possible to define satellites that do not exist
let sv = SV::new(Constellation::GPS, 1);
assert_eq!(sv.prn, 1);
assert_eq!(sv.constellation, Constellation::GPS);
assert_eq!(sv.timescale(), Some(TimeScale::GPST)); // convenient method
assert_eq!(sv.constellation.country_code(), Some("US".to_string())); // convenient method
assert_eq!(Constellation::GPS.to_string(), "GPS (US)"); // readable format
assert_eq!(format!("{:E}", Constellation::GPS), "GPS"); // standard accronym
assert_eq!(format!("{:x}", Constellation::GPS), "G"); // RINEX like format
assert_eq!(Constellation::from_str("G"), Ok(Constellation::GPS)); // reciprocal
assert_eq!(Constellation::from_str("GPS (US)"), Ok(Constellation::GPS)); // reciprocal
assert_eq!(sv.launch_datetime(), None); // only available for GEO satellites (SBAS)
```
## SBAS (Geostationary services)
We offer convenient methods to handle SBAS (geostationary services).
For example, we integrate a builtin database to define most known SBAS services.
```rust
use std::str::FromStr;
use gnss_rs::prelude::*;
use hifitime::{TimeScale, Epoch, MonthName};
let egnos = Constellation::EGNOS;
assert!(egnos.is_sbas(), "obvious");
assert_eq!(egnos.timescale(), Some(TimeScale::GPST)); // we refer GEO services to GPST
// convenient builder for RINEX and other similar applications.
// Must be known to our database for this to work.
// The database is defined in data/sbas.json
let geo23 = SV::new_sbas(23).unwrap();
assert_eq!(geo23.constellation, Constellation::EGNOS);
// convenient information using our builtin database
assert_eq!(geo23.launch_datetime().and_then(|e| Some(e.to_string())), Some("2021-11-01T00:00:00 UTC".to_string()));
```
All this information is provided by default. If you compiled the library with the "sbas" option,
we provide a selection helper that helps select the GEO service, for given user coordinates.
```rust
use geo::Point;
use gnss_rs::{
sbas_selector,
prelude::Constellation,
};
let paris = Point::new(2.38268, 48.808378); //x=longitude°, y=latitude°
assert_eq!(sbas_selector(paris), Some(Constellation::EGNOS));
```
## COSPAR definition
When compiled with the "COSPAR" option, the library defines the `COSPAR`
launch identifier (unique number).
```rust
use gnss_rs::prelude::COSPAR;
use std::str::FromStr;
assert!(COSPAR::from_str("2018-080A").is_ok());
```
## DOMES definition
When compiled with the "DOMES" option, the library provides the definition
of [DOMES (IGS) site identification number](https://itrf.ign.fr/en/network/domes/description).
- The SERDE features unlocks serialization/deserialization of the main structures defined here.
- The DOMES features unlocks the definition of DOMES GNSS/IGS reference station,
that are widely used in GNSS data processing. This number identifies a station uniquely.
- The COSPAR features unlocks the definition of the COSPAR (Launch) ID number.
This number identifies the launch of a vehicule uniquely. It is used in RINEX
and other files format.
- The SBAS feature will create a static database that defines each SBAS service areas,
projected on ground as WKT/GEO objects, with one method to select a SBAS service based
on Latitude and Longitude coordinates.
## Relevant Ecosystems
Many libraries exist nowadays to process GNSS data or perform typical GNSS processing tasks.
Amongst them, be sure to checkout:
- [Nyx](https://github.com/nyx-space/nyx): Orbital navigation
- [ANISE](https://github.com/nyx-space/anise): Earth orientation modeling and Orbital navigation
- [GNSS-RTK](https://github.com/nav-solutions/gnss-rtk): Precise Point Positioning, related calculations and modeling
- [RINEX](https://github.com/nav-solutions/rinex): files processing and management
- [SP3](https://github.com/nav-solutions/sp3): files processing and management
- [Hifitime](https://github.com/nyx-space/hifitime): Timescale and related calculations
- [CGGTTS](https://github.com/nav-solutions/cggtts): files production and processing
## Python bindings
Install with maturin
```bash
maturin develop # local install
```
Install from pypi directly:
```bash
pip3 install gnss-rs
```
Getting started:
```python
from gnss import Constellation, SV, TimeScale
gps = Constellation.GPS
assert "{}".format(gps), "GPS (US)"
assert "{:x}".format(gps), "GPS" # drop country code
# smart builder
assert Constellation.from_country_code("US"), Constellation.GPS
# PRN# is not checked, it is up to you to create valid satellites.
sat = SV(Constellation.GPS, 10)
assert sat.prn == 10
assert sat.timescale() == TimeScale.GPST
sat.constellation = Constellation.BeiDou
assert "{}".format(sat.constellation, "BeiDou (CH)")
assert "{:x}".format(sat.constellation, "BDS") # drop country code
assert sat.timescale() == TimeScale.BDT
```
## License
This library is part of the [NAV-Solutions framework](https://github.com/nav-solutions) which
is licensed under [Mozilla V2 Public](https://www.mozilla.org/en-US/MPL/2.0) license.