use crate::core_types::{RasterData, RasterType};
use crate::data_sources::DateType;
use crate::types::{BlockSize, GeoTransform, RasterDataShape};
use anyhow::Result;
use num_traits::NumCast;
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Debug, PartialEq, Clone)]
pub struct Extent {
pub xmin: f64,
pub ymin: f64,
pub xmax: f64,
pub ymax: f64,
}
impl FromStr for Extent {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split(',').collect();
if parts.len() != 4 {
return Err("Extent must be in the format xmin,ymin,xmax,ymax".to_string());
}
let xmin = parts[0].parse().map_err(|_| "Invalid xmin")?;
let ymin = parts[1].parse().map_err(|_| "Invalid ymin")?;
let xmax = parts[2].parse().map_err(|_| "Invalid xmax")?;
let ymax = parts[3].parse().map_err(|_| "Invalid ymax")?;
Ok(Extent {
xmin,
ymin,
xmax,
ymax,
})
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Layer {
pub source: PathBuf,
pub(crate) layer_pos: usize,
pub(crate) time_pos: usize,
}
impl Layer {
pub fn new(source: PathBuf, layer_pos: usize, time_pos: usize) -> Self {
Layer {
source,
layer_pos,
time_pos,
}
}
pub fn stack_position(
&mut self,
original_layer: Layer,
dimension_to_stack: crate::types::Dimension,
max_dim: usize,
) -> &mut Layer {
match dimension_to_stack {
crate::types::Dimension::Layer => self.layer_pos = original_layer.layer_pos + max_dim,
crate::types::Dimension::Time => self.time_pos = original_layer.time_pos + max_dim,
}
self
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RasterMetadata<U>
where
U: RasterType,
{
pub layers: Vec<Layer>,
pub shape: RasterDataShape,
pub(crate) block_size: BlockSize,
pub epsg_code: u32,
pub geo_transform: GeoTransform,
pub overlap_size: usize,
pub date_indices: Vec<DateType>,
pub layer_indices: Vec<String>,
pub na_value: U,
}
impl<U> Default for RasterMetadata<U>
where
U: RasterType,
{
fn default() -> Self {
Self::new()
}
}
impl<U> RasterMetadata<U>
where
U: RasterType,
{
pub fn new() -> Self {
let layers = Vec::new();
let shape = RasterDataShape {
times: 0,
layers: 0,
rows: 0,
cols: 0,
};
let block_size = BlockSize { rows: 0, cols: 0 };
let epsg_code = 4326;
let geo_transform = GeoTransform {
x_ul: 0.,
x_res: 0.,
x_rot: 0.,
y_ul: 0.,
y_rot: 0.,
y_res: 0.,
};
let overlap_size = 0;
let date_indices = Vec::new();
let layer_indices = Vec::new();
let na_value = U::zero();
RasterMetadata {
layers,
shape,
block_size,
epsg_code,
geo_transform,
overlap_size,
date_indices,
layer_indices,
na_value: NumCast::from(na_value).unwrap(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RasterDataBlock<T>
where
T: RasterType,
{
pub data: RasterData<T>,
pub metadata: RasterMetadata<T>,
pub no_data: T,
}