gistools/proj/project/
tcea.rs1use crate::proj::{CoordinateStep, Proj, ProjectCoordinates, TransformCoordinates};
2use alloc::rc::Rc;
3use core::cell::RefCell;
4use libm::{asin, atan2, cos, sin, sqrt, tan};
5
6#[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
35pub 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
41pub 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}