use std::convert::TryFrom;
use nalgebra::{Affine2, Vector2};
use ndarray::Array2;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{cell_map::Bounds, CellMap, CellMapParams, Error, Layer};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CellMapFile<L, T>
where
L: Layer,
{
pub num_layers: usize,
pub layers: Vec<L>,
pub cell_bounds: Bounds,
pub cell_size: Vector2<f64>,
pub cell_boundary_precision: f64,
pub from_parent_angle_rad: f64,
pub from_parent_translation: Vector2<f64>,
pub from_parent_matrix: Affine2<f64>,
pub data: Vec<Array2<T>>,
}
impl<L, T> CellMapFile<L, T>
where
L: Layer,
{
pub fn into_cell_map(self) -> Result<CellMap<L, T>, Error> {
let params = CellMapParams {
cell_size: self.cell_size,
cell_bounds: self.cell_bounds,
rotation_in_parent_rad: self.from_parent_angle_rad,
position_in_parent: self.from_parent_translation,
cell_boundary_precision: self.cell_boundary_precision,
};
CellMap::new_from_data(params, self.data)
}
}
impl<L, T> CellMapFile<L, T>
where
L: Layer + Serialize,
T: Clone + Serialize,
{
pub(crate) fn new(map: &CellMap<L, T>) -> Self {
Self {
num_layers: L::NUM_LAYERS,
layers: L::all(),
cell_bounds: map.metadata.cell_bounds,
cell_size: map.metadata.cell_size,
cell_boundary_precision: map.metadata.cell_boundary_precision,
from_parent_angle_rad: map.params.rotation_in_parent_rad,
from_parent_translation: map.params.position_in_parent,
from_parent_matrix: map.metadata.to_parent.inverse(),
data: map.data.clone(),
}
}
}
impl<L, T> CellMapFile<L, T>
where
L: Layer + Serialize,
T: Serialize,
{
#[cfg(feature = "json")]
pub fn write_json<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), Error> {
let file = std::fs::OpenOptions::new()
.create(true)
.append(false)
.truncate(true)
.write(true)
.open(path)
.map_err(Error::IoError)?;
serde_json::to_writer_pretty(file, &self).map_err(Error::JsonError)?;
Ok(())
}
}
impl<L, T> CellMapFile<L, T>
where
L: Layer + DeserializeOwned,
T: DeserializeOwned,
{
#[cfg(feature = "json")]
pub fn from_json<P: AsRef<std::path::Path>>(path: P) -> Result<Self, Error> {
let file = std::fs::File::open(path).map_err(Error::IoError)?;
let map_file: CellMapFile<L, T> =
serde_json::from_reader(&file).map_err(Error::JsonError)?;
Ok(map_file)
}
}
impl<L, T> From<CellMap<L, T>> for CellMapFile<L, T>
where
L: Layer + Serialize,
T: Clone + Serialize,
{
fn from(map: CellMap<L, T>) -> Self {
Self::new(&map)
}
}
impl<L, T> TryFrom<CellMapFile<L, T>> for CellMap<L, T>
where
L: Layer,
{
type Error = Error;
fn try_from(value: CellMapFile<L, T>) -> Result<Self, Self::Error> {
value.into_cell_map()
}
}