use std::any::Any;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct RasterBuf {
pub width: u32,
pub height: u32,
pub pixels: Vec<u8>,
}
impl RasterBuf {
pub fn new(width: u32, height: u32) -> Self {
Self {
width,
height,
pixels: vec![0; (width * height * 4) as usize],
}
}
pub fn filled(width: u32, height: u32, rgba: [u8; 4]) -> Self {
let mut s = Self::new(width, height);
for px in s.pixels.chunks_exact_mut(4) {
px.copy_from_slice(&rgba);
}
s
}
pub fn pixel(&self, x: u32, y: u32) -> [u8; 4] {
let i = ((y * self.width + x) * 4) as usize;
[
self.pixels[i],
self.pixels[i + 1],
self.pixels[i + 2],
self.pixels[i + 3],
]
}
}
pub type OpaqueValue = Arc<dyn Any + Send + Sync>;
#[derive(Debug, Clone)]
pub struct ScalarField {
pub width: u32,
pub height: u32,
pub values: Arc<[f32]>,
pub nodata: Option<f32>,
pub geo_scale: Option<GeoScale>,
}
#[derive(Debug, Clone, Copy)]
pub struct GeoScale {
pub metres_per_pixel_x: f32,
pub metres_per_pixel_y: f32,
}
impl ScalarField {
pub fn sample(&self, x: u32, y: u32) -> f32 {
self.values[(y * self.width + x) as usize]
}
pub fn metres_per_pixel_x(&self) -> f32 {
self.geo_scale.map(|g| g.metres_per_pixel_x).unwrap_or(1.0)
}
pub fn metres_per_pixel_y(&self) -> f32 {
self.geo_scale.map(|g| g.metres_per_pixel_y).unwrap_or(1.0)
}
}