2024-04-11 12:17:39 +00:00
|
|
|
mod dem;
|
2024-04-11 13:38:46 +00:00
|
|
|
|
|
|
|
use axum::{
|
2024-04-15 22:22:06 +00:00
|
|
|
extract::{Path, State},
|
|
|
|
http::StatusCode,
|
|
|
|
response::IntoResponse,
|
|
|
|
routing::get,
|
|
|
|
Router,
|
2024-04-11 13:38:46 +00:00
|
|
|
};
|
2024-04-15 21:17:14 +00:00
|
|
|
use axum_macros::debug_handler;
|
|
|
|
use std::env;
|
|
|
|
|
2024-04-15 22:22:06 +00:00
|
|
|
use tower_http::{
|
|
|
|
services::ServeDir,
|
|
|
|
trace::{self, DefaultMakeSpan},
|
|
|
|
};
|
2024-04-15 21:17:14 +00:00
|
|
|
|
|
|
|
use dem::DatasetRepository;
|
2024-04-11 13:38:46 +00:00
|
|
|
|
2024-04-15 21:44:57 +00:00
|
|
|
use tower_http::trace::TraceLayer;
|
2024-04-15 22:22:06 +00:00
|
|
|
use tracing::{info, Level, Span};
|
2024-04-11 18:10:53 +00:00
|
|
|
|
2024-04-15 21:17:14 +00:00
|
|
|
const DEFAULT_DATA_DIR: &str = "/data";
|
|
|
|
const DEFAULT_PORT: &str = "3000";
|
2024-04-11 18:34:55 +00:00
|
|
|
|
2024-04-15 21:17:14 +00:00
|
|
|
#[tokio::main]
|
2024-04-11 13:38:46 +00:00
|
|
|
async fn main() {
|
|
|
|
// initialize tracing
|
|
|
|
tracing_subscriber::fmt::init();
|
2024-04-11 12:09:39 +00:00
|
|
|
|
2024-04-15 21:17:14 +00:00
|
|
|
let config = load_config().unwrap();
|
|
|
|
let cache = DatasetRepository::new(config.basedir);
|
|
|
|
|
|
|
|
let serve_dir = ServeDir::new("assets");
|
2024-04-11 18:10:53 +00:00
|
|
|
|
2024-04-11 13:38:46 +00:00
|
|
|
let app = Router::new()
|
2024-04-11 18:10:53 +00:00
|
|
|
.route("/elevation/:lat/:lon", get(get_elevation))
|
2024-04-15 21:17:14 +00:00
|
|
|
.nest_service("/", serve_dir)
|
2024-04-15 21:44:57 +00:00
|
|
|
.with_state(cache)
|
2024-04-15 22:22:06 +00:00
|
|
|
.layer(
|
2024-04-15 21:44:57 +00:00
|
|
|
TraceLayer::new_for_http()
|
|
|
|
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
|
|
|
|
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
|
|
|
|
);
|
2024-04-11 13:38:46 +00:00
|
|
|
|
2024-04-15 21:17:14 +00:00
|
|
|
let host = format!("[::]:{}", config.port);
|
2024-04-11 22:33:10 +00:00
|
|
|
info!("Will start server on {host}");
|
|
|
|
|
|
|
|
let listener = tokio::net::TcpListener::bind(host).await.unwrap();
|
|
|
|
axum::serve(listener, app).await.unwrap();
|
2024-04-11 12:09:39 +00:00
|
|
|
}
|
2024-04-11 13:38:46 +00:00
|
|
|
|
|
|
|
#[debug_handler]
|
2024-04-15 22:22:06 +00:00
|
|
|
async fn get_elevation(
|
|
|
|
State(dsr): State<DatasetRepository>,
|
|
|
|
Path((lat, lon)): Path<(f64, f64)>,
|
|
|
|
) -> impl IntoResponse {
|
2024-04-15 21:17:14 +00:00
|
|
|
let ele = dem::elevation_from_coordinates(dsr, lat, lon);
|
2024-04-15 22:22:06 +00:00
|
|
|
match ele.await {
|
|
|
|
Some(ele) => (StatusCode::OK, format!("{ele}")),
|
|
|
|
None => (StatusCode::NOT_IMPLEMENTED, "".to_string()),
|
|
|
|
}
|
2024-04-11 13:38:46 +00:00
|
|
|
}
|
|
|
|
|
2024-04-15 21:17:14 +00:00
|
|
|
fn load_config() -> Result<Config, env::VarError> {
|
|
|
|
Ok(Config {
|
|
|
|
basedir: env::var("DEM_LOCATION").unwrap_or_else(|_| DEFAULT_DATA_DIR.to_string()),
|
|
|
|
port: env::var("HTTP_PORT").unwrap_or_else(|_| DEFAULT_PORT.to_string()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Config {
|
|
|
|
basedir: String,
|
|
|
|
port: String,
|
2024-04-15 21:44:57 +00:00
|
|
|
}
|