Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion datatypes/src/primitives/query_rectangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ impl BandSelection {
pub fn is_single(&self) -> bool {
self.count() == 1
}

pub fn contains(&self, band: u32) -> bool {
self.0.contains(&band)
}

pub fn contains_all(&self, bands: &[u32]) -> bool {
bands.iter().all(|band| self.contains(*band))
}
}

impl From<u32> for BandSelection {
Expand All @@ -184,6 +192,12 @@ impl From<u32> for BandSelection {
}
}

impl AsRef<[u32]> for BandSelection {
fn as_ref(&self) -> &[u32] {
self.as_slice()
}
}

impl TryFrom<Vec<u32>> for BandSelection {
type Error = crate::error::Error;

Expand All @@ -204,7 +218,7 @@ impl QueryAttributeSelection for BandSelection {}

#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct BandSelectionIter {
band_selection: BandSelection,
pub band_selection: BandSelection,
next_index: usize,
}

Expand Down
4 changes: 4 additions & 0 deletions datatypes/src/raster/grid_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,10 @@ impl GridIdx2DIter {
self.x_pos = self.grid_bounds.x_min();
self.y_pos = self.grid_bounds.y_min();
}

pub fn next_is_min_index(&self) -> bool {
self.grid_bounds.min_index() == GridIdx::new_y_x(self.y_pos, self.x_pos)
}
}

impl Iterator for GridIdx2DIter {
Expand Down
2 changes: 2 additions & 0 deletions datatypes/src/raster/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub use raster_properties::{
RasterProperties, RasterPropertiesEntry, RasterPropertiesEntryType, RasterPropertiesKey,
};
pub use raster_traits::{CoordinatePixelAccess, GeoTransformAccess, Raster};
pub use util::{TileIdxBandCrossProductIter, TileInformationBandCrossProductIter};

mod arrow_conversion;
mod band_names;
Expand All @@ -79,3 +80,4 @@ mod raster_traits;
mod tiling;
mod typed_raster_conversion;
mod typed_raster_tile;
mod util;
121 changes: 121 additions & 0 deletions datatypes/src/raster/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use crate::{
primitives::{BandSelection, BandSelectionIter},
raster::{GridBoundingBox2D, GridIdx2D, GridIdx2DIter, TileInformation, TileInformationIter},
};

#[derive(Clone, Debug)]
pub struct TileIdxBandCrossProductIter {
tile_iter: GridIdx2DIter,
band_iter: BandSelectionIter, // TODO: maybe change this to actual attributes from ResultDescriptor not the Selection?
current_tile: Option<GridIdx2D>,
}

impl TileIdxBandCrossProductIter {
pub fn new(tile_iter: GridIdx2DIter, band_iter: BandSelectionIter) -> Self {
let mut tile_iter = tile_iter;
let current_tile = tile_iter.next();
Self {
tile_iter,
band_iter,
current_tile,
}
}

pub fn grid_bounds(&self) -> GridBoundingBox2D {
self.tile_iter.grid_bounds
}

pub fn band_selection(&self) -> &BandSelection {
&self.band_iter.band_selection
}

pub fn with_grid_bounds_and_selection(
bounds: GridBoundingBox2D,
band_selection: BandSelection,
) -> Self {
let tile_iter = GridIdx2DIter::new(&bounds);
let band_iter = BandSelectionIter::new(band_selection);
Self::new(tile_iter, band_iter)
}

pub fn reset(&mut self) {
self.band_iter.reset();
self.tile_iter.reset();
self.current_tile = self.tile_iter.next();
}
}

impl Iterator for TileIdxBandCrossProductIter {
type Item = (GridIdx2D, u32);

fn next(&mut self) -> Option<Self::Item> {
let current_t = self.current_tile;

match (current_t, self.band_iter.next()) {
(None, _) => None,
(Some(t), Some(b)) => Some((t, b)),
(Some(_t), None) => {
self.band_iter.reset();
self.current_tile = self.tile_iter.next();
self.current_tile.map(|t| {
(
t,
self.band_iter
.next()
.expect("There must be at least one band"),
)
})
}
}
}
}

#[derive(Clone, Debug)]
pub struct TileInformationBandCrossProductIter {
tile_iter: TileInformationIter,
band_iter: BandSelectionIter,
current_tile: Option<TileInformation>,
}

impl TileInformationBandCrossProductIter {
pub fn new(tile_iter: TileInformationIter, band_iter: BandSelectionIter) -> Self {
let mut tile_iter = tile_iter;
let current_tile = tile_iter.next();
Self {
tile_iter,
band_iter,
current_tile,
}
}

pub fn reset(&mut self) {
self.band_iter.reset();
self.tile_iter.reset();
self.current_tile = self.tile_iter.next();
}
}

impl Iterator for TileInformationBandCrossProductIter {
type Item = (TileInformation, u32);

fn next(&mut self) -> Option<Self::Item> {
let current_t = self.current_tile;

match (current_t, self.band_iter.next()) {
(None, _) => None,
(Some(t), Some(b)) => Some((t, b)),
(Some(_t), None) => {
self.band_iter.reset();
self.current_tile = self.tile_iter.next();
self.current_tile.map(|t| {
(
t,
self.band_iter
.next()
.expect("There must be at least one band"),
)
})
}
}
}
}
Loading