use geometry_coords::CoordinateScalar;
use geometry_cs::{AngleUnit, FromF64, Geographic, Polar, Spherical};
use geometry_trait::Point;
pub(crate) trait HasAngularUnits {
type Units: AngleUnit;
}
impl<U: AngleUnit> HasAngularUnits for Spherical<U> {
type Units = U;
}
impl<U: AngleUnit> HasAngularUnits for Geographic<U> {
type Units = U;
}
impl<U: AngleUnit> HasAngularUnits for Polar<U> {
type Units = U;
}
pub(crate) fn lonlat_radians<P>(p: &P) -> (P::Scalar, P::Scalar)
where
P: Point,
P::Scalar: CoordinateScalar + FromF64,
P::Cs: HasAngularUnits,
{
let lon = p.get::<0>();
let lat = p.get::<1>();
(
<P::Cs as HasAngularUnits>::Units::to_radians(lon),
<P::Cs as HasAngularUnits>::Units::to_radians(lat),
)
}
#[cfg(test)]
mod tests {
use super::*;
use geometry_adapt::{Adapt, WithCs};
use geometry_cs::{Degree, Radian, Spherical};
#[test]
fn degree_input_matches_radian_input() {
let in_deg: WithCs<Adapt<[f64; 2]>, Spherical<Degree>> =
WithCs::new(Adapt([10.0_f64, 20.0]));
let in_rad: WithCs<Adapt<[f64; 2]>, Spherical<Radian>> =
WithCs::new(Adapt([10.0_f64.to_radians(), 20.0_f64.to_radians()]));
let (lon_d, lat_d) = lonlat_radians(&in_deg);
let (lon_r, lat_r) = lonlat_radians(&in_rad);
assert!((lon_d - lon_r).abs() < 1e-12);
assert!((lat_d - lat_r).abs() < 1e-12);
}
}