pub const fn es_from_rf(rf: f64) -> f64 {
let f = 1.0 / rf;
2.0 * f - f * f
}
pub const WGS84_A: f64 = 6_378_137.0;
pub const WGS84_RF: f64 = 298.257_223_563;
pub const WGS84_F: f64 = 1.0 / WGS84_RF;
pub const WGS84_ES: f64 = es_from_rf(WGS84_RF);
pub const WGS84_E: f64 = 0.081_819_190_842_622_0;
pub const GRS80_A: f64 = 6_378_137.0;
pub const GRS80_RF: f64 = 298.257_222_101;
pub const GRS80_F: f64 = 1.0 / GRS80_RF;
pub const GRS80_ES: f64 = es_from_rf(GRS80_RF);
const _SELF_CHECK: () = {
assert!(WGS84_ES > 0.0);
assert!(WGS84_ES < 1.0);
assert!(GRS80_ES > 0.0);
assert!(GRS80_ES < 1.0);
assert!(WGS84_E > 0.08);
assert!(WGS84_E < 0.09);
};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wgs84_es_matches_computed() {
let rt = crate::Ellipsoid::named("WGS84").expect("WGS84");
assert!(
(WGS84_ES - rt.es).abs() < 1e-15,
"WGS84_ES={} vs runtime es={}",
WGS84_ES,
rt.es
);
}
#[test]
fn wgs84_e_squared_matches_es() {
assert!(
(WGS84_E * WGS84_E - WGS84_ES).abs() < 1e-12,
"WGS84_E²={} vs WGS84_ES={}",
WGS84_E * WGS84_E,
WGS84_ES
);
}
#[test]
fn grs80_es_matches_computed() {
let rt = crate::Ellipsoid::named("GRS80").expect("GRS80");
assert!(
(GRS80_ES - rt.es).abs() < 1e-15,
"GRS80_ES={} vs runtime es={}",
GRS80_ES,
rt.es
);
}
#[test]
fn es_from_rf_is_accurate_wgs84() {
let f = WGS84_F;
let expected = 2.0 * f - f * f;
assert!(
(WGS84_ES - expected).abs() < 1e-18,
"const es_from_rf mismatch: {} vs {}",
WGS84_ES,
expected
);
}
#[test]
fn wgs84_a_matches_named() {
let rt = crate::Ellipsoid::named("WGS84").expect("WGS84");
assert_eq!(WGS84_A, rt.a, "WGS84_A must match named ellipsoid");
}
#[test]
fn grs80_a_matches_named() {
let rt = crate::Ellipsoid::named("GRS80").expect("GRS80");
assert_eq!(GRS80_A, rt.a, "GRS80_A must match named ellipsoid");
}
#[test]
fn constants_are_truly_const() {
const TEST_A: f64 = WGS84_A;
const TEST_ES: f64 = WGS84_ES;
assert_eq!(TEST_A, WGS84_A);
assert_eq!(TEST_ES, WGS84_ES);
}
}