1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
//! Unlike all other raw projections `Mercator` and `MercatorTransverse` are
//! hard coded to work only with f64s The Additional dynamic range/
//! resolution is essential in giving accurate results near the poles.
use core::fmt::Debug;
use geo_types::Coord;
use num_traits::float::FloatConst;
use crate::projection::ScaleSet;
use crate::Transform;
use super::builder_mercator::types::BuilderMercatorAntimeridianResampleClip;
use super::builder_mercator::Builder as MercatorBuilder;
use super::RawBase;
use super::TransformExtent;
/// Projection definition. ``Mercator::builder()`` returns a builder.
#[derive(Clone, Debug, Default)]
pub struct Mercator {}
impl RawBase for Mercator {
type Builder<DRAIN: Clone> = BuilderMercatorAntimeridianResampleClip<DRAIN, Self, f64>;
#[inline]
fn builder<DRAIN: Clone>() -> Self::Builder<DRAIN> {
let mut default: Self::Builder<DRAIN> = MercatorBuilder::new(Self {});
default.scale_set(961_f64 / f64::TAU());
default
}
}
impl TransformExtent for Mercator {
type T = f64;
#[inline]
fn transform_extent(
&self,
k: f64,
t: Coord<f64>,
x0: f64,
y0: f64,
x1: f64,
y1: f64,
) -> [Coord<f64>; 2] {
[
Coord {
x: f64::max(t.x - k, x0),
y: y0,
},
Coord {
x: f64::min(t.x + k, x1),
y: y1,
},
]
}
}
impl Transform for Mercator {
type T = f64;
#[inline]
fn transform(&self, p: &Coord<f64>) -> Coord<f64> {
// Divergence between f64 and f32
// when p.y = 1.5707963267948966 (PI/2)
// f64 outputs -37.33185619326892 which is consistent
// with JS.
// The f32 is different from JS. Technically
// tan(PI/2) is NAN. and so log(NAN) is NAN.
// The value returned
// from tan(PI_f64/2_f64) happens to be the same
// large number in both the JS and RUST.
Coord {
x: p.x,
y: ((f64::FRAC_PI_2() + p.y) / 2f64).tan().ln(),
}
}
#[inline]
fn invert(&self, p: &Coord<f64>) -> Coord<f64> {
Coord {
x: p.x,
y: 2f64.mul_add((p.y.exp()).atan(), -f64::FRAC_PI_2()),
}
}
}