use crate::dms::dmstor;
use crate::error::ProjResult;
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PrimeMeridianDef {
pub id: &'static str,
pub defn: &'static str,
}
pub static PRIME_MERIDIANS: &[PrimeMeridianDef] = &[
PrimeMeridianDef {
id: "greenwich",
defn: "0dE",
},
PrimeMeridianDef {
id: "lisbon",
defn: "9d07'54.862\"W",
},
PrimeMeridianDef {
id: "paris",
defn: "2d20'14.025\"E",
},
PrimeMeridianDef {
id: "bogota",
defn: "74d04'51.3\"W",
},
PrimeMeridianDef {
id: "madrid",
defn: "3d41'16.58\"W",
},
PrimeMeridianDef {
id: "rome",
defn: "12d27'8.4\"E",
},
PrimeMeridianDef {
id: "bern",
defn: "7d26'22.5\"E",
},
PrimeMeridianDef {
id: "jakarta",
defn: "106d48'27.79\"E",
},
PrimeMeridianDef {
id: "ferro",
defn: "17d40'W",
},
PrimeMeridianDef {
id: "brussels",
defn: "4d22'4.71\"E",
},
PrimeMeridianDef {
id: "stockholm",
defn: "18d3'29.8\"E",
},
PrimeMeridianDef {
id: "athens",
defn: "23d42'58.815\"E",
},
PrimeMeridianDef {
id: "oslo",
defn: "10d43'22.5\"E",
},
PrimeMeridianDef {
id: "copenhagen",
defn: "12d34'40.35\"E",
},
];
pub fn find_prime_meridian(id: &str) -> Option<&'static PrimeMeridianDef> {
PRIME_MERIDIANS.iter().find(|p| p.id == id)
}
pub fn prime_meridian_offset(id: &str) -> ProjResult<f64> {
match find_prime_meridian(id) {
Some(pm) => dmstor(pm.defn),
None => Err(crate::error::ProjError::IllegalArgValue),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::consts::DEG_TO_RAD;
#[test]
fn table_has_fourteen_entries() {
assert_eq!(PRIME_MERIDIANS.len(), 14);
}
#[test]
fn greenwich_is_zero() {
assert_eq!(prime_meridian_offset("greenwich").expect("greenwich"), 0.0);
}
#[test]
fn paris_offset_matches() {
let expected = 2.337_229_166_666_667 * DEG_TO_RAD;
assert!((prime_meridian_offset("paris").expect("paris") - expected).abs() < 1e-9);
}
#[test]
fn ferro_is_west_negative() {
let expected = -17.666_666_666_666_67 * DEG_TO_RAD;
assert!((prime_meridian_offset("ferro").expect("ferro") - expected).abs() < 1e-9);
}
#[test]
fn unknown_id_not_found() {
assert!(find_prime_meridian("nope").is_none());
}
#[test]
fn unknown_offset_is_error() {
assert!(prime_meridian_offset("nope").is_err());
}
#[test]
fn lisbon_is_west_negative() {
assert!(prime_meridian_offset("lisbon").expect("lisbon") < 0.0);
}
#[test]
fn rome_is_east_positive() {
assert!(prime_meridian_offset("rome").expect("rome") > 0.0);
}
}