use std::ops::Range; use geo_types::LineString; use crate::coords::Mapper; #[derive(Debug)] pub struct CMS { mapper: Mapper, window_size: (f32, f32), bounds: (f64, f64, f64, f64), } unsafe impl Send for CMS {} unsafe impl Sync for CMS {} impl CMS { pub fn new(mapper: Mapper, window_size: (f32, f32)) -> Self { let bounds = mapper.get_bounds(); Self { mapper, window_size, bounds, } } pub fn set_lat_range(&mut self, lat_range: Range) { self.mapper.set_lat_range(lat_range); self.bounds = self.mapper.get_bounds() } pub fn set_lon_range(&mut self, lon_range: Range) { self.mapper.set_lon_range(lon_range); self.bounds = self.mapper.get_bounds(); } pub fn map(&self, loc: (f64, f64)) -> Option<(f32, f32)> { self.mapper.map(loc).ok().map(|(x, y)| { // println!("x: {}, y: {}", x, y); let (w, h) = self.window_size; let (w, h) = (w as f64, h as f64); let (x, y) = (x - self.bounds.0, y - self.bounds.2); let (x, y) = ( x / (self.bounds.1 - self.bounds.0), 1.0 - y / (self.bounds.3 - self.bounds.2), ); let (x, y) = (x * w, y * h); (x as f32, y as f32) }) } pub fn ring_map(&self, line: &LineString) -> Option> { Some( line.points() .into_iter() .map(|p| self.map((p.x(), p.y())).unwrap()) .collect::>() .into(), ) } }