16 个版本 (8 个稳定)

1.0.8 2024 年 4 月 27 日
1.0.7 2024 年 2 月 25 日
1.0.6 2023 年 10 月 14 日
1.0.4 2023 年 9 月 19 日
0.0.8 2023 年 8 月 31 日

#39 in 地理空间

每月 48 次下载
用于 4 个 crate(3 个直接使用)

MIT/Apache

61KB
1.5K SLoC

SP3

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

SP3 精确 GNSS 轨道文件解析器。

SP3 由 IGS 制定。

目前解析器仅支持修订版 C & D,并拒绝修订版 A & B。

入门

将 "sp3" 添加到您的 cargo 文件中

[dependencies]
sp3 = "1"

解析 SP3 文件

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() {

}

文件合并

合并文件,例如创建跨越 48 小时的上下文

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());

位置矢量插值

在期望的时元插值 SV 位置。
为了保留 SP3 数据集的高精度(+/- 1mm 精度),我们建议对于典型 SP3 文件(15' 时元间隔),至少使用 9 阶的插值。

当前实现限制可插值时元为 [tmin, tmax] = [(N +1)/2 * τ, T(n-1) - (N +1)/2 * τ],包括两者,其中 N 是插值阶数,τ 是时元间隔,T(n-1) 是此文件中的最后一个时元。

请参考在线 API 获取更多信息

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);

依赖项

~2.5–5MB
~94K SLoC