use std::io::{Read, Write};
use dirs;
use netcdf;
type Error = Box<dyn std::error::Error>;
use std::path::PathBuf;
fn data_dir() -> Result<PathBuf, Error> {
let mut path = dirs::cache_dir().unwrap();
path.push("oceansdb");
std::fs::create_dir_all(&path)?;
Ok(path)
}
fn etopo() -> Result<String, Error> {
let url = "https://pae-paha.pacioos.hawaii.edu/thredds/ncss/etopo5?var=ROSE&disableLLSubset=on&disableProjSubset=on&horizStride=1";
let mut p = data_dir().unwrap();
p.push("etopo5.nc");
if !p.exists() {
download(url, p.to_str().unwrap()).unwrap();
}
Ok(p.to_str().unwrap().to_string())
}
fn download(url: &str, filename: &str) -> Result<usize, Error> {
let mut fp = std::io::BufWriter::new(
std::fs::OpenOptions::new()
.create(true)
.write(true)
.open(filename)?,
);
let mut res = ureq::get(url).call()?.into_reader().take(500_000_000);
let mut buffer = vec![];
res.read_to_end(&mut buffer)?;
let s = fp.write(buffer.as_slice())?;
dbg!(s);
Ok(s)
}
pub struct Etopo5 {}
impl Etopo5 {
pub fn new() -> Self {
Self {}
}
pub fn depth(&self, lat: f32, lon: f32) -> f32 {
let filename = etopo().unwrap();
let file = netcdf::open(filename).unwrap();
let var_lat = &file.variable("ETOPO05_Y").unwrap();
let lat_data = var_lat.values_arr::<f64, _>(..).unwrap();
dbg!(&lat_data);
let var_lon = &file.variable("ETOPO05_X").unwrap();
let lon_data = var_lon.values_arr::<f64, _>(..).unwrap();
dbg!(&lon_data);
let dx = lon_data.map(|x| (x - lon as f64).abs());
let mut i = 0;
for (n, &value) in dx.iter().enumerate() {
if value < dx[i] {
i = n;
}
}
let dy = lat_data.map(|y| (y - lat as f64).abs());
let mut j = 0;
for (n, &value) in dy.iter().enumerate() {
if value < dy[j] {
j = n;
}
}
let depth = &file
.variable("ROSE")
.unwrap()
.value::<f32, _>([j, i])
.unwrap();
dbg!(&depth);
*depth
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn download_etopo() {
let filename = etopo().unwrap();
assert!(PathBuf::from(filename).exists());
}
#[test]
fn bathymetry() {
let etopo = Etopo5::new();
let depth = etopo.depth(15.0, 360.0 - 38.0);
assert_eq!(depth, -5017.0);
}
}