smore shit
Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
This commit is contained in:
parent
e4657c87e6
commit
1c448a240d
2 changed files with 40 additions and 26 deletions
37
src/dem.rs
37
src/dem.rs
|
@ -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 {
|
||||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -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()),
|
||||||
|
|
Loading…
Reference in a new issue