use crate::proj::{CoordinateStep, Proj, ProjectCoordinates, TransformCoordinates};
use alloc::rc::Rc;
use core::{cell::RefCell, f64::consts::FRAC_PI_4};
use libm::{atan, exp, log, tan};
#[derive(Debug, Clone, PartialEq)]
pub struct MillerCylindricalProjection {
proj: Rc<RefCell<Proj>>,
}
impl ProjectCoordinates for MillerCylindricalProjection {
fn code(&self) -> i64 {
-1
}
fn name(&self) -> &'static str {
"Miller Cylindrical"
}
fn names() -> &'static [&'static str] {
&["MillerCylindrical", "Miller Cylindrical", "Miller_Cylindrical", "mill"]
}
}
impl CoordinateStep for MillerCylindricalProjection {
fn new(proj: Rc<RefCell<Proj>>) -> Self {
proj.borrow_mut().es = 0.;
MillerCylindricalProjection { proj }
}
fn forward<P: TransformCoordinates>(&self, p: &mut P) {
mill_s_forward(p);
}
fn inverse<P: TransformCoordinates>(&self, p: &mut P) {
mill_s_inverse(p);
}
}
pub fn mill_s_forward<P: TransformCoordinates>(p: &mut P) {
p.set_x(p.lam());
p.set_y(log(tan(FRAC_PI_4 + p.phi() * 0.4)) * 1.25);
}
pub fn mill_s_inverse<P: TransformCoordinates>(p: &mut P) {
p.set_lam(p.x());
p.set_phi(2.5 * (atan(exp(0.8 * p.y())) - FRAC_PI_4));
}