rusterize/encoding/
arrays.rs1use crate::{
2 geo::raster::RasterInfo,
3 prelude::{RasterDtype, RasterizeContext},
4 rasterization::pixel_functions::PixelFn,
5};
6use ndarray::Array3;
7use num_traits::Num;
8use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, IntoParallelRefIterator, ParallelIterator};
9
10pub struct DenseArray<N> {
12 array: Array3<N>,
13 band_names: Vec<String>,
14 raster_info: RasterInfo,
15}
16
17impl<N: Num> DenseArray<N> {
18 pub(crate) fn new(array: Array3<N>, band_names: Vec<String>, raster_info: RasterInfo) -> Self {
19 Self {
20 array,
21 band_names,
22 raster_info,
23 }
24 }
25
26 pub fn into_parts(self) -> (Array3<N>, Vec<String>, RasterInfo) {
28 (self.array, self.band_names, self.raster_info)
29 }
30
31 pub fn array(&self) -> &Array3<N> {
33 &self.array
34 }
35
36 pub fn band_names(&self) -> &[String] {
38 &self.band_names
39 }
40
41 pub fn raster_info(&self) -> &RasterInfo {
43 &self.raster_info
44 }
45}
46
47struct Triplets<N> {
50 rows: Vec<u64>,
51 cols: Vec<u64>,
52 data: Vec<N>,
53}
54
55impl<N: Num> Triplets<N> {
56 fn new(rows: Vec<u64>, cols: Vec<u64>, data: Vec<N>) -> Self {
57 Self { rows, cols, data }
58 }
59}
60
61pub struct SparseArray<N> {
64 band_names: Vec<String>,
65 triplets: Triplets<N>,
66 offsets: Vec<usize>,
67 raster_info: RasterInfo,
68 pxfn: PixelFn<N>,
69 background: N,
70}
71
72impl<N> SparseArray<N>
73where
74 N: RasterDtype,
75{
76 pub(crate) fn new(
77 band_names: Vec<String>,
78 rows: Vec<u64>,
79 cols: Vec<u64>,
80 data: Vec<N>,
81 offsets: Vec<usize>,
82 ctx: RasterizeContext<N>,
83 ) -> Self {
84 let pxfn = ctx.pixel_fn();
85 let background = ctx.background;
86
87 Self {
88 band_names,
89 triplets: Triplets::new(rows, cols, data),
90 offsets,
91 raster_info: ctx.raster_info,
92 pxfn,
93 background,
94 }
95 }
96
97 pub fn band_names(&self) -> &[String] {
99 &self.band_names
100 }
101
102 pub fn build_array(&self) -> Array3<N> {
104 let mut raster = self.raster_info.build_raster(self.band_names.len(), self.background);
105
106 let rows = self.triplets.rows.as_slice();
107 let cols = self.triplets.cols.as_slice();
108 let data = self.triplets.data.as_slice();
109
110 let offsets = self
112 .offsets
113 .iter()
114 .scan(0, |state, &n| {
115 let start = *state;
116 *state += n;
117 Some(start)
118 })
119 .collect::<Vec<usize>>();
120
121 raster
122 .outer_iter_mut()
123 .into_par_iter()
124 .zip(self.offsets.par_iter())
125 .zip(offsets.par_iter())
126 .for_each(|((mut band, n), &off)| {
127 let end = off + *n;
128 let band_rows = &rows[off..end];
129 let band_cols = &cols[off..end];
130 let band_data = &data[off..end];
131
132 for ((band_row, band_col), band_value) in band_rows.iter().zip(band_cols).zip(band_data) {
133 (self.pxfn)(
134 &mut band,
135 *band_row as usize,
136 *band_col as usize,
137 *band_value,
138 self.background,
139 );
140 }
141 });
142 raster
143 }
144
145 pub fn extent(&self) -> (f64, f64, f64, f64) {
146 (
147 self.raster_info.xmin,
148 self.raster_info.ymin,
149 self.raster_info.xmax,
150 self.raster_info.ymax,
151 )
152 }
153
154 pub fn shape(&self) -> (usize, usize, usize) {
155 (self.band_names.len(), self.raster_info.nrows, self.raster_info.ncols)
156 }
157
158 pub fn resolution(&self) -> (f64, f64) {
159 (self.raster_info.xres, self.raster_info.yres)
160 }
161
162 pub fn raster_info(&self) -> &RasterInfo {
164 &self.raster_info
165 }
166
167 pub fn epsg(&self) -> Option<u16> {
168 self.raster_info.epsg
169 }
170}
171
172#[cfg(feature = "polars")]
173mod feature_gated {
174 use super::SparseArray;
175 use crate::prelude::PolarsHandler;
176 use num_traits::Num;
177 use polars::prelude::*;
178
179 impl<N> SparseArray<N>
180 where
181 N: Num + Copy + PolarsHandler,
182 {
183 pub fn to_frame(&self) -> DataFrame {
185 let mut columns: Vec<Column> = Vec::new();
186
187 if self.offsets.len() > 1 {
189 let bands = self
190 .offsets
191 .iter()
192 .enumerate()
193 .flat_map(|(i, v)| std::iter::repeat_n(i + 1, *v))
194 .map(|b| b as u64)
195 .collect::<Vec<u64>>();
196 let bands_column = Column::new("band".into(), bands);
197 columns.push(bands_column);
198 }
199
200 columns.push(Column::new("row".into(), self.triplets.rows.as_slice()));
201 columns.push(Column::new("col".into(), self.triplets.cols.as_slice()));
202
203 let height = self.triplets.data.len();
204 columns.push(N::from_named_vec("values", &self.triplets.data));
205
206 DataFrame::new(height, columns).unwrap()
207 }
208 }
209}