gistools/proj/project/
tcea.rs

1use crate::proj::{CoordinateStep, Proj, ProjectCoordinates, TransformCoordinates};
2use alloc::rc::Rc;
3use core::cell::RefCell;
4use libm::{asin, atan2, cos, sin, sqrt, tan};
5
6/// Transverse Cylindrical Equal Area Projection
7#[derive(Debug, Clone, PartialEq)]
8pub struct TransverseCylindricalEqualArealProjection {
9    proj: Rc<RefCell<Proj>>,
10}
11impl ProjectCoordinates for TransverseCylindricalEqualArealProjection {
12    fn code(&self) -> i64 {
13        -1
14    }
15    fn name(&self) -> &'static str {
16        "Transverse Cylindrical Equal Area"
17    }
18    fn names() -> &'static [&'static str] {
19        &["Transverse Cylindrical Equal Area", "tcea"]
20    }
21}
22impl CoordinateStep for TransverseCylindricalEqualArealProjection {
23    fn new(proj: Rc<RefCell<Proj>>) -> Self {
24        proj.borrow_mut().es = 0.;
25        TransverseCylindricalEqualArealProjection { proj }
26    }
27    fn forward<P: TransformCoordinates>(&self, p: &mut P) {
28        tcea_s_forward(&self.proj.borrow(), p);
29    }
30    fn inverse<P: TransformCoordinates>(&self, p: &mut P) {
31        tcea_s_inverse(&self.proj.borrow(), p);
32    }
33}
34
35/// Transverse Cylindrical Equal Area forward project
36pub fn tcea_s_forward<P: TransformCoordinates>(proj: &Proj, p: &mut P) {
37    p.set_x(cos(p.phi()) * sin(p.lam()) / proj.k0);
38    p.set_y(proj.k0 * (atan2(tan(p.phi()), cos(p.lam())) - proj.phi0));
39}
40
41/// Transverse Cylindrical Equal Area inverse project
42pub fn tcea_s_inverse<P: TransformCoordinates>(proj: &Proj, p: &mut P) {
43    let y = p.y() / proj.k0 + proj.phi0;
44    let x = p.x() * proj.k0;
45    let t = sqrt(1. - x * x);
46    p.set_phi(asin(t * sin(y)));
47    p.set_lam(atan2(x, t * cos(y)));
48}