eorst/
types.rs

1//! Geospatial and array shape types.
2//!
3//! This module contains all the fundamental data structures for describing
4//! raster dimensions, coordinates, geotransforms, and block configurations.
5
6use clap::ValueEnum;
7use serde::{Deserialize, Serialize};
8
9/// Shape of a 4D raster array (times, layers, rows, cols).
10#[derive(PartialEq, Debug, Clone, Copy)]
11pub struct RasterDataShape {
12    /// Number of time steps.
13    pub times: usize,
14    /// Number of layers/bands.
15    pub layers: usize,
16    /// Number of rows.
17    pub rows: usize,
18    /// Number of columns.
19    pub cols: usize,
20}
21
22/// Dimension along which to stack or layer data.
23#[derive(Debug, std::cmp::PartialEq, Clone, Copy, Default)]
24pub enum Dimension {
25    /// Stack along the layer dimension.
26    #[default]
27    Layer,
28    /// Stack along the time dimension.
29    Time,
30}
31
32/// Image resolution (pixel size in georeferenced units).
33#[derive(Debug, Default, PartialEq, Clone, Copy)]
34pub struct ImageResolution {
35    /// X resolution (pixel width).
36    pub x: f64,
37    /// Y resolution (pixel height, typically negative for north-up).
38    pub y: f64,
39}
40
41/// Image dimensions in pixels.
42#[derive(Default, Debug, PartialEq, Clone, Copy)]
43pub struct ImageSize {
44    /// Number of rows (height).
45    pub rows: usize,
46    /// Number of columns (width).
47    pub cols: usize,
48}
49
50/// Offset in array coordinates.
51#[derive(PartialEq, Debug, Clone, Copy)]
52pub struct Offset {
53    /// Row offset.
54    pub rows: isize,
55    /// Column offset.
56    pub cols: isize,
57}
58
59/// Size in array coordinates.
60#[derive(PartialEq, Debug, Clone, Copy)]
61pub struct Size {
62    /// Number of rows.
63    pub rows: isize,
64    /// Number of columns.
65    pub cols: isize,
66}
67
68/// Block size for chunked raster operations.
69#[derive(Debug, PartialEq, Clone, Copy)]
70pub struct BlockSize {
71    /// Number of rows per block.
72    pub rows: usize,
73    /// Number of columns per block.
74    pub cols: usize,
75}
76
77impl Default for BlockSize {
78    fn default() -> Self {
79        BlockSize {
80            rows: 1024,
81            cols: 1024,
82        }
83    }
84}
85
86/// Geotransform parameters defining the affine transformation from pixel to georeferenced coordinates.
87#[derive(Default, Debug, PartialEq, Clone, Copy)]
88pub struct GeoTransform {
89    /// X coordinate of the upper-left pixel center.
90    pub x_ul: f64,
91    /// X resolution (pixel width).
92    pub x_res: f64,
93    /// X rotation (typically 0).
94    pub x_rot: f64,
95    /// Y coordinate of the upper-left pixel center.
96    pub y_ul: f64,
97    /// Y rotation (typically 0).
98    pub y_rot: f64,
99    /// Y resolution (pixel height, typically negative).
100    pub y_res: f64,
101}
102
103impl GeoTransform {
104    /// Converts the GeoTransform to a 6-element array.
105    /// Array format: [x_ul, x_res, x_rot, y_ul, y_rot, y_res].
106    pub fn to_array(&self) -> [f64; 6] {
107        let array: [f64; 6] = [
108            self.x_ul, self.x_res, self.x_rot, self.y_ul, self.y_rot, self.y_res,
109        ];
110        array
111    }
112}
113
114/// Window for reading raster data.
115#[derive(PartialEq, Debug, Clone, Copy)]
116pub struct ReadWindow {
117    /// Offset from which to start reading.
118    pub offset: Offset,
119    /// Size of the window to read.
120    pub size: Size,
121}
122
123/// Overlap size for block-based operations (padding around each block).
124#[derive(Debug, PartialEq, Clone, Copy, Default)]
125pub struct Overlap {
126    /// Number of pixels to pad on the left side.
127    pub left: usize,
128    /// Number of pixels to pad on the top side.
129    pub top: usize,
130    /// Number of pixels to pad on the right side.
131    pub right: usize,
132    /// Number of pixels to pad on the bottom side.
133    pub bottom: usize,
134}
135
136/// Sampling method for aggregating raster values.
137#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, ValueEnum)]
138pub enum SamplingMethod {
139    /// Use the actual value.
140    Value,
141    /// Use the most common value (mode).
142    Mode,
143    /// Use the minimum value.
144    Min,
145    /// Use the standard deviation.
146    StdDev,
147    /// Use the average value.
148    Avg,
149}
150
151/// 2D index into an array (column, row).
152#[derive(Debug, Copy, Clone, PartialEq)]
153pub struct Index2d {
154    /// Column index.
155    pub col: usize,
156    /// Row index.
157    pub row: usize,
158}
159
160/// x and y coordinates of a location.
161#[derive(Default, Debug, PartialEq, Clone, Copy)]
162pub struct Coordinates {
163    pub(crate) x: f64,
164    pub(crate) y: f64,
165}
166
167/// Rectangle for array indexing (distances from a center point).
168#[derive(Debug, Copy, Clone)]
169pub struct Rectangle {
170    /// Number of columns to the left of the center.
171    pub left: usize,
172    /// Number of rows above the center.
173    pub top: usize,
174    /// Number of columns to the right of the center.
175    pub right: usize,
176    /// Number of rows below the center.
177    pub bottom: usize,
178}
179
180/// Coordinate value type for spatial coordinates.
181#[derive(Debug, PartialEq)]
182pub enum CoordType {
183    /// Integer coordinate value.
184    EInt(i64),
185    /// Floating-point coordinate value.
186    EFloat(f32),
187    /// String coordinate value.
188    EString(String),
189}
190
191/// Output format for raster write operations.
192#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, strum::EnumString)]
193#[strum(ascii_case_insensitive)]
194pub enum OutputFormat {
195    /// Simple tiled GeoTIFF (fast, single-pass, no overviews).
196    #[default]
197    #[strum(serialize = "geotiff")]
198    GeoTiff,
199    /// Tiled GeoTIFF with overviews built in-place after writing.
200    #[strum(serialize = "geotiff-overviews", serialize = "geotiff_overviews")]
201    GeoTiffOverviews,
202    /// Cloud Optimized GeoTIFF (overviews + IFD reordering via gdal_translate).
203    #[strum(serialize = "cog")]
204    COG,
205}
206
207/// Configuration for output file generation.
208#[derive(Debug, Clone)]
209pub struct OutputConfig {
210    /// Output format controlling overviews and COG compliance.
211    pub format: OutputFormat,
212    /// Compression for the final output (e.g., "LZW", "DEFLATE", "ZSTD").
213    pub compression: String,
214    /// Resampling method for overviews (e.g., "CUBIC", "NEAREST", "AVERAGE").
215    pub overview_resampling: String,
216    /// Overview decimation levels (e.g., \[2, 4, 8, 16, 32\]).
217    pub overview_levels: Vec<i32>,
218}
219
220impl Default for OutputConfig {
221    fn default() -> Self {
222        Self {
223            format: OutputFormat::GeoTiff,
224            compression: "LZW".to_string(),
225            overview_resampling: "CUBIC".to_string(),
226            overview_levels: vec![2, 4, 8, 16, 32],
227        }
228    }
229}