smore shit

Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
This commit is contained in:
Frank Villaro-Dixon 2024-04-16 00:22:06 +02:00
parent e4657c87e6
commit 1c448a240d
2 changed files with 40 additions and 26 deletions

View file

@ -3,7 +3,7 @@ use std::sync::Arc;
use gdal::errors::GdalError; use gdal::errors::GdalError;
use gdal::Dataset; use gdal::Dataset;
use tracing::{debug, debug_span, info}; use tracing::{debug, debug_span, error, info};
use moka::future::Cache; use moka::future::Cache;
@ -30,24 +30,26 @@ impl DatasetRepository {
DatasetRepository { cache: c, basedir } DatasetRepository { cache: c, basedir }
} }
async fn get(&self, filename: String) -> Arc<MyDataset> { async fn get(&self, filename: String) -> Option<Arc<MyDataset>> {
let full_filename = format!("{}/{filename}", self.basedir); let full_filename = format!("{}/{filename}", self.basedir);
if !self.cache.contains_key(&full_filename) { if !self.cache.contains_key(&full_filename) {
info!("Will open {full_filename} because not in cache!"); info!("Will open {full_filename} because not in cache!");
let ds = Arc::new(MyDataset { let ds = Dataset::open(full_filename.clone());
ds: Dataset::open(full_filename.clone()).unwrap(), match ds {
}); Err(x) => {
self.cache.insert(full_filename.clone(), ds).await; error!("File not present");
} return None;
}
match self.cache.get(&full_filename).await { Ok(ds) => {
Some(dataset_arc) => dataset_arc, let mds = Arc::new(MyDataset { ds: ds });
None => panic!("foo") self.cache.insert(full_filename.clone(), mds).await;
}
}
} }
self.cache.get(&full_filename).await
} }
} }
impl Clone for DatasetRepository { impl Clone for DatasetRepository {
@ -59,15 +61,18 @@ impl Clone for DatasetRepository {
} }
} }
pub async fn elevation_from_coordinates(dr: DatasetRepository, lat: f64, lon: f64) -> Option<f64> {
pub async fn elevation_from_coordinates(dr: DatasetRepository, lat: f64, lon: f64) -> f64 {
let span = debug_span!("req", lat=%lat, lon=%lon); let span = debug_span!("req", lat=%lat, lon=%lon);
let _guard = span.enter(); let _guard = span.enter();
let filename = get_filename_from_latlon(lat, lon); let filename = get_filename_from_latlon(lat, lon);
debug!(filename, "filename"); 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(); 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 let raster_value = raster_band
.read_as::<f64>((px, py), (1, 1), (1, 1), None) .read_as::<f64>((px, py), (1, 1), (1, 1), None)
.unwrap(); .unwrap();
raster_value.data[0] Some(raster_value.data[0])
} }
fn get_filename_from_latlon(lat: f64, lon: f64) -> String { fn get_filename_from_latlon(lat: f64, lon: f64) -> String {

View file

@ -1,18 +1,24 @@
mod dem; mod dem;
use axum::{ 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 axum_macros::debug_handler;
use std::env; use std::env;
use tower_http::{services::ServeDir, trace::{self, DefaultMakeSpan}}; use tower_http::{
services::ServeDir,
trace::{self, DefaultMakeSpan},
};
use dem::DatasetRepository; use dem::DatasetRepository;
use tracing::{info, Level, Span};
use tower_http::trace::TraceLayer; use tower_http::trace::TraceLayer;
use tracing::{info, Level, Span};
const DEFAULT_DATA_DIR: &str = "/data"; const DEFAULT_DATA_DIR: &str = "/data";
const DEFAULT_PORT: &str = "3000"; const DEFAULT_PORT: &str = "3000";
@ -22,7 +28,6 @@ async fn main() {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
let config = load_config().unwrap(); let config = load_config().unwrap();
let cache = DatasetRepository::new(config.basedir); let cache = DatasetRepository::new(config.basedir);
@ -32,7 +37,7 @@ async fn main() {
.route("/elevation/:lat/:lon", get(get_elevation)) .route("/elevation/:lat/:lon", get(get_elevation))
.nest_service("/", serve_dir) .nest_service("/", serve_dir)
.with_state(cache) .with_state(cache)
.layer( .layer(
TraceLayer::new_for_http() TraceLayer::new_for_http()
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO)) .make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)), .on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
@ -46,13 +51,17 @@ async fn main() {
} }
#[debug_handler] #[debug_handler]
async fn get_elevation(State(dsr): State<DatasetRepository>, Path((lat, lon)): Path<(f64, f64)>) -> String { async fn get_elevation(
State(dsr): State<DatasetRepository>,
Path((lat, lon)): Path<(f64, f64)>,
) -> impl IntoResponse {
let ele = dem::elevation_from_coordinates(dsr, lat, lon); let ele = dem::elevation_from_coordinates(dsr, lat, lon);
let myele = ele.await; match ele.await {
format!("{myele}") Some(ele) => (StatusCode::OK, format!("{ele}")),
None => (StatusCode::NOT_IMPLEMENTED, "".to_string()),
}
} }
fn load_config() -> Result<Config, env::VarError> { fn load_config() -> Result<Config, env::VarError> {
Ok(Config { Ok(Config {
basedir: env::var("DEM_LOCATION").unwrap_or_else(|_| DEFAULT_DATA_DIR.to_string()), basedir: env::var("DEM_LOCATION").unwrap_or_else(|_| DEFAULT_DATA_DIR.to_string()),