use chrono::{DateTime, FixedOffset};
use gdal::Dataset;
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DateType {
Date(DateTime<FixedOffset>),
Index(usize),
}
#[derive(Debug, PartialEq, Clone)]
pub struct DataSource {
pub source: PathBuf,
pub bands: Vec<usize>,
pub layer_names: Vec<String>,
}
pub struct DataSourceBuilder {
pub source: PathBuf,
pub bands: Vec<usize>,
pub layer_names: Vec<String>,
pub date_indices: Vec<DateType>,
}
impl DataSourceBuilder {
pub fn from_file(file_name: &PathBuf) -> Self {
let source = file_name;
let n_bands = DataSourceBuilder::get_n_bands(file_name);
let bands: Vec<usize> = (1..n_bands + 1).collect();
let layer_names = (0..n_bands)
.map(|layer_index| format!("layer_{:?}", layer_index))
.collect::<Vec<String>>();
let date_indices = vec![DateType::Index(0)];
DataSourceBuilder {
source: source.clone(),
bands,
layer_names,
date_indices,
}
}
pub fn band_dimension(self, dimension: crate::types::Dimension) -> Self {
let n_bands = DataSourceBuilder::get_n_bands(&self.source);
let layer_names = match dimension {
crate::types::Dimension::Layer => self.layer_names,
crate::types::Dimension::Time => vec!["Layer_0".to_string()],
};
let date_indices = match dimension {
crate::types::Dimension::Layer => self.date_indices,
crate::types::Dimension::Time => {
(0..n_bands).map(DateType::Index).collect::<Vec<DateType>>()
}
};
DataSourceBuilder {
source: self.source.clone(),
bands: self.bands,
layer_names,
date_indices,
}
}
pub fn set_dates(self, dates: Vec<DateType>) -> Self {
let n_dates = self.date_indices.len();
let n_dates_new = dates.len();
assert_eq!(n_dates, n_dates_new);
DataSourceBuilder {
source: self.source.clone(),
bands: self.bands,
layer_names: self.layer_names,
date_indices: dates,
}
}
pub fn set_names(self, names: Vec<&str>) -> Self {
let n_names = self.layer_names.len();
let n_names_new = names.len();
assert_eq!(n_names, n_names_new);
DataSourceBuilder {
source: self.source.clone(),
bands: self.bands,
layer_names: names.iter().map(|n| n.to_string()).collect(),
date_indices: self.date_indices,
}
}
pub fn build(self) -> DataSource {
DataSource {
source: self.source,
bands: self.bands,
layer_names: self.layer_names,
}
}
pub fn bands(mut self, bands: Vec<usize>) -> Self {
self.bands = bands.clone();
self.layer_names = bands
.iter()
.enumerate()
.map(|(i, _)| format!("layer_{}", i))
.collect();
self
}
fn get_n_bands(source: &PathBuf) -> usize {
let ds = Dataset::open(source).unwrap();
ds.raster_count()
}
}