h3ron_polars/algorithm/chunkedarray/
resolution.rs1use crate::algorithm::chunkedarray::util::list_map_cells;
2use crate::{Error, FromIndexIterator, IndexChunked, IndexValue};
3use h3ron::error::check_valid_h3_resolution;
4use h3ron::iter::change_resolution;
5use h3ron::H3Cell;
6use polars_core::prelude::{ListChunked, UInt64Chunked, UInt8Chunked};
7use std::iter::once;
8
9pub trait H3Resolution {
12 fn h3_resolution(&self) -> UInt8Chunked;
15}
16
17impl<'a, IX: IndexValue> H3Resolution for IndexChunked<'a, IX> {
18 fn h3_resolution(&self) -> UInt8Chunked {
19 UInt8Chunked::from_iter(self.iter_indexes_validated().map(
20 |maybe_index| match maybe_index {
21 Some(Ok(index)) => Some(index.resolution()),
22 _ => None,
23 },
24 ))
25 }
26}
27
28pub trait H3ChangeResolution {
30 fn h3_change_resolution(&self, target_resolution: u8) -> Result<ListChunked, Error>;
36}
37
38impl<'a> H3ChangeResolution for IndexChunked<'a, H3Cell> {
39 fn h3_change_resolution(&self, target_resolution: u8) -> Result<ListChunked, Error> {
40 check_valid_h3_resolution(target_resolution)?;
41 list_map_cells(self, |cell| {
42 Ok(UInt64Chunked::from_index_iter(
43 change_resolution(once(cell), target_resolution)
44 .filter_map(|cell| cell.ok()),
46 ))
47 })
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use crate::algorithm::{H3ChangeResolution, H3Resolution};
54 use crate::{AsH3CellChunked, FromIndexIterator, NamedFromIndexes};
55 use h3ron::{H3Cell, Index};
56 use polars_core::prelude::{ChunkExplode, TakeRandom, UInt64Chunked};
57
58 #[test]
59 fn cell_resolution() {
60 let expected_res = 6;
61 let cell = H3Cell::from_coordinate((4.5, 1.3).into(), expected_res).unwrap();
62 let ca = UInt64Chunked::from_index_iter([
63 Some(cell),
64 Some(H3Cell::new(55)), None,
66 ]);
67 assert_eq!(ca.len(), 3);
68 let resolution_ca = ca.h3cell().h3_resolution();
69
70 assert_eq!(resolution_ca.get(0), Some(expected_res));
71 assert_eq!(resolution_ca.get(1), None);
72 assert_eq!(resolution_ca.get(2), None);
73 }
74
75 #[test]
76 fn cell_change_resolution_to_child() {
77 let cell = H3Cell::from_coordinate((4.5, 1.3).into(), 6).unwrap();
78 let ca = UInt64Chunked::new_from_indexes("", vec![cell]);
79 assert_eq!(ca.len(), 1);
80
81 let changed = ca.h3cell().h3_change_resolution(7).unwrap();
82 assert_eq!(changed.len(), 1);
83 let exploded = changed.explode().unwrap().unique().unwrap();
84 assert_eq!(exploded.len(), 7);
85 }
86}