pub struct ElevationProvider {
pub resolution_arcsec: f64,
data: Vec<f64>,
cols: usize,
rows: usize,
}
impl ElevationProvider {
pub fn from_heightmap(hm: &crate::terrain::heightmap::Heightmap) -> Self {
Self {
resolution_arcsec: 360.0 * 3600.0 / hm.width as f64,
data: hm.data.clone(),
cols: hm.width,
rows: hm.height,
}
}
pub fn sample(&self, lat_deg: f64, lon_deg: f64) -> f64 {
let u = ((lon_deg + 180.0) / 360.0).clamp(0.0, 1.0);
let v = ((90.0 - lat_deg) / 180.0).clamp(0.0, 1.0);
let x = u * (self.cols - 1) as f64;
let y = v * (self.rows - 1) as f64;
let ix = (x as usize).min(self.cols - 2);
let iy = (y as usize).min(self.rows - 2);
let fx = x - ix as f64;
let fy = y - iy as f64;
let v00 = self.data[iy * self.cols + ix];
let v10 = self.data[iy * self.cols + ix + 1];
let v01 = self.data[(iy + 1) * self.cols + ix];
let v11 = self.data[(iy + 1) * self.cols + ix + 1];
v00 * (1.0 - fx) * (1.0 - fy)
+ v10 * fx * (1.0 - fy)
+ v01 * (1.0 - fx) * fy
+ v11 * fx * fy
}
}
pub struct NotableElevation {
pub name: &'static str,
pub elevation_m: f64,
pub lat_deg: f64,
pub lon_deg: f64,
}
pub fn notable_elevations() -> Vec<NotableElevation> {
vec![
NotableElevation {
name: "Olympus Mons summit",
elevation_m: 21_900.0,
lat_deg: 18.65,
lon_deg: -133.8,
},
NotableElevation {
name: "Hellas Planitia floor",
elevation_m: -7_152.0,
lat_deg: -42.7,
lon_deg: 70.0,
},
NotableElevation {
name: "Ascraeus Mons summit",
elevation_m: 18_200.0,
lat_deg: 11.92,
lon_deg: -104.87,
},
NotableElevation {
name: "Valles Marineris floor",
elevation_m: -7_000.0,
lat_deg: -14.0,
lon_deg: -59.0,
},
NotableElevation {
name: "Isidis Planitia floor",
elevation_m: -3_800.0,
lat_deg: 12.9,
lon_deg: 87.0,
},
NotableElevation {
name: "Argyre basin floor",
elevation_m: -5_200.0,
lat_deg: -49.7,
lon_deg: -43.0,
},
NotableElevation {
name: "Tharsis plateau",
elevation_m: 10_000.0,
lat_deg: 0.0,
lon_deg: -110.0,
},
]
}