use crate::geom::{new_point, Point, PointType};
use crate::grid::zones::ZoneType;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CellState {
Free = 0,
Banned,
}
impl fmt::Display for CellState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CellState::Free => write!(f, "free"),
CellState::Banned => write!(f, "banned"),
}
}
}
pub type CellID = i64;
#[derive(Debug, Clone)]
pub struct Cell {
id: CellID,
point: PointType,
type_zone: ZoneType,
speed_limit: i32,
left_cell: CellID,
forward_cell: CellID,
right_cell: CellID,
meso_link_id: i64,
state: CellState,
}
impl Cell {
pub fn new(id: CellID) -> CellBuilder {
CellBuilder {
cell: Cell {
id,
point: new_point(-1.0, -1.0, None),
type_zone: ZoneType::Undefined,
speed_limit: -1,
left_cell: -1,
forward_cell: -1,
right_cell: -1,
meso_link_id: -1,
state: CellState::Free,
},
}
}
pub fn distance_to(&self, other: &Cell) -> f64 {
self.point.distance_to(&other.point)
}
pub fn set_state(&mut self, new_state: CellState) {
self.state = new_state;
}
pub fn get_state(&self) -> CellState {
self.state
}
pub fn get_id(&self) -> CellID {
self.id
}
pub fn get_forward_id(&self) -> CellID {
self.forward_cell
}
pub fn set_forward_id(&mut self, id: CellID) {
self.forward_cell = id;
}
pub fn get_left_id(&self) -> CellID {
self.left_cell
}
pub fn set_left_id(&mut self, id: CellID) {
self.left_cell = id;
}
pub fn get_right_id(&self) -> CellID {
self.right_cell
}
pub fn set_right_id(&mut self, id: CellID) {
self.right_cell = id;
}
pub fn get_speed_limit(&self) -> i32 {
self.speed_limit
}
pub fn get_point(&self) -> &PointType {
&self.point
}
pub fn get_zone_type(&self) -> ZoneType {
self.type_zone
}
}
pub struct CellBuilder {
cell: Cell,
}
impl CellBuilder {
pub fn with_point(mut self, point: PointType) -> Self {
self.cell.point = point;
self
}
pub fn with_zone_type(mut self, zone_type: ZoneType) -> Self {
self.cell.type_zone = zone_type;
self
}
pub fn with_speed_limit(mut self, speed_limit: i32) -> Self {
self.cell.speed_limit = speed_limit;
self
}
pub fn with_forward_node(mut self, forward_cell: CellID) -> Self {
self.cell.forward_cell = forward_cell;
self
}
pub fn with_left_node(mut self, left_cell: CellID) -> Self {
self.cell.left_cell = left_cell;
self
}
pub fn with_right_node(mut self, right_cell: CellID) -> Self {
self.cell.right_cell = right_cell;
self
}
pub fn with_meso_link(mut self, meso_link_id: i64) -> Self {
self.cell.meso_link_id = meso_link_id;
self
}
pub fn build(self) -> Cell {
self.cell
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::geom::SRID;
#[test]
fn test_cells_gc_distance() {
let correct_distance = 634430.92026;
let cell1 = Cell::new(1)
.with_point(new_point(37.61556, 55.75222, Some(SRID::WGS84)))
.build();
let cell2 = Cell::new(2)
.with_point(new_point(30.31413, 59.93863, Some(SRID::WGS84)))
.build();
let distance = cell1.distance_to(&cell2);
assert!(
(distance - correct_distance).abs() < 0.001,
"Distance should be {}, but got {}",
correct_distance,
distance
);
}
}