Skip to main content

elevation_mini/
lib.rs

1#[repr(C)]
2union BytesToI16 {
3    bytes: [u8; 4672082],
4    data: [[i16; 2161]; 1081],
5}
6
7static U: BytesToI16 = BytesToI16 {
8    bytes: *include_bytes!("data.bin"),
9};
10
11static DATA: [[i16; 2161]; 1081] = unsafe { U.data };
12
13/// Estimated elevation in meters at a given latitude and longitude. Interpolates between known points.
14pub fn elevation(lat: f64, lon: f64) -> f64 {
15    assert!(
16        (-90.0..=90.0).contains(&lat),
17        "Latitude out of bounds [-90.0, 90.0]"
18    );
19    assert!(
20        (-180.0..=180.0).contains(&lon),
21        "Longitude out of bounds [-180.0, 180.0]"
22    );
23
24    // Grid dimensions and step size
25    let lat_min = -90.0;
26    let lon_min = -180.0;
27    let lat_step = 180.0 / 1080.0; // ≈ 0.1667°
28    let lon_step = 360.0 / 2160.0;
29
30    // Position in the grid
31    let lat_pos = (lat - lat_min) / lat_step;
32    let lon_pos = (lon - lon_min) / lon_step;
33
34    let y = lat_pos.floor() as usize;
35    let x = lon_pos.floor() as usize;
36
37    let dy = lat_pos - y as f64;
38    let dx = lon_pos - x as f64;
39
40    // Clamp to avoid going out of bounds
41    let y = y.min(1079); // since we use y+1
42    let x = x.min(2159); // since we use x+1
43
44    let q11 = DATA[y][x] as f64;
45    let q12 = DATA[y][x + 1] as f64;
46    let q21 = DATA[y + 1][x] as f64;
47    let q22 = DATA[y + 1][x + 1] as f64;
48
49    // Bilinear interpolation
50    q11 * (1.0 - dx) * (1.0 - dy) + q12 * dx * (1.0 - dy) + q21 * (1.0 - dx) * dy + q22 * dx * dy
51}