geello 0.2.0

A tool to render geo data
Documentation
use crate::render_option::TileProj;
use geo::Rect;
use geo::{Coord, Geometry, MapCoordsInPlace};
const EARTH_RADIUS: f64 = 6378137.0;
const PI: f64 = std::f64::consts::PI;
const EPSG3857_XY_MAX: f64 = EARTH_RADIUS * PI;

pub fn is_default<T: Default + PartialEq>(value: &T) -> bool {
    value == &T::default()
}

pub fn get_rect_from_xyz(x: u32, y: u32, z: u32, proj: &TileProj) -> Rect {
    match proj {
        TileProj::EPSG3857 => get_rect_from_xyz_3857(x, y, z),
        TileProj::EPSG4326 => get_rect_from_xyz_4326(x, y, z),
    }
}
pub fn get_rect_from_xyz_4326(x: u32, y: u32, z: u32) -> Rect {
    if z == 0 {
        if x == 0 {
            Rect::new((-180f64, -90f64), (0f64, 90f64))
        } else if x == 1 {
            Rect::new((0f64, -90f64), (180f64, 90f64))
        } else {
            Rect::new((-182f64, -92f64), (-181f64, -91f64))
        }
    } else {
        let x_n = 2u32.pow(z + 1);
        let y_n = 2u32.pow(z);
        let lon_deg = 360.0 / x_n as f64;
        let lat_deg = 180.0 / y_n as f64;
        let min_lon = x as f64 * lon_deg - 180.0;
        let max_lat = 90.0 - y as f64 * lat_deg;
        let max_lon = min_lon + lon_deg;
        let min_lat = max_lat - lat_deg;
        Rect::new((min_lon, min_lat), (max_lon, max_lat))
    }
}
pub fn get_rect_from_xyz_3857(x: u32, y: u32, z: u32) -> Rect {
    let n = 2u32.pow(z);
    let deg = EPSG3857_XY_MAX * 2f64 / n as f64;
    let min_lon = x as f64 * deg - EPSG3857_XY_MAX;
    let max_lat = EPSG3857_XY_MAX - y as f64 * deg;
    let max_lon = min_lon + deg;
    let min_lat = max_lat - deg;
    Rect::new((min_lon, min_lat), (max_lon, max_lat))
}

pub fn transform(geom: &mut Geometry, proj: &TileProj) {
    match proj {
        TileProj::EPSG4326 => transform_3857_to_4326(geom),
        TileProj::EPSG3857 => transform_4326_to_3857(geom),
    }
}

pub fn transform_3857_to_4326(geom: &mut Geometry) {
    geom.map_coords_in_place(|Coord { x, y }| -> Coord {
        let (x, y) = transform_3857_to_4326_point(x, y);
        Coord { x, y }
    });
}

pub fn transform_4326_to_3857(geom: &mut Geometry) {
    geom.map_coords_in_place(|Coord { x, y }| -> Coord {
        let (x, y) = transform_4326_to_3857_point(x, y);
        Coord { x, y }
    });
}

pub fn transform_4326_to_3857_point(x: f64, y: f64) -> (f64, f64) {
    let x = x * EPSG3857_XY_MAX / 180f64;
    let y = ((y + 90f64) * PI / 360f64).tan().ln() / (PI / 180f64);
    let y = y * EPSG3857_XY_MAX / 180f64;
    (x, y)
}

pub fn transform_3857_to_4326_point(x: f64, y: f64) -> (f64, f64) {
    let x = x * 180f64 / EPSG3857_XY_MAX;
    let y = y * 180f64 / EPSG3857_XY_MAX;
    let y = ((y * (PI / 180f64)).exp().atan() * 360f64) / PI - 90f64;
    (x, y)
}