use std::ops::{Add, Sub};
const COORD_PRECISION: f64 = 10_000_000.0;
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
pub struct Coordinate {
pub lat: i32,
pub lon: i32,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Boundary {
pub min: Coordinate,
pub max: Coordinate,
pub freeze: bool,
}
impl Coordinate {
pub fn new(lat: f64, lon: f64) -> Coordinate {
let int_lat = (lat * COORD_PRECISION) as i32;
let int_lon = (lon * COORD_PRECISION) as i32;
Coordinate {
lat: int_lat,
lon: int_lon,
}
}
pub fn lat(self) -> f64 {
self.lat as f64 / COORD_PRECISION
}
pub fn lon(self) -> f64 {
self.lon as f64 / COORD_PRECISION
}
}
impl Sub for Coordinate {
type Output = Coordinate;
fn sub(self, rhs: Self) -> Self::Output {
Coordinate {
lon: self.lon - rhs.lon,
lat: self.lat - rhs.lat,
}
}
}
impl Add for Coordinate {
type Output = Coordinate;
fn add(self, rhs: Self) -> Self::Output {
Coordinate {
lon: self.lon + rhs.lon,
lat: self.lat + rhs.lat,
}
}
}
impl From<(f64, f64)> for Coordinate {
fn from((lat, lon): (f64, f64)) -> Self {
Coordinate::new(lat, lon)
}
}
impl Boundary {
pub fn inverted() -> Self {
Boundary {
min: (90.0, 180.0).into(),
max: (-90.0, -180.0).into(),
freeze: false,
}
}
pub fn expand(&mut self, c: Coordinate) {
if self.freeze {
return;
}
if c.lat > self.max.lat {
self.max.lat = c.lat;
}
if c.lat < self.min.lat {
self.min.lat = c.lat;
}
if c.lon > self.max.lon {
self.max.lon = c.lon;
}
if c.lon < self.min.lon {
self.min.lon = c.lon;
}
}
}
impl Default for Boundary {
fn default() -> Self {
Boundary {
min: (-90.0, -180.0).into(),
max: (90.0, 180.0).into(),
freeze: false,
}
}
}