config file ification
This commit is contained in:
parent
aa512c3d97
commit
7bd7b30fec
7 changed files with 96 additions and 8 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2743,9 +2743,11 @@ dependencies = [
|
||||||
"ordered-float",
|
"ordered-float",
|
||||||
"png",
|
"png",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"serde",
|
||||||
"thiserror 1.0.64",
|
"thiserror 1.0.64",
|
||||||
"tikv-jemallocator",
|
"tikv-jemallocator",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"wxbox-grib2",
|
"wxbox-grib2",
|
||||||
|
|
16
config.toml
Normal file
16
config.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[sources.grib2.noaa_mrms_merged_composite_reflectivity_qc]
|
||||||
|
from = "https://mrms.ncep.noaa.gov/data/2D/HAWAII/MergedReflectivityQCComposite/MRMS_MergedReflectivityQCComposite.latest.grib2.gz"
|
||||||
|
needs_gzip = true
|
||||||
|
valid_for = 120
|
||||||
|
palette = """
|
||||||
|
Color: 10 164 164 255 100 100 192
|
||||||
|
Color: 20 64 128 255 32 64 128
|
||||||
|
Color: 30 0 255 0 0 128 0
|
||||||
|
Color: 40 255 255 0 255 128 0
|
||||||
|
Color: 50 255 0 0 160 0 0
|
||||||
|
Color: 60 255 0 255 128 0 128
|
||||||
|
Color: 70 255 255 255 128 128 128
|
||||||
|
Color: 80 128 128 128
|
||||||
|
"""
|
||||||
|
missing = -99.0
|
||||||
|
no_coverage = -999.0
|
|
@ -19,6 +19,8 @@ mime = "0.3.17"
|
||||||
wxbox-grib2 = { version = "0.1", path = "../wxbox-grib2" }
|
wxbox-grib2 = { version = "0.1", path = "../wxbox-grib2" }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = "0.3"
|
tracing-subscriber = "0.3"
|
||||||
|
toml = "0.8"
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
|
|
23
wxbox-tiler/src/config.rs
Normal file
23
wxbox-tiler/src/config.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
pub sources: Sources
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Sources {
|
||||||
|
pub grib2: HashMap<String, Grib2Source>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Grib2Source {
|
||||||
|
pub from: String,
|
||||||
|
pub needs_gzip: bool,
|
||||||
|
pub valid_for: u64,
|
||||||
|
pub palette: String,
|
||||||
|
pub missing: Option<f64>,
|
||||||
|
pub range_folded: Option<f64>,
|
||||||
|
pub no_coverage: Option<f64>
|
||||||
|
}
|
|
@ -1,32 +1,42 @@
|
||||||
pub(crate) mod sources;
|
pub(crate) mod sources;
|
||||||
|
|
||||||
mod pixmap;
|
mod pixmap;
|
||||||
|
mod config;
|
||||||
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
use std::env::args;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::fs;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use actix_web::{App, HttpServer};
|
use actix_web::{App, HttpServer};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use wxbox_grib2::GribMessage;
|
use wxbox_grib2::GribMessage;
|
||||||
|
use crate::config::Config;
|
||||||
|
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
grib2_cache: RwLock<HashMap<String, Arc<RwLock<GribMessage>>>>,
|
grib2_cache: RwLock<HashMap<String, Arc<RwLock<GribMessage>>>>,
|
||||||
grib2_cache_timestamps: RwLock<HashMap<String, SystemTime>>
|
grib2_cache_timestamps: RwLock<HashMap<String, SystemTime>>,
|
||||||
|
config: Config
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
|
let config_path = args().nth(1).unwrap();
|
||||||
|
let config_str = fs::read_to_string(config_path).unwrap();
|
||||||
|
let config: Config = toml::from_str(&config_str).unwrap();
|
||||||
|
|
||||||
let data = Data::new(AppState {
|
let data = Data::new(AppState {
|
||||||
grib2_cache: RwLock::new(HashMap::new()),
|
grib2_cache: RwLock::new(HashMap::new()),
|
||||||
grib2_cache_timestamps: RwLock::new(HashMap::new())
|
grib2_cache_timestamps: RwLock::new(HashMap::new()),
|
||||||
|
config
|
||||||
});
|
});
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.service(sources::noaa::noaa_mrms_merged_composite_reflectivity_qc)
|
.service(sources::grib2::grib2_source)
|
||||||
.app_data(data.clone())
|
.app_data(data.clone())
|
||||||
})
|
})
|
||||||
.bind(("::", 8080))?
|
.bind(("::", 8080))?
|
||||||
|
|
|
@ -3,12 +3,18 @@ use std::f64::consts::PI;
|
||||||
use std::io::{BufWriter, Cursor, Read};
|
use std::io::{BufWriter, Cursor, Read};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
use actix_web::error::UrlencodedError::ContentType;
|
||||||
|
use actix_web::http::StatusCode;
|
||||||
|
use actix_web::HttpResponse;
|
||||||
|
use actix_web::web::Data;
|
||||||
use flate2::read::GzDecoder;
|
use flate2::read::GzDecoder;
|
||||||
use png::{BitDepth, ColorType, Encoder};
|
use png::{BitDepth, ColorType, Encoder};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use wxbox_grib2::GribMessage;
|
use wxbox_grib2::GribMessage;
|
||||||
use wxbox_grib2::wgs84::LatLong;
|
use wxbox_grib2::wgs84::LatLong;
|
||||||
use wxbox_pal::{Color, ColorPalette, Palette};
|
use wxbox_pal::{Color, ColorPalette, Palette};
|
||||||
|
use crate::AppState;
|
||||||
|
use crate::config::Grib2Source;
|
||||||
use crate::pixmap::Pixmap;
|
use crate::pixmap::Pixmap;
|
||||||
|
|
||||||
pub async fn needs_reload(lct: &RwLock<HashMap<String, SystemTime>>, lutkey: &String, valid_for: u64) -> bool {
|
pub async fn needs_reload(lct: &RwLock<HashMap<String, SystemTime>>, lutkey: &String, valid_for: u64) -> bool {
|
||||||
|
@ -125,6 +131,35 @@ pub async fn render(xtile: f64, ytile: f64, z: i32, tilesize: usize, pal: Palett
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_web::get("/grib2/{id}/{z}/{x}/{y}.png")]
|
||||||
|
pub async fn grib2_source(path: actix_web::web::Path<(String, i32, u32, u32)>, data: Data<AppState>) -> HttpResponse {
|
||||||
|
if let Some(known_source) = data.config.sources.grib2.get(&path.0) {
|
||||||
|
reload_if_required(
|
||||||
|
&known_source.from,
|
||||||
|
known_source.needs_gzip,
|
||||||
|
known_source.valid_for.into(),
|
||||||
|
&path.0,
|
||||||
|
&data.grib2_cache_timestamps,
|
||||||
|
&data.grib2_cache
|
||||||
|
).await;
|
||||||
|
let lct_reader = data.grib2_cache_timestamps.read().await;
|
||||||
|
if let Some(grib2) = data.grib2_cache.read().await.get(&path.0) {
|
||||||
|
HttpResponse::Ok()
|
||||||
|
.insert_header(actix_web::http::header::ContentType(mime::IMAGE_PNG))
|
||||||
|
// TODO: use the timestamp in the grib2 ID section
|
||||||
|
.insert_header(("x-wxbox-tiler-data-valid-time", lct_reader.get(&path.0).expect("impossible").duration_since(::std::time::UNIX_EPOCH).expect("time went backwards").as_secs().to_string()))
|
||||||
|
.insert_header(("Access-Control-Allow-Origin", "*"))
|
||||||
|
.insert_header(("Access-Control-Expose-Headers", "*"))
|
||||||
|
.insert_header(("Access-Control-Allow-Headers", "*"))
|
||||||
|
.body(crate::sources::grib2::render(path.2 as f64, path.3 as f64, path.1, 256, wxbox_pal::parser::parse(&known_source.palette).unwrap(), grib2, known_source.missing, known_source.range_folded, known_source.no_coverage).await)
|
||||||
|
} else {
|
||||||
|
HttpResponse::new(StatusCode::NOT_FOUND)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HttpResponse::new(StatusCode::NOT_FOUND)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! grib2_handler {
|
macro_rules! grib2_handler {
|
||||||
(mount $f:ident, at: $path:expr, from: $from:expr, needs_gzip: $needs_gzip:expr, valid_for: $valid_for:expr, palette: $pal:expr, missing: $missing:expr, range_folded: $rf:expr, no_coverage: $nc:expr) => {
|
(mount $f:ident, at: $path:expr, from: $from:expr, needs_gzip: $needs_gzip:expr, valid_for: $valid_for:expr, palette: $pal:expr, missing: $missing:expr, range_folded: $rf:expr, no_coverage: $nc:expr) => {
|
||||||
|
@ -152,4 +187,4 @@ macro_rules! grib2_handler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}*/
|
|
@ -1,13 +1,13 @@
|
||||||
use crate::grib2_handler;
|
//use crate::grib2_handler;
|
||||||
|
/*
|
||||||
grib2_handler! {
|
grib2_handler! {
|
||||||
mount noaa_mrms_merged_composite_reflectivity_qc,
|
mount noaa_mrms_merged_composite_reflectivity_qc,
|
||||||
at: "/noaa_mrms_merged_composite_reflectivity_qc/{z}/{x}/{y}.png",
|
at: "/noaa_mrms_merged_composite_reflectivity_qc/{z}/{x}/{y}.png",
|
||||||
from: "https://mrms.ncep.noaa.gov/data/2D/MergedReflectivityQCComposite/MRMS_MergedReflectivityQCComposite.latest.grib2.gz",
|
from: "https://mrms.ncep.noaa.gov/data/2D/HAWAII/MergedReflectivityQCComposite/MRMS_MergedReflectivityQCComposite.latest.grib2.gz",
|
||||||
needs_gzip: true,
|
needs_gzip: true,
|
||||||
valid_for: 120,
|
valid_for: 120,
|
||||||
palette: wxbox_pal::parser::parse(wxbox_pal::default_palettes::DEFAULT_REFLECTIVITY_PALETTE).unwrap(),
|
palette: wxbox_pal::parser::parse(wxbox_pal::default_palettes::DEFAULT_REFLECTIVITY_PALETTE).unwrap(),
|
||||||
missing: Some(-99.0),
|
missing: Some(-99.0),
|
||||||
range_folded: None,
|
range_folded: None,
|
||||||
no_coverage: Some(-999.0)
|
no_coverage: Some(-999.0)
|
||||||
}
|
}*/
|
Loading…
Reference in a new issue