1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use std::fs::File;
use anyhow::Result;
use byteorder::{BigEndian, ReadBytesExt};
use geom::{Distance, LonLat};
const GRID_DIM: usize = 1201;
pub struct Elevation {
lon_offset: f64,
lat_offset: f64,
data: Vec<i16>,
}
impl Elevation {
pub fn load(path: &str) -> Result<Elevation> {
println!("Reading elevation data from {}", path);
let mut f = File::open(path)?;
let mut e = Elevation {
lon_offset: -122.0,
lat_offset: 47.0,
data: Vec::with_capacity(GRID_DIM.pow(2)),
};
for _ in 0..GRID_DIM.pow(2) {
e.data.push(f.read_i16::<BigEndian>()?);
}
Ok(e)
}
pub fn get(&self, pt: LonLat) -> Distance {
let x = ((pt.x() - self.lon_offset).abs() * (GRID_DIM as f64)) as usize;
let y = ((pt.y() - self.lat_offset).abs() * (GRID_DIM as f64)) as usize;
let i = x + (y * GRID_DIM);
if i >= self.data.len() {
panic!("srtm lookup for out-of-bounds {}", pt);
}
Distance::meters(f64::from(self.data[i]))
}
}