use crate::{
parsers::Buffer,
tools::{ElevationConverter, convert_mapbox_elevation_data},
};
#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
pub struct IsoGrid {
pub width: usize,
pub height: usize,
pub min: f64,
pub max: f64,
pub elevations: Vec<f64>,
}
#[cfg(feature = "std")]
pub fn get_elevation_grid(
image_data: &Buffer,
elevation_converter: Option<ElevationConverter>,
tms_style: Option<bool>,
) -> IsoGrid {
use crate::parsers::{ImageData, image_decoder};
let elevation_converter = elevation_converter.unwrap_or(convert_mapbox_elevation_data);
let tms_style = tms_style.unwrap_or(false);
let Ok(ImageData { width, height, data, .. }) = image_decoder(image_data, None) else {
panic!("Failed to decode image");
};
let channels = data.len() / (width * height);
let mut min = f64::INFINITY;
let mut max = f64::NEG_INFINITY;
let mut elevations = vec![0.; width * height];
for j in 0..height {
let actual_k = if tms_style { height - j - 1 } else { j };
let row_offset = actual_k * width * channels;
let output_row_offset = actual_k * width;
for i in 0..width {
let index = row_offset + i * channels;
let alpha = if channels > 3 { data.get_u8_at(index + 3) } else { 255 };
let elevation = elevation_converter(
data.get_u8_at(index),
data.get_u8_at(index + 1),
data.get_u8_at(index + 2),
Some(alpha),
);
min = f64::min(min, elevation);
max = f64::max(max, elevation);
elevations[output_row_offset + i] = elevation;
}
}
IsoGrid { width, height, min, max, elevations }
}