sync
This commit is contained in:
parent
e4445a4f47
commit
a07acecea2
@ -87,10 +87,11 @@ pub enum AppMsg {
|
|||||||
DeleteElement(ElementKey),
|
DeleteElement(ElementKey),
|
||||||
}
|
}
|
||||||
type RcDispatcher = Rc<Dispatcher>;
|
type RcDispatcher = Rc<Dispatcher>;
|
||||||
|
type ArcDispatcher = Arc<Dispatcher>;
|
||||||
#[tracker::track]
|
#[tracker::track]
|
||||||
pub struct AppModel {
|
pub struct AppModel {
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
dispatcher: RcDispatcher,
|
dispatcher: ArcDispatcher,
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
cms: CMS,
|
cms: CMS,
|
||||||
waiting_for: Option<DateTime<Utc>>,
|
waiting_for: Option<DateTime<Utc>>,
|
||||||
@ -262,7 +263,7 @@ impl Component for AppModel {
|
|||||||
.launch(())
|
.launch(())
|
||||||
.forward(sender.input_sender(), |a| AppMsg::Close);
|
.forward(sender.input_sender(), |a| AppMsg::Close);
|
||||||
|
|
||||||
let mut dispatcher = Rc::new(Dispatcher::new(5, 5, chrono::Duration::minutes(1)));
|
let mut dispatcher = Arc::new(Dispatcher::new(5, 5, chrono::Duration::minutes(1)));
|
||||||
let cms = CMS::new(Mercator::default().into(), (3000.0, 3000.0));
|
let cms = CMS::new(Mercator::default().into(), (3000.0, 3000.0));
|
||||||
let dialog_buffer = buffer.clone();
|
let dialog_buffer = buffer.clone();
|
||||||
let dialog_cms = cms.clone();
|
let dialog_cms = cms.clone();
|
||||||
@ -282,45 +283,15 @@ impl Component for AppModel {
|
|||||||
let meta: MetaInfo = (&data.meta).clone().into();
|
let meta: MetaInfo = (&data.meta).clone().into();
|
||||||
let (lat_start, lat_end) = meta.lat_range.unwrap();
|
let (lat_start, lat_end) = meta.lat_range.unwrap();
|
||||||
let (lon_start, lon_end) = meta.lon_range.unwrap();
|
let (lon_start, lon_end) = meta.lon_range.unwrap();
|
||||||
let imp = tools(&data);
|
let (imp, cfg) = tools(&data);
|
||||||
|
|
||||||
dialog_file_pool.insert(path.clone(), Arc::new(data));
|
dialog_file_pool.insert(path.clone(), Arc::new(data));
|
||||||
use femtovg::Color;
|
|
||||||
let config = GridImpConfig {
|
|
||||||
color_map: ColorMapperComb::BoundaryNormDiscrete(ColorMapper::new(
|
|
||||||
Discrete::new(vec![
|
|
||||||
Color::rgb(0, 172, 164),
|
|
||||||
Color::rgb(192, 192, 254),
|
|
||||||
Color::rgb(122, 114, 238),
|
|
||||||
Color::rgb(30, 38, 208),
|
|
||||||
Color::rgb(166, 252, 168),
|
|
||||||
Color::rgb(0, 234, 0),
|
|
||||||
Color::rgb(16, 146, 26),
|
|
||||||
Color::rgb(252, 244, 100),
|
|
||||||
Color::rgb(200, 200, 2),
|
|
||||||
Color::rgb(140, 140, 0),
|
|
||||||
Color::rgb(254, 172, 172),
|
|
||||||
Color::rgb(254, 100, 92),
|
|
||||||
Color::rgb(238, 2, 48),
|
|
||||||
Color::rgb(212, 142, 254),
|
|
||||||
Color::rgb(170, 36, 250),
|
|
||||||
]),
|
|
||||||
BoundaryNorm::new(
|
|
||||||
vec![
|
|
||||||
0i8, 5i8, 10i8, 15i8, 20i8, 25i8, 30i8, 35i8, 40i8, 45i8,
|
|
||||||
50i8, 55i8, 60i8, 65i8, 70i8, 75i8,
|
|
||||||
],
|
|
||||||
false,
|
|
||||||
Some(-125),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
};
|
|
||||||
let element = Rc::new(RefCell::new(Element::new(
|
let element = Rc::new(RefCell::new(Element::new(
|
||||||
"CR",
|
"CR",
|
||||||
dialog_cms.clone(),
|
dialog_cms.clone(),
|
||||||
dialog_dispatcher.clone(),
|
dialog_dispatcher.clone(),
|
||||||
true,
|
false,
|
||||||
Arc::new(config),
|
cfg,
|
||||||
path.clone(),
|
path.clone(),
|
||||||
dialog_buffer.clone(),
|
dialog_buffer.clone(),
|
||||||
dialog_file_pool.clone(),
|
dialog_file_pool.clone(),
|
||||||
|
|||||||
@ -12,12 +12,12 @@ pub enum OutputMsg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct PathItem {
|
pub struct PathItem {
|
||||||
title: String,
|
title: &'static str,
|
||||||
path: String,
|
path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathItem {
|
impl PathItem {
|
||||||
pub fn new(title: String, path: String) -> Self {
|
pub fn new(title: &'static str, path: String) -> Self {
|
||||||
Self { title, path }
|
Self { title, path }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
use super::dispatcher_list::PathItem;
|
use super::dispatcher_list::PathItem;
|
||||||
use crate::{
|
use crate::{
|
||||||
config::PATH_FORMATS,
|
|
||||||
data::{self, CoordType, Radar2d},
|
data::{self, CoordType, Radar2d},
|
||||||
predefined::color_mapper::BoundaryNorm,
|
predefined::color_mapper::BoundaryNorm,
|
||||||
widgets::render::Layer,
|
widgets::render::Layer,
|
||||||
@ -100,15 +99,15 @@ impl SimpleComponent for SettingModel {
|
|||||||
.forward(sender.input_sender(), |msg| match msg {
|
.forward(sender.input_sender(), |msg| match msg {
|
||||||
_ => SettingMsg::SaveConfig,
|
_ => SettingMsg::SaveConfig,
|
||||||
});
|
});
|
||||||
{
|
// {
|
||||||
let config = CONFIG.lock().unwrap();
|
// let config = CONFIG.lock().unwrap();
|
||||||
let etws_config = config.plugins.get("etws_loader").unwrap();
|
// let etws_config = config.plugins.get("etws_loader").unwrap();
|
||||||
let paths = etws_config.path_formats.as_ref().unwrap_or(&PATH_FORMATS);
|
// // let paths = etws_config.path_formats.as_ref().unwrap_or(&PATH_FORMATS);
|
||||||
let mut list_guard = path_list.guard();
|
// let mut list_guard = path_list.guard();
|
||||||
for p in paths {
|
// for p in paths {
|
||||||
list_guard.push_back(PathItem::new(p.0.clone(), p.1.clone()));
|
// list_guard.push_back(PathItem::new(p.0, p.1.clone()));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
let model = SettingModel { path_list };
|
let model = SettingModel { path_list };
|
||||||
|
|
||||||
let my_view = model.path_list.widget();
|
let my_view = model.path_list.widget();
|
||||||
@ -118,22 +117,22 @@ impl SimpleComponent for SettingModel {
|
|||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
|
// fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
|
||||||
match msg {
|
// match msg {
|
||||||
SettingMsg::PathFormats((plugin, (k, v))) => {
|
// SettingMsg::PathFormats((plugin, (k, v))) => {
|
||||||
let mut config = CONFIG.lock().unwrap();
|
// let mut config = CONFIG.lock().unwrap();
|
||||||
let mut pluging_cfg = config.plugins.get_mut(&plugin).unwrap();
|
// let mut pluging_cfg = config.plugins.get_mut(&plugin).unwrap();
|
||||||
if pluging_cfg.path_formats.is_none() {
|
// if pluging_cfg.path_formats.is_none() {
|
||||||
pluging_cfg.path_formats = Some(HashMap::new());
|
// pluging_cfg.path_formats = Some(HashMap::new());
|
||||||
}
|
// }
|
||||||
pluging_cfg.path_formats.as_mut().unwrap().insert(k, v);
|
// pluging_cfg.path_formats.as_mut().unwrap().insert(&k, v);
|
||||||
let mut list_guard = self.path_list.guard();
|
// let mut list_guard = self.path_list.guard();
|
||||||
// list_guard.push_back(PathItem::new(k, v));
|
// // list_guard.push_back(PathItem::new(k, v));
|
||||||
}
|
// }
|
||||||
SettingMsg::SaveConfig => {
|
// SettingMsg::SaveConfig => {
|
||||||
let mut config = CONFIG.lock().unwrap();
|
// let mut config = CONFIG.lock().unwrap();
|
||||||
config.save();
|
// config.save();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
270
src/config.rs
270
src/config.rs
@ -1,41 +1,238 @@
|
|||||||
use crate::errors::ConfigError;
|
use crate::errors::ConfigError;
|
||||||
|
use crate::predefined::color_mapper::{
|
||||||
|
BoundaryNorm, BoundaryNormDiscrete, ColorMapper, ColorMapperComb, Discrete,
|
||||||
|
};
|
||||||
|
use crate::utils::{
|
||||||
|
create_cc_default_cvmapper, create_hgt_default_cvmapper, create_kdp_default_cvmapper,
|
||||||
|
create_reflect_default_cvmapper, create_vel_default_cvmapper, create_vil_default_cvmapper,
|
||||||
|
parse_hex_color,
|
||||||
|
};
|
||||||
use dirs;
|
use dirs;
|
||||||
|
use gtk::ResponseType::No;
|
||||||
|
use num_traits::{AsPrimitive, FromPrimitive};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::{collections::HashMap, env, io::Write, path::PathBuf};
|
use std::{collections::HashMap, env, io::Write, path::PathBuf};
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
lazy_static! {
|
macro_rules! cvmap {
|
||||||
pub static ref PATH_FORMATS: HashMap<String, String> = {
|
($config:ident,
|
||||||
let mut map = HashMap::new();
|
$({
|
||||||
map.insert("R".to_string(), String::new());
|
$cmap: literal, $vmap: literal, $value: expr
|
||||||
map.insert("V".to_string(), String::new());
|
},)+
|
||||||
map.insert("SW".to_string(), String::new());
|
) => {
|
||||||
map.insert("CC".to_string(), String::new());
|
match ($config.cmap.as_str(), $config.vmap.as_str()) {
|
||||||
map.insert("ZDR".to_string(), String::new());
|
$(
|
||||||
map.insert("PHIDP".to_string(), String::new());
|
($cmap, $vmap) => {
|
||||||
map.insert("KDP".to_string(), String::new());
|
$value
|
||||||
map.insert("HCA".to_string(), String::new());
|
}
|
||||||
map.insert("DBZ".to_string(), String::new());
|
)+
|
||||||
map.insert("QPE".to_string(), String::new());
|
_ => {
|
||||||
map.insert("QPF".to_string(), String::new());
|
panic!("Invalid color and value mapping")
|
||||||
map.insert("VIL".to_string(), String::new());
|
}
|
||||||
map.insert("OHP".to_string(), String::new());
|
}
|
||||||
map.insert("THP".to_string(), String::new());
|
|
||||||
map.insert("ET".to_string(), String::new());
|
|
||||||
map.insert("EB".to_string(), String::new());
|
|
||||||
map
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! drawers {
|
||||||
|
($m:ident, $({
|
||||||
|
$key: literal, $a: ident
|
||||||
|
},)+) => {
|
||||||
|
{
|
||||||
|
let mut defa = Drawers::default();
|
||||||
|
$(
|
||||||
|
let $a = {
|
||||||
|
let kv = $m.remove($key);
|
||||||
|
if let Some(v) = kv {
|
||||||
|
defa.$a = v.try_into()?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
)+
|
||||||
|
// Drawers {
|
||||||
|
// $(
|
||||||
|
// $a,
|
||||||
|
// )+
|
||||||
|
// }
|
||||||
|
defa
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Settings {
|
||||||
|
pub plugin_config: Vec<PluginConfig>,
|
||||||
|
pub drawers: Drawers,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Drawers {
|
||||||
|
pub reflectivity: DrawerConfig<i8>,
|
||||||
|
pub velocity: DrawerConfig<i8>,
|
||||||
|
pub spectrum_width: DrawerConfig<i8>,
|
||||||
|
pub correlation_coefficient: DrawerConfig<f32>,
|
||||||
|
pub differential_reflectivity: DrawerConfig<f32>,
|
||||||
|
pub differential_phase: DrawerConfig<f32>,
|
||||||
|
pub specific_differential_phase: DrawerConfig<f32>,
|
||||||
|
pub hydrometeor_classification: DrawerConfig<i8>,
|
||||||
|
pub radar_rainfall_accumulation: DrawerConfig<f32>,
|
||||||
|
pub radar_rainfall_forecast: DrawerConfig<f32>,
|
||||||
|
pub vertically_integrated_liquid: DrawerConfig<f32>,
|
||||||
|
pub one_hour_precipitation: DrawerConfig<f32>,
|
||||||
|
pub three_hour_precipitation: DrawerConfig<f32>,
|
||||||
|
pub echo_tops: DrawerConfig<f32>,
|
||||||
|
pub echo_bases: DrawerConfig<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Drawers {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
reflectivity: DrawerConfig {
|
||||||
|
title: "Reflectivity",
|
||||||
|
color_mapper: create_reflect_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
velocity: DrawerConfig {
|
||||||
|
title: "Velocity",
|
||||||
|
color_mapper: create_vel_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
spectrum_width: DrawerConfig {
|
||||||
|
title: "Spectrum Width",
|
||||||
|
color_mapper: ColorMapperComb::default(),
|
||||||
|
},
|
||||||
|
|
||||||
|
correlation_coefficient: DrawerConfig {
|
||||||
|
title: "Correlation Coefficient",
|
||||||
|
color_mapper: create_cc_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
differential_reflectivity: DrawerConfig {
|
||||||
|
title: "Differential Reflectivity",
|
||||||
|
color_mapper: create_kdp_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
differential_phase: DrawerConfig {
|
||||||
|
title: "Differential Phase",
|
||||||
|
color_mapper: create_kdp_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
specific_differential_phase: DrawerConfig {
|
||||||
|
title: "Specific Differential Phase",
|
||||||
|
color_mapper: create_kdp_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
hydrometeor_classification: DrawerConfig {
|
||||||
|
title: "Hydrometeor Classification",
|
||||||
|
color_mapper: ColorMapperComb::default(),
|
||||||
|
},
|
||||||
|
|
||||||
|
radar_rainfall_accumulation: DrawerConfig {
|
||||||
|
title: "Radar Rainfall Accumulation",
|
||||||
|
color_mapper: create_vil_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
radar_rainfall_forecast: DrawerConfig {
|
||||||
|
title: "Radar Rainfall Forecast",
|
||||||
|
color_mapper: create_vil_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
vertically_integrated_liquid: DrawerConfig {
|
||||||
|
title: "Vertically Integrated Liquid",
|
||||||
|
color_mapper: create_vil_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
one_hour_precipitation: DrawerConfig {
|
||||||
|
title: "One Hour Precipitation",
|
||||||
|
color_mapper: create_vil_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
three_hour_precipitation: DrawerConfig {
|
||||||
|
title: "Three Hour Precipitation",
|
||||||
|
color_mapper: create_vil_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
echo_tops: DrawerConfig {
|
||||||
|
title: "Echo Tops",
|
||||||
|
color_mapper: create_hgt_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
|
||||||
|
echo_bases: DrawerConfig {
|
||||||
|
title: "Echo Bases",
|
||||||
|
color_mapper: create_hgt_default_cvmapper().into(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct DrawerConfig<T>
|
||||||
|
where
|
||||||
|
T: PartialEq + PartialOrd + Debug + Clone,
|
||||||
|
{
|
||||||
|
pub title: &'static str,
|
||||||
|
pub color_mapper: ColorMapperComb<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SeDrawerConfig {
|
||||||
|
pub cmap: String,
|
||||||
|
pub vmap: String,
|
||||||
|
pub colors: Option<Vec<String>>,
|
||||||
|
pub values: Option<Vec<f32>>,
|
||||||
|
pub extrand: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> TryFrom<SeDrawerConfig> for DrawerConfig<T>
|
||||||
|
where
|
||||||
|
T: FromPrimitive + PartialEq + PartialOrd + Debug + Copy + 'static,
|
||||||
|
f32: AsPrimitive<T>,
|
||||||
|
{
|
||||||
|
type Error = &'static str;
|
||||||
|
fn try_from(value: SeDrawerConfig) -> Result<Self, Self::Error> {
|
||||||
|
let boundaries = value
|
||||||
|
.values
|
||||||
|
.map(|x| x.iter().map(|x| x.as_()).collect::<Vec<T>>())
|
||||||
|
.unwrap();
|
||||||
|
let colors = if let Some(v) = value.colors {
|
||||||
|
let mut colors = Vec::new();
|
||||||
|
for value in v.iter() {
|
||||||
|
let (r, g, b) = parse_hex_color(value)?;
|
||||||
|
colors.push(femtovg::Color::rgb(r, g, b));
|
||||||
|
}
|
||||||
|
Some(colors)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let c = cvmap!(
|
||||||
|
value,
|
||||||
|
{
|
||||||
|
"boundary_norm", "discrete",
|
||||||
|
ColorMapper::new(
|
||||||
|
Discrete::new(colors.unwrap()),
|
||||||
|
BoundaryNorm::new(boundaries, value.extrand.unwrap_or(false), T::from_f32(-125.0)),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
title: "Reflectivity",
|
||||||
|
color_mapper: c.into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub plugins: HashMap<String, PluginConfig>,
|
pub plugins: Vec<PluginConfig>,
|
||||||
|
pub drawer_config: HashMap<String, SeDrawerConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct PluginConfig {
|
pub struct PluginConfig {
|
||||||
pub version: String,
|
pub version: String,
|
||||||
pub path_formats: Option<HashMap<String, String>>,
|
pub name: String,
|
||||||
|
pub publisher: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@ -84,3 +281,32 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Config> for Settings {
|
||||||
|
type Error = &'static str;
|
||||||
|
fn try_from(value: Config) -> Result<Self, Self::Error> {
|
||||||
|
let mut map = value.drawer_config;
|
||||||
|
let c = drawers!(map,
|
||||||
|
{"reflectivity", reflectivity},
|
||||||
|
{"velocity", velocity},
|
||||||
|
{"spectrum_width", spectrum_width},
|
||||||
|
{"correlation_coefficient", correlation_coefficient},
|
||||||
|
{"differential_reflectivity", differential_reflectivity},
|
||||||
|
{"differential_phase", differential_phase},
|
||||||
|
{"specific_differential_phase", specific_differential_phase},
|
||||||
|
{"hydrometeor_classification", hydrometeor_classification},
|
||||||
|
{"radar_rainfall_accumulation", radar_rainfall_accumulation},
|
||||||
|
{"radar_rainfall_forecast", radar_rainfall_forecast},
|
||||||
|
{"vertically_integrated_liquid", vertically_integrated_liquid},
|
||||||
|
{"one_hour_precipitation", one_hour_precipitation},
|
||||||
|
{"three_hour_precipitation", three_hour_precipitation},
|
||||||
|
{"echo_tops", echo_tops},
|
||||||
|
{"echo_bases", echo_bases},
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
plugin_config: value.plugins,
|
||||||
|
drawers: c,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,10 +1,45 @@
|
|||||||
use crate::pipeline::element_imp::*;
|
use crate::pipeline::element_imp::*;
|
||||||
use crate::utils::*;
|
use crate::utils::*;
|
||||||
|
use crate::CONFIG;
|
||||||
use radarg_plugin_interface::{CoordType, DataShape, PluginResult, PluginResultType};
|
use radarg_plugin_interface::{CoordType, DataShape, PluginResult, PluginResultType};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn tools(data: &PluginResult) -> ElementImpl {
|
macro_rules! dispatch {
|
||||||
|
($block:ident,$conf:ident, $wrap:tt , $fill_value: ident, $(
|
||||||
|
{
|
||||||
|
$t:ty | $branch: pat => $v:ident
|
||||||
|
}
|
||||||
|
),+ $(,)?) => {
|
||||||
|
match $block.data_type {
|
||||||
|
$(
|
||||||
|
$branch => {
|
||||||
|
let mut $v = $wrap::default();
|
||||||
|
$v.color_map = $conf.drawers.$v.color_mapper.clone();
|
||||||
|
$v.fill_value = <$t>::from_f64($fill_value);
|
||||||
|
Arc::new($v) as Arc<dyn Any + Send + Sync>
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
|
||||||
|
_ => { panic!("") }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! dis {
|
||||||
|
($block:ident, $config:ident, $wrap:tt, $fill_value: ident) => {
|
||||||
|
dispatch!(
|
||||||
|
$block, $config, $wrap, $fill_value,
|
||||||
|
{ i8|PluginResultType::R => reflectivity },
|
||||||
|
{ i8|PluginResultType::DBZ => reflectivity },
|
||||||
|
{ f32|PluginResultType::ZDR => differential_reflectivity },
|
||||||
|
{ f32|PluginResultType::KDP => specific_differential_phase },
|
||||||
|
{ i8|PluginResultType::PHIDP => differential_phase }
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tools(data: &PluginResult) -> (ElementImpl, Arc<dyn Any + Send + Sync>) {
|
||||||
let blocks_num = data.blocks.len();
|
let blocks_num = data.blocks.len();
|
||||||
|
|
||||||
if blocks_num == 0 {
|
if blocks_num == 0 {
|
||||||
@ -16,16 +51,29 @@ pub fn tools(data: &PluginResult) -> ElementImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let block = data.blocks.first().unwrap();
|
let block = data.blocks.first().unwrap();
|
||||||
|
let fill_value = block.fill_value;
|
||||||
|
let config = CONFIG.read().unwrap();
|
||||||
|
|
||||||
match block.coord_type {
|
let imp = match block.coord_type {
|
||||||
CoordType::Polar => PolarElementImp().into(),
|
CoordType::Polar => {
|
||||||
CoordType::Cartesian => match block.shape {
|
let cfg = dis!(block, config, PolarElementConfig, fill_value);
|
||||||
DataShape::Cube => MultiLayerGridImp().into(),
|
(PolarElementImp().into(), cfg)
|
||||||
DataShape::Matrix => GridImp().into(),
|
}
|
||||||
_ => panic!("Invalid shape"),
|
CoordType::Cartesian => {
|
||||||
},
|
let cfg = dis!(block, config, GridImpConfig, fill_value);
|
||||||
|
(
|
||||||
|
match block.shape {
|
||||||
|
DataShape::Cube => MultiLayerGridImp().into(),
|
||||||
|
DataShape::Matrix => GridImp().into(),
|
||||||
|
_ => panic!("Invalid shape"),
|
||||||
|
},
|
||||||
|
cfg,
|
||||||
|
)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Invalid type")
|
panic!("Invalid type")
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
imp
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/main.rs
12
src/main.rs
@ -4,12 +4,11 @@
|
|||||||
mod utils;
|
mod utils;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
use config::Config;
|
use config::{Config, Settings};
|
||||||
use gtk::{
|
use gtk::{gio, prelude::SettingsExt};
|
||||||
gio::{self, Settings},
|
|
||||||
prelude::SettingsExt,
|
|
||||||
};
|
|
||||||
use plugin_system::{init_plugin, PluginManager};
|
use plugin_system::{init_plugin, PluginManager};
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use std::sync::RwLock;
|
||||||
use std::{ptr, sync::Mutex};
|
use std::{ptr, sync::Mutex};
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
mod actions;
|
mod actions;
|
||||||
@ -41,7 +40,8 @@ declare_surfman!();
|
|||||||
const APP_ID: &str = "org.tsuki.radar_g";
|
const APP_ID: &str = "org.tsuki.radar_g";
|
||||||
static RUNTIME: SafeLazy<Runtime> =
|
static RUNTIME: SafeLazy<Runtime> =
|
||||||
SafeLazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed."));
|
SafeLazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed."));
|
||||||
static CONFIG: SafeLazy<Mutex<Config>> = SafeLazy::new(|| Mutex::new(Config::from_env().unwrap()));
|
static CONFIG: SafeLazy<RwLock<Settings>> =
|
||||||
|
SafeLazy::new(|| RwLock::new(Config::from_env().unwrap().try_into().unwrap()));
|
||||||
static PLUGIN_MANAGER: SafeLazy<PluginManager> = SafeLazy::new(|| PluginManager::new().unwrap());
|
static PLUGIN_MANAGER: SafeLazy<PluginManager> = SafeLazy::new(|| PluginManager::new().unwrap());
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@ -63,41 +63,42 @@ impl Dispatcher {
|
|||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let datetime_format: regex::Regex =
|
let datetime_format: regex::Regex =
|
||||||
Regex::new(r"(?:%[YHMSmd](?:[-/:_]?%[YHMSmd])*)").unwrap();
|
Regex::new(r"(?:%[YHMSmd](?:[-/:_]?%[YHMSmd])*)").unwrap();
|
||||||
let config = CONFIG.lock().unwrap();
|
let config = CONFIG.read().unwrap();
|
||||||
let path_format = config
|
// let path_format = config
|
||||||
.plugins
|
// .plugins
|
||||||
.get("etws_loader")
|
// .get("etws_loader")
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
.path_formats
|
// .path_formats
|
||||||
.as_ref();
|
// .as_ref();
|
||||||
if path_format.is_none() {
|
return None;
|
||||||
return None;
|
// if path_format.is_none() {
|
||||||
}
|
// return None;
|
||||||
let c = path_format.unwrap().get(name).map(|s| {
|
// }
|
||||||
let path = s.clone();
|
// let c = path_format.unwrap().get(name).map(|s| {
|
||||||
let need_formated = datetime_format.captures_iter(&path).collect::<Vec<_>>();
|
// let path = s.clone();
|
||||||
let mut result_path = path.clone();
|
// let need_formated = datetime_format.captures_iter(&path).collect::<Vec<_>>();
|
||||||
|
// let mut result_path = path.clone();
|
||||||
for need_format in need_formated.iter() {
|
//
|
||||||
let fmt = need_format.get(0).unwrap().as_str();
|
// for need_format in need_formated.iter() {
|
||||||
let t = current_time.format(fmt).to_string();
|
// let fmt = need_format.get(0).unwrap().as_str();
|
||||||
result_path = result_path.replace(fmt, &t);
|
// let t = current_time.format(fmt).to_string();
|
||||||
}
|
// result_path = result_path.replace(fmt, &t);
|
||||||
result_path
|
// }
|
||||||
});
|
// result_path
|
||||||
if let Some(c) = c {
|
// });
|
||||||
if check_existed {
|
// if let Some(c) = c {
|
||||||
if std::path::Path::new(&c).exists() {
|
// if check_existed {
|
||||||
Some(c)
|
// if std::path::Path::new(&c).exists() {
|
||||||
} else {
|
// Some(c)
|
||||||
None
|
// } else {
|
||||||
}
|
// None
|
||||||
} else {
|
// }
|
||||||
Some(c)
|
// } else {
|
||||||
}
|
// Some(c)
|
||||||
} else {
|
// }
|
||||||
None
|
// } else {
|
||||||
}
|
// None
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_path(
|
pub fn get_path(
|
||||||
@ -108,92 +109,94 @@ impl Dispatcher {
|
|||||||
mut max_retry_time: usize,
|
mut max_retry_time: usize,
|
||||||
file_path: &PathBuf,
|
file_path: &PathBuf,
|
||||||
) -> Option<Vec<(String, DateTime<Utc>)>> {
|
) -> Option<Vec<(String, DateTime<Utc>)>> {
|
||||||
let config = CONFIG.lock().unwrap();
|
let config = CONFIG.read().unwrap();
|
||||||
let path_format = config
|
|
||||||
.plugins
|
|
||||||
.get("etws_loader")
|
|
||||||
.unwrap()
|
|
||||||
.path_formats
|
|
||||||
.as_ref();
|
|
||||||
if path_format.is_none() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
path_format.unwrap().get(name).map(|s| {
|
|
||||||
let path = s.clone();
|
|
||||||
// let file_path = { file_path_root.lock().unwrap().clone() };
|
|
||||||
let path = if path.starts_with("./") {
|
|
||||||
let file_root = file_root(&file_path, path.replace("./", ""));
|
|
||||||
file_root.map(|root| {
|
|
||||||
let splited = path.split_at(2);
|
|
||||||
root.join(PathBuf::from(splited.1))
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Some(PathBuf::from(path))
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut result_paths = Vec::new();
|
return None;
|
||||||
if let Some(path_uninit) = path {
|
// let path_format = config
|
||||||
let mut path_str = path_uninit.to_string_lossy().to_string();
|
// .plugins
|
||||||
let prefixs = get_prefix(&file_path, &path_str);
|
// .get("etws_loader")
|
||||||
|
// .unwrap()
|
||||||
for (idx, prefix) in prefixs.iter().enumerate() {
|
// .path_formats
|
||||||
if let Some(s) = prefix.as_ref() {
|
// .as_ref();
|
||||||
path_str = path_str.replacen("{prefix}", &s, 1);
|
// if path_format.is_none() {
|
||||||
}
|
// return None;
|
||||||
}
|
// }
|
||||||
|
// path_format.unwrap().get(name).map(|s| {
|
||||||
let need_formated = DATETIME_FORMAT.captures_iter(&path_str).collect::<Vec<_>>();
|
// let path = s.clone();
|
||||||
let mut fore = self.fore_len;
|
// // let file_path = { file_path_root.lock().unwrap().clone() };
|
||||||
let mut back = 1;
|
// let path = if path.starts_with("./") {
|
||||||
|
// let file_root = file_root(&file_path, path.replace("./", ""));
|
||||||
while fore > 0 {
|
// file_root.map(|root| {
|
||||||
let mut result_path = path_str.clone();
|
// let splited = path.split_at(2);
|
||||||
let t = current_time - self.step * fore as i32;
|
// root.join(PathBuf::from(splited.1))
|
||||||
for need_format in need_formated.iter() {
|
// })
|
||||||
let fmt = need_format.get(0).unwrap().as_str();
|
// } else {
|
||||||
let t = t.format(fmt).to_string();
|
// Some(PathBuf::from(path))
|
||||||
result_path = result_path.replace(fmt, &t);
|
// };
|
||||||
}
|
//
|
||||||
|
// let mut result_paths = Vec::new();
|
||||||
if check_existed {
|
// if let Some(path_uninit) = path {
|
||||||
// if max_retry_time == 0 {
|
// let mut path_str = path_uninit.to_string_lossy().to_string();
|
||||||
// break;
|
// let prefixs = get_prefix(&file_path, &path_str);
|
||||||
// }
|
//
|
||||||
if !std::path::Path::new(&result_path).exists() {
|
// for (idx, prefix) in prefixs.iter().enumerate() {
|
||||||
} else {
|
// if let Some(s) = prefix.as_ref() {
|
||||||
result_paths.push((result_path.clone(), t));
|
// path_str = path_str.replacen("{prefix}", &s, 1);
|
||||||
}
|
// }
|
||||||
} else {
|
// }
|
||||||
result_paths.push((result_path.clone(), t));
|
//
|
||||||
}
|
// let need_formated = DATETIME_FORMAT.captures_iter(&path_str).collect::<Vec<_>>();
|
||||||
fore = fore - 1;
|
// let mut fore = self.fore_len;
|
||||||
}
|
// let mut back = 1;
|
||||||
|
//
|
||||||
while back < self.back_len + 1 {
|
// while fore > 0 {
|
||||||
let mut result_path = path_str.clone();
|
// let mut result_path = path_str.clone();
|
||||||
let t = current_time + self.step * back as i32;
|
// let t = current_time - self.step * fore as i32;
|
||||||
for need_format in need_formated.iter() {
|
// for need_format in need_formated.iter() {
|
||||||
let fmt = need_format.get(0).unwrap().as_str();
|
// let fmt = need_format.get(0).unwrap().as_str();
|
||||||
let t = t.format(fmt).to_string();
|
// let t = t.format(fmt).to_string();
|
||||||
result_path = result_path.replace(fmt, &t);
|
// result_path = result_path.replace(fmt, &t);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if check_existed {
|
// if check_existed {
|
||||||
// if max_retry_time == 0 {
|
// // if max_retry_time == 0 {
|
||||||
// break;
|
// // break;
|
||||||
// }
|
// // }
|
||||||
if !std::path::Path::new(&result_path).exists() {
|
// if !std::path::Path::new(&result_path).exists() {
|
||||||
} else {
|
// } else {
|
||||||
result_paths.push((result_path.clone(), t));
|
// result_paths.push((result_path.clone(), t));
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
result_paths.push((result_path.clone(), t));
|
// result_paths.push((result_path.clone(), t));
|
||||||
}
|
// }
|
||||||
back = back + 1;
|
// fore = fore - 1;
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
result_paths
|
// while back < self.back_len + 1 {
|
||||||
})
|
// let mut result_path = path_str.clone();
|
||||||
|
// let t = current_time + self.step * back as i32;
|
||||||
|
// for need_format in need_formated.iter() {
|
||||||
|
// let fmt = need_format.get(0).unwrap().as_str();
|
||||||
|
// let t = t.format(fmt).to_string();
|
||||||
|
// result_path = result_path.replace(fmt, &t);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if check_existed {
|
||||||
|
// // if max_retry_time == 0 {
|
||||||
|
// // break;
|
||||||
|
// // }
|
||||||
|
// if !std::path::Path::new(&result_path).exists() {
|
||||||
|
// } else {
|
||||||
|
// result_paths.push((result_path.clone(), t));
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// result_paths.push((result_path.clone(), t));
|
||||||
|
// }
|
||||||
|
// back = back + 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// result_paths
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ macro_rules! impl_element_imp_dispatch {
|
|||||||
context: &mut Context<'b>
|
context: &mut Context<'b>
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + 'static,
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive + 'static,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
$(
|
$(
|
||||||
@ -147,7 +147,7 @@ pub enum ElementOutput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait ElementImp: Debug + TryFrom<ElementImpl> + Into<ElementImpl> {
|
pub trait ElementImp: Debug + TryFrom<ElementImpl> + Into<ElementImpl> {
|
||||||
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + 'a>: ElementConfig
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + 'a + Clone + FromPrimitive>: ElementConfig
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
type Input<'a, T: 'a>
|
type Input<'a, T: 'a>
|
||||||
@ -161,7 +161,7 @@ pub trait ElementImp: Debug + TryFrom<ElementImpl> + Into<ElementImpl> {
|
|||||||
config: &Self::Config<'a, T>,
|
config: &Self::Config<'a, T>,
|
||||||
context: &mut Context<'b>,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone;
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive;
|
||||||
|
|
||||||
fn output_type(&self) -> ElementOutput;
|
fn output_type(&self) -> ElementOutput;
|
||||||
}
|
}
|
||||||
@ -175,11 +175,13 @@ pub trait ElementConfig {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct GridImp();
|
pub struct GridImp();
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct GridImpConfig<T>
|
pub struct GridImpConfig<T>
|
||||||
where
|
where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Clone,
|
||||||
{
|
{
|
||||||
pub color_map: ColorMapperComb<T>,
|
pub color_map: ColorMapperComb<T>,
|
||||||
|
pub fill_value: T
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridImp {
|
impl GridImp {
|
||||||
@ -213,8 +215,10 @@ impl GridImp {
|
|||||||
let rt_lat = dim2[[r + 1, c + 1]];
|
let rt_lat = dim2[[r + 1, c + 1]];
|
||||||
let rt_lon = dim1[[r + 1, c + 1]];
|
let rt_lon = dim1[[r + 1, c + 1]];
|
||||||
let v = &data[[r, c]];
|
let v = &data[[r, c]];
|
||||||
|
if v == &config.fill_value {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let mapped_color = mapper.color(*v);
|
let mapped_color = mapper.color(*v);
|
||||||
|
|
||||||
if mapped_color.is_none() {
|
if mapped_color.is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -231,7 +235,7 @@ impl GridImp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ElementImp for GridImp {
|
impl ElementImp for GridImp {
|
||||||
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq> = GridImpConfig<T> where
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + Clone + FromPrimitive> = GridImpConfig<T> where
|
||||||
T: 'a;
|
T: 'a;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
fn process<'a, 'b: 'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
@ -241,7 +245,7 @@ impl ElementImp for GridImp {
|
|||||||
config: &Self::Config<'a, T>,
|
config: &Self::Config<'a, T>,
|
||||||
context: &mut Context<'b>,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: Send + Sync + Debug + PartialOrd + PartialEq + Copy + Clone,
|
T: Send + Sync + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive,
|
||||||
{
|
{
|
||||||
let shape = input.shape();
|
let shape = input.shape();
|
||||||
if shape.len() == 2 {
|
if shape.len() == 2 {
|
||||||
@ -268,7 +272,7 @@ impl MultiLayerGridImp {
|
|||||||
config: &MultiLayerGridImpConfig<T>,
|
config: &MultiLayerGridImpConfig<T>,
|
||||||
context: &mut Context<'b>,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy + FromPrimitive,
|
||||||
{
|
{
|
||||||
let two = config.twod.clone();
|
let two = config.twod.clone();
|
||||||
let _layer = data.into_dimensionality::<Ix3>().unwrap();
|
let _layer = data.into_dimensionality::<Ix3>().unwrap();
|
||||||
@ -280,7 +284,7 @@ impl MultiLayerGridImp {
|
|||||||
|
|
||||||
pub struct MultiLayerGridImpConfig<T>
|
pub struct MultiLayerGridImpConfig<T>
|
||||||
where
|
where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Clone,
|
||||||
{
|
{
|
||||||
twod: GridImp,
|
twod: GridImp,
|
||||||
two_d_config: GridImpConfig<T>,
|
two_d_config: GridImpConfig<T>,
|
||||||
@ -288,7 +292,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ElementImp for MultiLayerGridImp {
|
impl ElementImp for MultiLayerGridImp {
|
||||||
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + 'a> =
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + Clone + FromPrimitive + 'a> =
|
||||||
MultiLayerGridImpConfig<T>;
|
MultiLayerGridImpConfig<T>;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
|
|
||||||
@ -299,7 +303,7 @@ impl ElementImp for MultiLayerGridImp {
|
|||||||
config: &Self::Config<'a, T>,
|
config: &Self::Config<'a, T>,
|
||||||
context: &mut Context<'b>,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone,
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive,
|
||||||
{
|
{
|
||||||
self.draw(dims, input, config.upcast_ref(), context);
|
self.draw(dims, input, config.upcast_ref(), context);
|
||||||
}
|
}
|
||||||
@ -312,12 +316,14 @@ impl ElementImp for MultiLayerGridImp {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct PolarElementImp();
|
pub struct PolarElementImp();
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct PolarElementConfig<T>
|
pub struct PolarElementConfig<T>
|
||||||
where
|
where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Clone + FromPrimitive,
|
||||||
{
|
{
|
||||||
color_map: ColorMapperComb<T>,
|
pub color_map: ColorMapperComb<T>,
|
||||||
center: (f64, f64),
|
pub fill_value: T,
|
||||||
|
pub center: (f64, f64),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PolarElementImp {
|
impl PolarElementImp {
|
||||||
@ -382,7 +388,7 @@ impl PolarElementImp {
|
|||||||
config: &'a PolarElementConfig<T>,
|
config: &'a PolarElementConfig<T>,
|
||||||
context: &mut Context<'a>,
|
context: &mut Context<'a>,
|
||||||
) where
|
) where
|
||||||
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy,
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy + FromPrimitive,
|
||||||
{
|
{
|
||||||
let canvas = &mut context.canvas;
|
let canvas = &mut context.canvas;
|
||||||
let mapper = &context.cms;
|
let mapper = &context.cms;
|
||||||
@ -422,7 +428,7 @@ impl PolarElementImp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ElementImp for PolarElementImp {
|
impl ElementImp for PolarElementImp {
|
||||||
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq> = PolarElementConfig<T> where
|
type Config<'a, T: Sync + Send + Debug + PartialOrd + PartialEq + Clone + FromPrimitive> = PolarElementConfig<T> where
|
||||||
T: 'a;
|
T: 'a;
|
||||||
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
type Input<'a, T: 'a> = ArrayViewD<'a, T>;
|
||||||
fn process<'a, 'b: 'a, T>(
|
fn process<'a, 'b: 'a, T>(
|
||||||
@ -432,7 +438,7 @@ impl ElementImp for PolarElementImp {
|
|||||||
config: &Self::Config<'a, T>,
|
config: &Self::Config<'a, T>,
|
||||||
context: &mut Context<'b>,
|
context: &mut Context<'b>,
|
||||||
) where
|
) where
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone,
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + FromPrimitive,
|
||||||
{
|
{
|
||||||
let shape = input.shape();
|
let shape = input.shape();
|
||||||
if shape.len() == 2 {
|
if shape.len() == 2 {
|
||||||
@ -448,13 +454,18 @@ impl ElementImp for PolarElementImp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ElementConfig for GridImpConfig<T> where T: Sync + Send + Debug + PartialOrd + PartialEq {}
|
impl<T> ElementConfig for GridImpConfig<T> where
|
||||||
impl<T> ElementConfig for MultiLayerGridImpConfig<T> where
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Clone
|
||||||
T: Sync + Send + Debug + PartialOrd + PartialEq
|
{
|
||||||
|
}
|
||||||
|
impl<T> ElementConfig for MultiLayerGridImpConfig<T> where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Clone
|
||||||
|
{
|
||||||
|
}
|
||||||
|
impl<T> ElementConfig for PolarElementConfig<T> where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Clone + FromPrimitive
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
impl<T> ElementConfig for PolarElementConfig<T> where T: Sync + Send + Debug + PartialOrd + PartialEq
|
|
||||||
{}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum ElementImpl {
|
pub enum ElementImpl {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ use chrono::prelude::*;
|
|||||||
use femtovg::ImageFlags;
|
use femtovg::ImageFlags;
|
||||||
use femtovg::ImageId;
|
use femtovg::ImageId;
|
||||||
use futures::future::BoxFuture;
|
use futures::future::BoxFuture;
|
||||||
|
use glow::HasContext;
|
||||||
use num_traits::AsPrimitive;
|
use num_traits::AsPrimitive;
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use num_traits::Num;
|
use num_traits::Num;
|
||||||
@ -108,8 +109,7 @@ impl Target {
|
|||||||
if let TargetType::NativeBuffer(ref mem) = self.target {
|
if let TargetType::NativeBuffer(ref mem) = self.target {
|
||||||
use glow::*;
|
use glow::*;
|
||||||
let texture = unsafe {
|
let texture = unsafe {
|
||||||
// let id = gl.create_texture().unwrap();
|
let id = gl.create_texture().unwrap();
|
||||||
let id = gl.create_named_texture(1).unwrap();
|
|
||||||
gl.bind_texture(glow::TEXTURE_2D, Some(id));
|
gl.bind_texture(glow::TEXTURE_2D, Some(id));
|
||||||
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
|
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
|
||||||
gl.pixel_store_i32(glow::UNPACK_ROW_LENGTH, 3000 as i32);
|
gl.pixel_store_i32(glow::UNPACK_ROW_LENGTH, 3000 as i32);
|
||||||
@ -279,11 +279,9 @@ impl RenderResult {
|
|||||||
pub fn new(target: DataTarget, meta_info: MetaInfo) -> Self {
|
pub fn new(target: DataTarget, meta_info: MetaInfo) -> Self {
|
||||||
Self { target, meta_info }
|
Self { target, meta_info }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_meta_info(&self) -> MetaInfo {
|
pub fn get_meta_info(&self) -> MetaInfo {
|
||||||
self.meta_info.clone()
|
self.meta_info.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut_target(&mut self) -> &mut Target {
|
pub fn get_mut_target(&mut self) -> &mut Target {
|
||||||
&mut self.target.target
|
&mut self.target.target
|
||||||
}
|
}
|
||||||
@ -300,7 +298,7 @@ pub struct Element {
|
|||||||
subscribers: Arc<Mutex<HashMap<Key, Vec<oneshot::Sender<Arc<Mutex<PluginResult>>>>>>>,
|
subscribers: Arc<Mutex<HashMap<Key, Vec<oneshot::Sender<Arc<Mutex<PluginResult>>>>>>>,
|
||||||
cancellers: Arc<Mutex<HashMap<Key, oneshot::Sender<()>>>>,
|
cancellers: Arc<Mutex<HashMap<Key, oneshot::Sender<()>>>>,
|
||||||
current_key: Option<Key>,
|
current_key: Option<Key>,
|
||||||
dispatcher: Rc<Dispatcher>,
|
dispatcher: Arc<Dispatcher>,
|
||||||
buffer: Arc<Buffer<Key>>,
|
buffer: Arc<Buffer<Key>>,
|
||||||
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
||||||
current_target: Option<Arc<RwLock<RenderResult>>>,
|
current_target: Option<Arc<RwLock<RenderResult>>>,
|
||||||
@ -318,11 +316,10 @@ impl Element {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
name: impl Into<String>,
|
name: impl Into<String>,
|
||||||
cms: CMS,
|
cms: CMS,
|
||||||
dispatcher: Rc<Dispatcher>,
|
dispatcher: Arc<Dispatcher>,
|
||||||
cache: bool,
|
cache: bool,
|
||||||
config: Arc<dyn Any + Send + Sync>,
|
config: Arc<dyn Any + Send + Sync>,
|
||||||
root: std::path::PathBuf,
|
root: std::path::PathBuf,
|
||||||
|
|
||||||
buffer: Arc<Buffer<Key>>,
|
buffer: Arc<Buffer<Key>>,
|
||||||
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
file_pool: Arc<KVBuffer<PathBuf, Arc<PluginResult>>>,
|
||||||
imp: ElementImpl,
|
imp: ElementImpl,
|
||||||
@ -350,7 +347,12 @@ impl Element {
|
|||||||
let need_cache = self.cache;
|
let need_cache = self.cache;
|
||||||
let output_type = self.imp.output_type();
|
let output_type = self.imp.output_type();
|
||||||
|
|
||||||
fn _init(this: &mut Element, need_cache: bool, output_type: ElementOutput, render: &Render) {
|
fn _init(
|
||||||
|
this: &mut Element,
|
||||||
|
need_cache: bool,
|
||||||
|
output_type: ElementOutput,
|
||||||
|
render: &Render,
|
||||||
|
) {
|
||||||
let data = this.file_pool.get(&this.root);
|
let data = this.file_pool.get(&this.root);
|
||||||
if let Some(data) = data {
|
if let Some(data) = data {
|
||||||
let target = this._rrrr(data, need_cache, output_type, render);
|
let target = this._rrrr(data, need_cache, output_type, render);
|
||||||
@ -369,13 +371,12 @@ impl Element {
|
|||||||
_init(self, need_cache, output_type, render);
|
_init(self, need_cache, output_type, render);
|
||||||
}
|
}
|
||||||
ElementEvent::Draw => {
|
ElementEvent::Draw => {
|
||||||
if let Some(current) = self.current_target.as_ref(){
|
if let Some(current) = self.current_target.as_ref() {
|
||||||
let mut img = current.write().unwrap();
|
let mut img = current.write().unwrap();
|
||||||
let mut img = img.get_mut_target();
|
let mut img = img.get_mut_target();
|
||||||
render.draw_img(img);
|
render.draw_img(img);
|
||||||
} else {
|
} else {
|
||||||
_init(self, need_cache, output_type, render);
|
_init(self, need_cache, output_type, render);
|
||||||
|
|
||||||
if let ElementOutput::Target = output_type {
|
if let ElementOutput::Target = output_type {
|
||||||
let mut _img = self.current_target.as_ref().unwrap();
|
let mut _img = self.current_target.as_ref().unwrap();
|
||||||
let mut img = _img.write().unwrap();
|
let mut img = _img.write().unwrap();
|
||||||
@ -395,71 +396,6 @@ impl Element {
|
|||||||
self.buffer.get(key);
|
self.buffer.get(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// match key {
|
|
||||||
// ElementEvent::Init => {
|
|
||||||
// let data = self.get_file(&self.root);
|
|
||||||
// }
|
|
||||||
// ElementEvent::DateTime(key) => {
|
|
||||||
// let key = &Key {
|
|
||||||
// id: self.id,
|
|
||||||
// name: self.name.clone(),
|
|
||||||
// root: self.root.clone(),
|
|
||||||
// datetime: Some(key),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if self.cache {
|
|
||||||
// if let ElementOutput::Target = self.imp.output_type() {
|
|
||||||
// let target = self.run(key.to_owned()).await;
|
|
||||||
// // if let Some(target) = target {
|
|
||||||
// // let mut target = target.lock().await;
|
|
||||||
// // let target = target.get_mut_target();
|
|
||||||
// // render.draw_img(target);
|
|
||||||
// // }
|
|
||||||
// } else {
|
|
||||||
// let path = (&*self.dispatcher).borrow_mut().get_single_path(
|
|
||||||
// &self.name,
|
|
||||||
// key.datetime.to_owned().unwrap(),
|
|
||||||
// true,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if let Some(path) = path {
|
|
||||||
// let data = self.get_file(path);
|
|
||||||
// let mut _canvas = render.get_canvas();
|
|
||||||
// let mut canvas = _canvas.as_mut().unwrap();
|
|
||||||
// let cms = render.create_cms();
|
|
||||||
// let context = Context::new(cms, canvas);
|
|
||||||
// let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
|
||||||
// runner.run_without_target(&data);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// let path = (&*self.dispatcher).borrow_mut().get_single_path(
|
|
||||||
// &self.name,
|
|
||||||
// key.datetime.to_owned().unwrap(),
|
|
||||||
// true,
|
|
||||||
// );
|
|
||||||
// if let Some(path) = path {
|
|
||||||
// let data = self.get_file(path);
|
|
||||||
// let mut _canvas = render.get_canvas();
|
|
||||||
// let mut canvas = _canvas.as_mut().unwrap();
|
|
||||||
// let cms = render.create_cms();
|
|
||||||
// let context = Context::new(cms, canvas);
|
|
||||||
// let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
|
||||||
// runner.run_without_target(&data);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ElementEvent::Data(data) => {
|
|
||||||
// let mut _canvas = render.get_canvas();
|
|
||||||
// let mut canvas = _canvas.as_mut().unwrap();
|
|
||||||
// let cms = render.create_cms();
|
|
||||||
// let context = Context::new(cms, canvas);
|
|
||||||
// let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
|
||||||
// runner.run_without_target(&data);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_target_to_buffer(&self, key: Key, render_result: RenderResult) {
|
fn insert_target_to_buffer(&self, key: Key, render_result: RenderResult) {
|
||||||
@ -476,13 +412,23 @@ impl Element {
|
|||||||
) -> Option<RenderResult> {
|
) -> Option<RenderResult> {
|
||||||
match output_type {
|
match output_type {
|
||||||
ElementOutput::Target => {
|
ElementOutput::Target => {
|
||||||
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
use tokio::task;
|
||||||
let mut canvas = offscreen_renderer.create_canvas();
|
let cms = self.cms.clone();
|
||||||
let mut context = Context::new(self.cms.clone(), &mut canvas);
|
let imp = self.imp.clone();
|
||||||
let mut runner = Runner::new(self.imp, self.config.clone(), context);
|
let config = self.config.clone();
|
||||||
let target = runner.run(&data);
|
|
||||||
let meta = data.meta.clone().into();
|
let handle = task::spawn_blocking(move || {
|
||||||
Some(RenderResult::new(DataTarget::new(Some(data), target), meta))
|
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||||
|
let mut canvas = offscreen_renderer.create_canvas();
|
||||||
|
let mut context = Context::new(cms, &mut canvas);
|
||||||
|
let mut runner = Runner::new(imp, config, context);
|
||||||
|
let target = runner.run(&data);
|
||||||
|
let meta = data.meta.clone().into();
|
||||||
|
Some(RenderResult::new(DataTarget::new(Some(data), target), meta))
|
||||||
|
});
|
||||||
|
let result = RUNTIME.block_on(handle).ok().flatten();
|
||||||
|
result
|
||||||
|
// let result = RUNTIME.spawn(async {handle.await});
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
@ -508,38 +454,6 @@ impl Element {
|
|||||||
self.current_key.clone().unwrap()
|
self.current_key.clone().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
// async fn run(&self, key: Key) -> Option<Arc<Mutex<RenderResult>>> {
|
|
||||||
// {
|
|
||||||
// let cache = &self.buffer;
|
|
||||||
// if cache.peek(&key).is_some() {
|
|
||||||
// return Some(cache.get(&key).unwrap());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let datetime = key.datetime.unwrap();
|
|
||||||
|
|
||||||
// let dispatcher = (&*self.dispatcher);
|
|
||||||
|
|
||||||
// let current_path = dispatcher.get_single_path(&self.name, datetime, true);
|
|
||||||
// let paths = dispatcher.get_path(&self.name, datetime, true, 3, &self.root);
|
|
||||||
// if let Some(paths) = paths {
|
|
||||||
// paths.iter().for_each(|(p, d)| {
|
|
||||||
// let key = self.generate_key(d.to_owned());
|
|
||||||
// let f = self._run(p, &key);
|
|
||||||
// let handle = tokio::task::spawn(f);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if let Some(path) = current_path {
|
|
||||||
// let key = self.generate_key(datetime);
|
|
||||||
// let f = self._run(path, &key);
|
|
||||||
// let handle = tokio::task::spawn(f);
|
|
||||||
// let result = handle.await.unwrap();
|
|
||||||
// Some(result)
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
fn generate_key(&self, datetime: DateTime<Utc>) -> Key {
|
fn generate_key(&self, datetime: DateTime<Utc>) -> Key {
|
||||||
Key {
|
Key {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
@ -548,81 +462,6 @@ impl Element {
|
|||||||
datetime: Some(datetime),
|
datetime: Some(datetime),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn _run(
|
|
||||||
// &self,
|
|
||||||
// p: impl AsRef<std::path::Path>,
|
|
||||||
// key: &Key,
|
|
||||||
// ) -> BoxFuture<'static, Arc<Mutex<RenderResult>>> {
|
|
||||||
// let (tx, rx) = oneshot::channel();
|
|
||||||
// let buffer = self.buffer.clone();
|
|
||||||
// let config = self.config.clone();
|
|
||||||
// let canceller = self.cancellers.clone();
|
|
||||||
// let subscriber = self.subscribers.clone();
|
|
||||||
// let mut dialog_cms = self.cms.clone();
|
|
||||||
// let mut dialog_config = self.config.clone();
|
|
||||||
// let mut dialog_imp = self.imp.clone();
|
|
||||||
|
|
||||||
// let _key = key.to_owned();
|
|
||||||
// Box::pin(async move {
|
|
||||||
// let key = &_key;
|
|
||||||
// let mut subscribers = subscriber.lock().await;
|
|
||||||
// if subscribers.contains_key(key) {
|
|
||||||
// subscribers.get_mut(key).unwrap().push(tx);
|
|
||||||
// drop(subscribers);
|
|
||||||
// } else {
|
|
||||||
// let (canceller_tx, canceller_rx) = oneshot::channel();
|
|
||||||
// subscribers.insert(key.to_owned(), vec![tx]);
|
|
||||||
// drop(subscribers);
|
|
||||||
|
|
||||||
// let mut cancellers = canceller.lock().await;
|
|
||||||
// cancellers.insert(key.clone(), canceller_tx);
|
|
||||||
// drop(cancellers);
|
|
||||||
|
|
||||||
// use tokio::task;
|
|
||||||
|
|
||||||
// let key = key.to_owned();
|
|
||||||
// tokio::spawn(async move {
|
|
||||||
// let new_key = key.clone();
|
|
||||||
// tokio::select! {
|
|
||||||
// _ = async move {
|
|
||||||
// let handle = task::spawn_blocking(move || {
|
|
||||||
// let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
|
||||||
// let mut canvas = offscreen_renderer.create_canvas();
|
|
||||||
// let mut context = Context::new(dialog_cms, &mut canvas);
|
|
||||||
// let mut runner = Runner::new(dialog_imp, dialog_config, context);
|
|
||||||
|
|
||||||
// let loader = PLUGIN_MANAGER.get_plugin_by_name("etws_loader").unwrap();
|
|
||||||
// let mut loaded_data = loader.load("".into()).unwrap();
|
|
||||||
// let meta = loaded_data.meta.clone().into();
|
|
||||||
|
|
||||||
// let target = runner.run(&loaded_data);
|
|
||||||
|
|
||||||
// RenderResult::new(
|
|
||||||
// DataTarget::new(Some(loaded_data), target),
|
|
||||||
// meta
|
|
||||||
// )
|
|
||||||
// });
|
|
||||||
// let result = handle.await.unwrap();
|
|
||||||
// let bf = Arc::new(Mutex::new(result));
|
|
||||||
// buffer.insert(key.clone(), bf.clone());
|
|
||||||
// let mut subscribers = subscriber.lock().await;
|
|
||||||
// for tx in subscribers.remove(&key).unwrap() {
|
|
||||||
// let _ = tx.send(bf.clone());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// } => {}
|
|
||||||
// _ = canceller_rx => {}
|
|
||||||
// }
|
|
||||||
// let mut cancellers = canceller.lock().await;
|
|
||||||
// cancellers.remove(&new_key);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// rx.await.unwrap()
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn key(&self) -> String {
|
fn key(&self) -> String {
|
||||||
format!("{}-{}", self.id, self.name)
|
format!("{}-{}", self.id, self.name)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,7 +141,6 @@ impl<'a> Runner<'a> {
|
|||||||
{ I32 },
|
{ I32 },
|
||||||
{ F64 },
|
{ F64 },
|
||||||
{ I64 },
|
{ I64 },
|
||||||
{ Bool },
|
|
||||||
{ F32 },
|
{ F32 },
|
||||||
{ I8 },
|
{ I8 },
|
||||||
{ U8 },
|
{ U8 },
|
||||||
|
|||||||
@ -73,9 +73,10 @@ impl PluginManager {
|
|||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
registered_plugins: HashMap::new(),
|
registered_plugins: HashMap::new(),
|
||||||
};
|
};
|
||||||
for (plugin_name, config) in CONFIG.lock().unwrap().plugins.iter() {
|
|
||||||
if let Ok((id, p)) = init_plugin(plugin_name.to_owned()) {
|
for plugin in CONFIG.read().unwrap().plugin_config.iter() {
|
||||||
println!("Loaded plugin: {}", plugin_name);
|
if let Ok((id, p)) = init_plugin(plugin.name.to_owned()) {
|
||||||
|
println!("Loaded plugin: {}", plugin.name);
|
||||||
this.registered_plugins.insert(id, p);
|
this.registered_plugins.insert(id, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,30 +1,52 @@
|
|||||||
use std::fmt::Debug;
|
use abi_stable::type_level::trait_marker::Default;
|
||||||
|
|
||||||
use femtovg::Color;
|
use femtovg::Color;
|
||||||
use image::imageops::ColorMap;
|
use image::imageops::ColorMap;
|
||||||
use num_traits::{AsPrimitive, FromPrimitive, NumOps};
|
use num_traits::{AsPrimitive, FromPrimitive, NumOps};
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
type BoundaryNormDiscrete<T> = ColorMapper<T, Discrete, BoundaryNorm<T>>;
|
pub type BoundaryNormDiscrete<T> = ColorMapper<T, Discrete, BoundaryNorm<T>>;
|
||||||
macro_rules! color_mapper_comb {
|
macro_rules! color_mapper_comb {
|
||||||
($comb: ident, $($key: tt,)+) => {
|
($comb: ident, $($key: tt,)+) => {
|
||||||
|
|
||||||
impl<T: PartialEq + PartialOrd + Debug> $comb<T> {
|
impl<T: PartialEq + PartialOrd + Debug + Clone> $comb<T> {
|
||||||
|
|
||||||
pub fn color(&self, value: T) -> Option<femtovg::Color> {
|
pub fn color(&self, value: T) -> Option<femtovg::Color> {
|
||||||
match self {
|
match self {
|
||||||
$(
|
$(
|
||||||
Self::$key(mapper) => mapper.color(value),
|
Self::$key(mapper) => mapper.color(value),
|
||||||
)+
|
)+
|
||||||
|
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> From<BoundaryNormDiscrete<T>> for $comb<T>
|
||||||
|
where
|
||||||
|
T: PartialEq + PartialOrd + Debug + Clone,
|
||||||
|
{
|
||||||
|
fn from(v: BoundaryNormDiscrete<T>) -> Self {
|
||||||
|
Self::BoundaryNormDiscrete(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ColorMapperComb<T: PartialEq + PartialOrd + Debug> {
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum ColorMapperComb<T: PartialEq + PartialOrd + Debug + Clone> {
|
||||||
BoundaryNormDiscrete(BoundaryNormDiscrete<T>),
|
BoundaryNormDiscrete(BoundaryNormDiscrete<T>),
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> std::default::Default for ColorMapperComb<T>
|
||||||
|
where
|
||||||
|
T: PartialEq + PartialOrd + Debug + Clone,
|
||||||
|
{
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
color_mapper_comb!(ColorMapperComb, BoundaryNormDiscrete,);
|
color_mapper_comb!(ColorMapperComb, BoundaryNormDiscrete,);
|
||||||
@ -38,10 +60,11 @@ pub trait CMap {
|
|||||||
fn map(&self, v: f32) -> femtovg::Color;
|
fn map(&self, v: f32) -> femtovg::Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct ColorMapper<T, CMAP, VMAP>
|
pub struct ColorMapper<T, CMAP, VMAP>
|
||||||
where
|
where
|
||||||
CMAP: CMap,
|
CMAP: CMap + Clone,
|
||||||
VMAP: VMap<Ty = T>,
|
VMAP: VMap<Ty = T> + Clone,
|
||||||
{
|
{
|
||||||
cmap: CMAP,
|
cmap: CMAP,
|
||||||
vmap: VMAP,
|
vmap: VMAP,
|
||||||
@ -50,8 +73,8 @@ where
|
|||||||
impl<T, CMAP, VMAP> ColorMapper<T, CMAP, VMAP>
|
impl<T, CMAP, VMAP> ColorMapper<T, CMAP, VMAP>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
CMAP: CMap,
|
CMAP: CMap + Clone,
|
||||||
VMAP: VMap<Ty = T>,
|
VMAP: VMap<Ty = T> + Clone,
|
||||||
{
|
{
|
||||||
pub fn new(cmap: CMAP, vmap: VMAP) -> Self {
|
pub fn new(cmap: CMAP, vmap: VMAP) -> Self {
|
||||||
Self { cmap, vmap }
|
Self { cmap, vmap }
|
||||||
@ -62,7 +85,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BoundaryNorm<T: PartialOrd + PartialEq> {
|
pub struct BoundaryNorm<T: PartialOrd + PartialEq> {
|
||||||
boundaries: Vec<T>,
|
boundaries: Vec<T>,
|
||||||
extrand: bool,
|
extrand: bool,
|
||||||
@ -106,7 +129,7 @@ where
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Gradient {}
|
pub struct Gradient {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Discrete {
|
pub struct Discrete {
|
||||||
colors: Vec<femtovg::Color>,
|
colors: Vec<femtovg::Color>,
|
||||||
}
|
}
|
||||||
|
|||||||
301
src/utils.rs
301
src/utils.rs
@ -1,17 +1,16 @@
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use femtovg::Color;
|
|
||||||
use gtk::glib::{HasParamSpec, ParamSpecInt64, ParamSpecInt64Builder};
|
|
||||||
use std::{borrow::BorrowMut, num::NonZeroU32};
|
|
||||||
|
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use femtovg::Canvas;
|
use femtovg::Canvas;
|
||||||
|
use femtovg::Color;
|
||||||
|
use gtk::glib::{HasParamSpec, ParamSpecInt64, ParamSpecInt64Builder};
|
||||||
use ndarray::{Array2, ArrayView1};
|
use ndarray::{Array2, ArrayView1};
|
||||||
|
use std::{borrow::BorrowMut, num::NonZeroU32};
|
||||||
use surfman::{
|
use surfman::{
|
||||||
Connection, Context, ContextAttributeFlags, ContextAttributes, ContextDescriptor, Device,
|
Connection, Context, ContextAttributeFlags, ContextAttributes, ContextDescriptor, Device,
|
||||||
GLVersion, NativeConnection, NativeContext, SurfaceAccess, SurfaceType,
|
GLVersion, NativeConnection, NativeContext, SurfaceAccess, SurfaceType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::predefined::color_mapper::BoundaryNorm;
|
use crate::predefined::color_mapper::{BoundaryNorm, BoundaryNormDiscrete, Discrete};
|
||||||
use crate::RUNTIME;
|
use crate::RUNTIME;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -31,7 +30,268 @@ where
|
|||||||
(xx, yy)
|
(xx, yy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! default_cvmapers {
|
||||||
|
($({
|
||||||
|
$key: ident, $value: expr, $colors: expr, $_ty:ty
|
||||||
|
}),+ $(,)?) => {
|
||||||
|
$(
|
||||||
|
pub fn $key() -> BoundaryNormDiscrete<$_ty> {
|
||||||
|
let discrete = Discrete::new($colors);
|
||||||
|
let boundarynorm = BoundaryNorm::new($value, true, None);
|
||||||
|
BoundaryNormDiscrete::new(discrete, boundarynorm)
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
default_cvmapers! {
|
||||||
|
{
|
||||||
|
create_reflect_default_cvmapper,
|
||||||
|
vec![-5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75],
|
||||||
|
vec![
|
||||||
|
Color::rgb(23, 174, 165),
|
||||||
|
Color::rgb(198, 195, 253),
|
||||||
|
Color::rgb(124, 114, 236),
|
||||||
|
Color::rgb(1, 160, 246),
|
||||||
|
Color::rgb(0, 236, 236),
|
||||||
|
Color::rgb(0, 216, 0),
|
||||||
|
Color::rgb(1, 144, 0),
|
||||||
|
Color::rgb(255, 255, 0),
|
||||||
|
Color::rgb(231, 192, 0),
|
||||||
|
Color::rgb(255, 144, 0),
|
||||||
|
Color::rgb(255, 0, 0),
|
||||||
|
Color::rgb(214, 0, 0),
|
||||||
|
Color::rgb(192, 0, 0),
|
||||||
|
Color::rgb(255, 0, 240),
|
||||||
|
Color::rgb(150, 0, 180),
|
||||||
|
Color::rgb(139, 0, 255),
|
||||||
|
],
|
||||||
|
i8
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
create_vel_default_cvmapper,
|
||||||
|
vec![
|
||||||
|
-35, -27, -20, -15, -10, -5, -1, 0, 1, 5, 10, 15, 20, 27,
|
||||||
|
35,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Color::rgb(0, 224, 255),
|
||||||
|
Color::rgb(0, 128, 255),
|
||||||
|
Color::rgb(50, 0, 150),
|
||||||
|
Color::rgb(0, 251, 144),
|
||||||
|
Color::rgb(0, 187, 144),
|
||||||
|
Color::rgb(0, 143, 0),
|
||||||
|
Color::rgb(205, 192, 159),
|
||||||
|
Color::rgb(255, 255, 255),
|
||||||
|
Color::rgb(248, 135, 0),
|
||||||
|
Color::rgb(255, 207, 0),
|
||||||
|
Color::rgb(255, 255, 0),
|
||||||
|
Color::rgb(174, 0, 0),
|
||||||
|
Color::rgb(208, 112, 0),
|
||||||
|
Color::rgb(255, 0, 0),
|
||||||
|
],
|
||||||
|
i8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create_phidp_default_cvmapper,
|
||||||
|
vec![
|
||||||
|
0.0, 22.0, 46.0, 68.0, 90.0, 112.0, 136.0, 158.0, 180.0, 202.0, 224.0, 248.0, 270.0,
|
||||||
|
292.0, 314.0, 359.0,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Color::rgb(0, 60, 255),
|
||||||
|
Color::rgb(0, 239, 239),
|
||||||
|
Color::rgb(0, 186, 191),
|
||||||
|
Color::rgb(0, 131, 125),
|
||||||
|
Color::rgb(0, 137, 56),
|
||||||
|
Color::rgb(0, 183, 41),
|
||||||
|
Color::rgb(0, 218, 13),
|
||||||
|
Color::rgb(0, 255, 0),
|
||||||
|
Color::rgb(255, 255, 59),
|
||||||
|
Color::rgb(255, 240, 0),
|
||||||
|
Color::rgb(255, 198, 0),
|
||||||
|
Color::rgb(255, 165, 0),
|
||||||
|
Color::rgb(255, 114, 0),
|
||||||
|
Color::rgb(255, 31, 0),
|
||||||
|
Color::rgb(193, 0, 0),
|
||||||
|
],
|
||||||
|
f32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create_zdr_default_cvmapper,
|
||||||
|
vec![
|
||||||
|
-5.0, -4.5, -4.0, -3.5, -3.0, -2.5, -2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Color::rgb(70, 70, 70),
|
||||||
|
Color::rgb(80, 80, 80),
|
||||||
|
Color::rgb(90, 90, 90),
|
||||||
|
Color::rgb(100, 100, 100),
|
||||||
|
Color::rgb(110, 110, 110),
|
||||||
|
Color::rgb(120, 120, 120),
|
||||||
|
Color::rgb(130, 130, 130),
|
||||||
|
Color::rgb(140, 140, 140),
|
||||||
|
Color::rgb(150, 150, 150),
|
||||||
|
Color::rgb(175, 175, 175),
|
||||||
|
Color::rgb(200, 200, 200),
|
||||||
|
Color::rgb(220, 240, 220),
|
||||||
|
Color::rgb(0, 192, 39),
|
||||||
|
],
|
||||||
|
f32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create_cc_default_cvmapper,
|
||||||
|
vec![
|
||||||
|
0.0, 0.1, 0.3, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9, 0.92, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Color::rgb(0, 60, 255),
|
||||||
|
Color::rgb(0, 239, 239),
|
||||||
|
Color::rgb(0, 186, 191),
|
||||||
|
Color::rgb(0, 131, 125),
|
||||||
|
Color::rgb(0, 137, 56),
|
||||||
|
Color::rgb(0, 183, 41),
|
||||||
|
Color::rgb(0, 218, 13),
|
||||||
|
Color::rgb(0, 255, 0),
|
||||||
|
Color::rgb(255, 255, 59),
|
||||||
|
Color::rgb(255, 240, 0),
|
||||||
|
Color::rgb(255, 198, 0),
|
||||||
|
Color::rgb(255, 165, 0),
|
||||||
|
Color::rgb(255, 114, 0),
|
||||||
|
Color::rgb(255, 31, 0),
|
||||||
|
Color::rgb(193, 0, 0),
|
||||||
|
],
|
||||||
|
f32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create_vil_default_cvmapper,
|
||||||
|
vec![
|
||||||
|
1.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35., 40., 45., 50., 55., 60., 65., 70.,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Color::rgb(156, 156, 156),
|
||||||
|
Color::rgb(118, 118, 118),
|
||||||
|
Color::rgb(250, 170, 170),
|
||||||
|
Color::rgb(238, 140, 140),
|
||||||
|
Color::rgb(201, 112, 112),
|
||||||
|
Color::rgb(0, 251, 144),
|
||||||
|
Color::rgb(0, 187, 0),
|
||||||
|
Color::rgb(255, 255, 112),
|
||||||
|
Color::rgb(208, 208, 96),
|
||||||
|
Color::rgb(255, 96, 96),
|
||||||
|
Color::rgb(218, 0, 0),
|
||||||
|
Color::rgb(174, 0, 0),
|
||||||
|
Color::rgb(0, 0, 255),
|
||||||
|
Color::rgb(255, 255, 255),
|
||||||
|
],
|
||||||
|
f32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create_hgt_default_cvmapper,
|
||||||
|
vec![
|
||||||
|
0.0, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 11., 12., 14., 15., 17., 18., 20., 21.,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Color::rgb(0, 0, 0),
|
||||||
|
Color::rgb(118, 118, 118),
|
||||||
|
Color::rgb(0, 224, 255),
|
||||||
|
Color::rgb(0, 176, 255),
|
||||||
|
Color::rgb(0, 144, 204),
|
||||||
|
Color::rgb(50, 0, 150),
|
||||||
|
Color::rgb(0, 251, 144),
|
||||||
|
Color::rgb(0, 187, 0),
|
||||||
|
Color::rgb(0, 239, 0),
|
||||||
|
Color::rgb(254, 191, 0),
|
||||||
|
Color::rgb(255, 255, 0),
|
||||||
|
Color::rgb(174, 0, 0),
|
||||||
|
Color::rgb(255, 0, 0),
|
||||||
|
Color::rgb(255, 255, 255),
|
||||||
|
],
|
||||||
|
f32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create_et_default_cvmapper,
|
||||||
|
vec![
|
||||||
|
0.1, 0.2, 0.5, 1.0, 1.5, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 11.0, 12.0, 14.0, 15.0, 17.0,
|
||||||
|
18.0, 20.0, 21.0,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Color::rgb(204, 253, 255),
|
||||||
|
Color::rgb(153, 248, 255),
|
||||||
|
Color::rgb(101, 239, 255),
|
||||||
|
Color::rgb(50, 227, 255),
|
||||||
|
Color::rgb(134, 255, 134),
|
||||||
|
Color::rgb(80, 255, 80),
|
||||||
|
Color::rgb(0, 241, 1),
|
||||||
|
Color::rgb(0, 187, 0),
|
||||||
|
Color::rgb(255, 255, 84),
|
||||||
|
Color::rgb(255, 240, 0),
|
||||||
|
Color::rgb(255, 191, 0),
|
||||||
|
Color::rgb(255, 168, 0),
|
||||||
|
Color::rgb(255, 89, 89),
|
||||||
|
Color::rgb(255, 64, 64),
|
||||||
|
Color::rgb(255, 13, 13),
|
||||||
|
Color::rgb(237, 0, 0),
|
||||||
|
Color::rgb(205, 0, 0),
|
||||||
|
Color::rgb(139, 0, 0),
|
||||||
|
],
|
||||||
|
f32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create_cpc_default_cvmapper,
|
||||||
|
vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
||||||
|
vec![
|
||||||
|
Color::rgb(201, 196, 191),
|
||||||
|
Color::rgb(112, 188, 73),
|
||||||
|
Color::rgb(245, 163, 110),
|
||||||
|
Color::rgb(208, 119, 52),
|
||||||
|
Color::rgb(234, 37, 47),
|
||||||
|
Color::rgb(199, 53, 47),
|
||||||
|
Color::rgb(145, 71, 152),
|
||||||
|
Color::rgb(178, 177, 65),
|
||||||
|
Color::rgb(103, 199, 208),
|
||||||
|
Color::rgb(55, 90, 165),
|
||||||
|
Color::rgb(187, 165, 204),
|
||||||
|
],
|
||||||
|
i8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
create_kdp_default_cvmapper,
|
||||||
|
vec![
|
||||||
|
-0.8, -0.4, -0.2, -0.1, 0.1, 0.15, 0.22, 0.33, 0.5, 0.75, 1.1, 1.7, 2.4, 3.1, 7.0, 20.0,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
Color::rgb(0, 255, 255),
|
||||||
|
Color::rgb(0, 239, 239),
|
||||||
|
Color::rgb(0, 168, 172),
|
||||||
|
Color::rgb(180, 180, 180),
|
||||||
|
Color::rgb(180, 180, 180),
|
||||||
|
Color::rgb(0, 192, 39),
|
||||||
|
Color::rgb(0, 232, 10),
|
||||||
|
Color::rgb(36, 255, 36),
|
||||||
|
Color::rgb(255, 255, 30),
|
||||||
|
Color::rgb(255, 230, 0),
|
||||||
|
Color::rgb(255, 188, 0),
|
||||||
|
Color::rgb(255, 152, 0),
|
||||||
|
Color::rgb(255, 94, 0),
|
||||||
|
Color::rgb(242, 15, 0),
|
||||||
|
Color::rgb(187, 0, 58),
|
||||||
|
Color::rgb(253, 6, 253),
|
||||||
|
],
|
||||||
|
f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pub fn create_dbz_boundarynorm() -> BoundaryNorm<i8> {
|
// pub fn create_dbz_boundarynorm() -> BoundaryNorm<i8> {
|
||||||
|
//
|
||||||
|
// // Discrete::new()
|
||||||
|
//
|
||||||
|
// // BoundaryNorm::new()
|
||||||
|
//
|
||||||
|
// BoundaryNormDiscrete::new(
|
||||||
|
//
|
||||||
|
// )
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![
|
// vec![
|
||||||
// -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
|
// -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
|
||||||
@ -85,7 +345,7 @@ where
|
|||||||
// -125.0,
|
// -125.0,
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// pub fn create_phidp_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_phidp_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![
|
// vec![
|
||||||
@ -113,7 +373,7 @@ where
|
|||||||
// -125.0,
|
// -125.0,
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// pub fn create_zdr_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_zdr_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![
|
// vec![
|
||||||
@ -138,7 +398,7 @@ where
|
|||||||
// -125.0,
|
// -125.0,
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// pub fn create_cc_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_cc_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![
|
// vec![
|
||||||
@ -165,7 +425,7 @@ where
|
|||||||
// -125.0,
|
// -125.0,
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// pub fn create_vil_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_vil_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![
|
// vec![
|
||||||
@ -191,7 +451,7 @@ where
|
|||||||
// -125.0,
|
// -125.0,
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// pub fn create_hgt_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_hgt_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![
|
// vec![
|
||||||
@ -217,7 +477,7 @@ where
|
|||||||
// -125.0,
|
// -125.0,
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// pub fn create_et_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_et_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![
|
// vec![
|
||||||
@ -248,7 +508,7 @@ where
|
|||||||
// -125.0,
|
// -125.0,
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// pub fn create_cpc_boundarynorm() -> BoundaryNorm<i8> {
|
// pub fn create_cpc_boundarynorm() -> BoundaryNorm<i8> {
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
// vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
||||||
@ -269,7 +529,7 @@ where
|
|||||||
// -125,
|
// -125,
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
// pub fn create_kdp_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_kdp_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
// BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
// vec![
|
// vec![
|
||||||
@ -327,3 +587,18 @@ pub fn estimate_zoom_level(
|
|||||||
|
|
||||||
zoom_level_estimation.round() as u8
|
zoom_level_estimation.round() as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_hex_color(hex: &str) -> Result<(u8, u8, u8), &'static str> {
|
||||||
|
if hex.starts_with('#') && hex.len() == 7 {
|
||||||
|
let r = u8::from_str_radix(&hex[1..3], 16);
|
||||||
|
let g = u8::from_str_radix(&hex[3..5], 16);
|
||||||
|
let b = u8::from_str_radix(&hex[5..7], 16);
|
||||||
|
|
||||||
|
match (r, g, b) {
|
||||||
|
(Ok(r), Ok(g), Ok(b)) => Ok((r, g, b)),
|
||||||
|
_ => Err("Invalid hexadecimal value"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err("Invalid color format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use crate::coords::Mapper;
|
|||||||
use crate::map_tile::MapTile;
|
use crate::map_tile::MapTile;
|
||||||
use crate::pipeline::new_element::{Target, TargetType};
|
use crate::pipeline::new_element::{Target, TargetType};
|
||||||
use femtovg::{Canvas, Color, FontId, Paint, Renderer};
|
use femtovg::{Canvas, Color, FontId, Paint, Renderer};
|
||||||
|
use glow::HasContext;
|
||||||
use gtk::glib::{self, prelude::*, Properties};
|
use gtk::glib::{self, prelude::*, Properties};
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
@ -15,7 +16,6 @@ use std::collections::HashMap;
|
|||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use glow::HasContext;
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
||||||
|
|||||||
@ -4,12 +4,12 @@ use crate::pipeline::new_element::{self, Target};
|
|||||||
use crate::pipeline::new_element::{Element, ElementEvent};
|
use crate::pipeline::new_element::{Element, ElementEvent};
|
||||||
use crate::RUNTIME;
|
use crate::RUNTIME;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum ElementType {
|
pub enum ElementType {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user