diff --git a/src/dem.rs b/src/dem.rs index 6e1d649..c1daa61 100644 --- a/src/dem.rs +++ b/src/dem.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use gdal::errors::GdalError; use gdal::Dataset; -use tracing::{debug, debug_span, info}; +use tracing::{debug, debug_span, error, info}; use moka::future::Cache; @@ -30,24 +30,26 @@ impl DatasetRepository { DatasetRepository { cache: c, basedir } } - async fn get(&self, filename: String) -> Arc { + async fn get(&self, filename: String) -> Option> { let full_filename = format!("{}/{filename}", self.basedir); if !self.cache.contains_key(&full_filename) { info!("Will open {full_filename} because not in cache!"); - let ds = Arc::new(MyDataset { - ds: Dataset::open(full_filename.clone()).unwrap(), - }); - self.cache.insert(full_filename.clone(), ds).await; - } - - match self.cache.get(&full_filename).await { - Some(dataset_arc) => dataset_arc, - None => panic!("foo") + let ds = Dataset::open(full_filename.clone()); + match ds { + Err(x) => { + error!("File not present"); + return None; + } + Ok(ds) => { + let mds = Arc::new(MyDataset { ds: ds }); + self.cache.insert(full_filename.clone(), mds).await; + } + } } + self.cache.get(&full_filename).await } - } impl Clone for DatasetRepository { @@ -59,15 +61,18 @@ impl Clone for DatasetRepository { } } - -pub async fn elevation_from_coordinates(dr: DatasetRepository, lat: f64, lon: f64) -> f64 { +pub async fn elevation_from_coordinates(dr: DatasetRepository, lat: f64, lon: f64) -> Option { let span = debug_span!("req", lat=%lat, lon=%lon); let _guard = span.enter(); let filename = get_filename_from_latlon(lat, lon); debug!(filename, "filename"); - let ds = &dr.get(filename).await.ds; + + let ds = &match dr.get(filename).await { + Some(x) => x, + None => return None, + }.ds; let (px, py) = geo_to_pixel(ds, lat, lon).unwrap(); @@ -75,7 +80,7 @@ pub async fn elevation_from_coordinates(dr: DatasetRepository, lat: f64, lon: f6 let raster_value = raster_band .read_as::((px, py), (1, 1), (1, 1), None) .unwrap(); - raster_value.data[0] + Some(raster_value.data[0]) } fn get_filename_from_latlon(lat: f64, lon: f64) -> String { diff --git a/src/main.rs b/src/main.rs index bdb0cdf..aa44642 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,24 @@ mod dem; use axum::{ - extract::{Path, State}, http::Request, routing::get, Router + extract::{Path, State}, + http::StatusCode, + response::IntoResponse, + routing::get, + Router, }; use axum_macros::debug_handler; use std::env; -use tower_http::{services::ServeDir, trace::{self, DefaultMakeSpan}}; +use tower_http::{ + services::ServeDir, + trace::{self, DefaultMakeSpan}, +}; use dem::DatasetRepository; -use tracing::{info, Level, Span}; use tower_http::trace::TraceLayer; - +use tracing::{info, Level, Span}; const DEFAULT_DATA_DIR: &str = "/data"; const DEFAULT_PORT: &str = "3000"; @@ -22,7 +28,6 @@ async fn main() { // initialize tracing tracing_subscriber::fmt::init(); - let config = load_config().unwrap(); let cache = DatasetRepository::new(config.basedir); @@ -32,7 +37,7 @@ async fn main() { .route("/elevation/:lat/:lon", get(get_elevation)) .nest_service("/", serve_dir) .with_state(cache) - .layer( + .layer( TraceLayer::new_for_http() .make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO)) .on_response(trace::DefaultOnResponse::new().level(Level::INFO)), @@ -46,13 +51,17 @@ async fn main() { } #[debug_handler] -async fn get_elevation(State(dsr): State, Path((lat, lon)): Path<(f64, f64)>) -> String { +async fn get_elevation( + State(dsr): State, + Path((lat, lon)): Path<(f64, f64)>, +) -> impl IntoResponse { let ele = dem::elevation_from_coordinates(dsr, lat, lon); - let myele = ele.await; - format!("{myele}") + match ele.await { + Some(ele) => (StatusCode::OK, format!("{ele}")), + None => (StatusCode::NOT_IMPLEMENTED, "".to_string()), + } } - fn load_config() -> Result { Ok(Config { basedir: env::var("DEM_LOCATION").unwrap_or_else(|_| DEFAULT_DATA_DIR.to_string()),