use crate::Crs;
use super::{Band, GeoTransform};
#[derive(Debug, Clone, PartialEq)]
pub struct RasterTile {
pub width: u32,
pub height: u32,
pub bands: Vec<Band>,
pub geo_transform: GeoTransform,
pub crs: Crs,
}
impl RasterTile {
pub fn byte_size(&self) -> usize {
let pixels = (self.width as usize) * (self.height as usize);
self.bands
.iter()
.map(|b| pixels * b.descriptor.dtype.size_bytes())
.sum()
}
pub fn bounds(&self) -> [f64; 4] {
self.geo_transform.world_bounds(self.width, self.height)
}
pub fn is_well_formed(&self) -> bool {
let pixels = (self.width as usize) * (self.height as usize);
self.bands.iter().all(|b| {
let bpp = b.descriptor.dtype.size_bytes();
bpp > 0 && b.data.len() == pixels * bpp
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::raster::{BandDescriptor, PixelType};
fn tile_256x256_rgb() -> RasterTile {
let make_band = |name: &str| {
Band::new(
BandDescriptor::new(Some(name.into()), PixelType::U8),
vec![0u8; 256 * 256],
)
};
RasterTile {
width: 256,
height: 256,
bands: vec![make_band("red"), make_band("green"), make_band("blue")],
geo_transform: GeoTransform::north_up(0.0, 0.0, 1.0, 1.0),
crs: Crs::Epsg(3857),
}
}
#[test]
fn byte_size_for_rgb_tile() {
let t = tile_256x256_rgb();
assert_eq!(t.byte_size(), 196_608);
}
#[test]
fn well_formed_round_trip() {
let t = tile_256x256_rgb();
assert!(t.is_well_formed());
}
#[test]
fn malformed_band_detected() {
let mut t = tile_256x256_rgb();
t.bands[0].data.truncate(100); assert!(!t.is_well_formed());
}
#[test]
fn bounds_from_geo_transform() {
let t = tile_256x256_rgb();
let b = t.bounds();
assert_eq!(b[0], 0.0);
assert_eq!(b[2], 256.0);
}
}