eorst/rasterdataset/
io.rs

1//! I/O methods for RasterDataset.
2//!
3//! This module contains methods for reading blocks and writing windows.
4
5use crate::core_types::{RasterData, RasterType};
6use crate::types::BlockSize;
7use crate::rasterdataset::RasterDataset;
8use crate::gdal_utils::{open_for_update, read_raster_band, raster_from_size, write_bands_to_file};
9
10use ndarray::{s, Array3};
11
12impl<R> RasterDataset<R>
13where
14    R: RasterType,
15{
16    /// Writes a 3D array to a window in the output file.
17    #[doc(hidden)]
18    pub fn write_window3<T>(
19        &self,
20        block_index: usize,
21        data: Array3<T>,
22        out_fn: &std::path::PathBuf,
23        na_value: T,
24    ) where
25        T: RasterType,
26    {
27        let trimmed = crate::array_ops::trimm_array3(&data, self.blocks[block_index].overlap_size);
28
29        let block_geotransform = self.blocks[block_index].geo_transform;
30        let block_size: BlockSize = BlockSize {
31            rows: trimmed.shape()[1],
32            cols: trimmed.shape()[2],
33        };
34        let n_bands = data.shape()[0] as isize;
35        let epsg_code = self.metadata.epsg_code;
36        let na_value = T::from(na_value).unwrap();
37        raster_from_size::<T>(
38            out_fn,
39            block_geotransform,
40            epsg_code,
41            block_size,
42            n_bands,
43            na_value,
44        );
45        let out_ds = open_for_update(out_fn);
46        write_bands_to_file(&out_ds, trimmed, (0, 0), (block_size.cols, block_size.rows));
47    }
48
49    /// Reads a block of raster data.
50    #[doc(hidden)]
51    pub fn read_block<T>(&self, block_id: usize) -> RasterData<T>
52    where
53        T: RasterType,
54    {
55        let block = &self.blocks[block_id];
56        let read_window = block.read_window;
57
58        let rows = read_window.size.rows as usize;
59        let cols = read_window.size.cols as usize;
60        let data_shape = (
61            self.metadata.shape.times,
62            self.metadata.shape.layers,
63            rows,
64            cols,
65        );
66
67        let mut data: RasterData<T> = RasterData::zeros(data_shape);
68
69        for layer in &self.metadata.layers {
70            let raster_path = std::path::Path::new(&layer.source);
71            let window = (read_window.offset.cols, read_window.offset.rows);
72            let window_size = (cols, rows);
73
74            let layer_data = read_raster_band::<T>(raster_path, 1, window, window_size);
75
76            let slice = s![
77                layer.time_pos,
78                layer.layer_pos,
79                ..,
80                ..
81            ];
82
83            data.slice_mut(slice).assign(&layer_data);
84        }
85        data
86    }
87
88    /// Reads a specific layer from a block.
89    #[doc(hidden)]
90    pub fn read_block_layer_idx<T>(&self, block_id: usize, layer_idx: usize) -> RasterData<T>
91    where
92        T: RasterType,
93    {
94        let block = &self.blocks[block_id];
95        let read_window = block.read_window;
96
97        let rows = read_window.size.rows as usize;
98        let cols = read_window.size.cols as usize;
99        let data_shape = (
100            self.metadata.shape.times,
101            self.metadata.shape.layers,
102            rows,
103            cols,
104        );
105
106        let mut data: RasterData<T> = RasterData::zeros(data_shape);
107
108        let layer = &self.metadata.layers[layer_idx];
109        let raster_path = std::path::Path::new(&layer.source);
110        let window = (read_window.offset.cols, read_window.offset.rows);
111        let window_size = (cols, rows);
112
113        let layer_data = read_raster_band::<T>(raster_path, 1, window, window_size);
114
115        let slice = s![
116            layer.time_pos,
117            layer.layer_pos,
118            ..,
119            ..
120        ];
121
122        data.slice_mut(slice).assign(&layer_data);
123
124        data
125    }
126}