init
This commit is contained in:
parent
cd4c46f9c6
commit
e0c02a4e35
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -529,6 +529,7 @@ dependencies = [
|
|||||||
"core_extensions",
|
"core_extensions",
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
"dirs",
|
"dirs",
|
||||||
|
"enum_dispatch",
|
||||||
"epoxy",
|
"epoxy",
|
||||||
"euclid",
|
"euclid",
|
||||||
"femtovg",
|
"femtovg",
|
||||||
@ -986,7 +987,7 @@ version = "0.5.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libloading 0.7.4",
|
"libloading 0.8.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1032,6 +1033,18 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum_dispatch"
|
||||||
|
version = "0.3.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2 1.0.76",
|
||||||
|
"quote 1.0.35",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
|
|||||||
@ -72,6 +72,7 @@ reqwest = "0.11.25"
|
|||||||
url = "2.5.0"
|
url = "2.5.0"
|
||||||
quick_cache = "0.4.1"
|
quick_cache = "0.4.1"
|
||||||
fns = "0.0.7"
|
fns = "0.0.7"
|
||||||
|
enum_dispatch = "0.3.12"
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|||||||
@ -7,7 +7,9 @@ use super::{
|
|||||||
ControlPanelOutputMsg, TimelineMsg,
|
ControlPanelOutputMsg, TimelineMsg,
|
||||||
};
|
};
|
||||||
use crate::components::sidebar::{SideBarInputMsg, SideBarModel};
|
use crate::components::sidebar::{SideBarInputMsg, SideBarModel};
|
||||||
use crate::pipeline::{GridElementImpl, OffscreenRenderer};
|
use crate::data_utils::tools;
|
||||||
|
use crate::pipeline::element::DataTarget;
|
||||||
|
use crate::pipeline::OffscreenRenderer;
|
||||||
use crate::predefined::widgets::ColorBar;
|
use crate::predefined::widgets::ColorBar;
|
||||||
use crate::widgets::{AssoElement, DynamicCol};
|
use crate::widgets::{AssoElement, DynamicCol};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -22,12 +24,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
data::MetaInfo,
|
data::MetaInfo,
|
||||||
errors::RenderError,
|
errors::RenderError,
|
||||||
pipeline::{utils::data_to_element, Dispatcher, Pipeline, RenderResult},
|
pipeline::{Dispatcher, Pipeline, RenderResult},
|
||||||
plugin_system::init_plugin,
|
plugin_system::init_plugin,
|
||||||
widgets::render::Layer,
|
widgets::render::Layer,
|
||||||
CONFIG, PLUGIN_MANAGER,
|
CONFIG, PLUGIN_MANAGER,
|
||||||
};
|
};
|
||||||
use crate::{data_utils::plugin_result_impl, pipeline::element::DataTarget};
|
|
||||||
use abi_stable::std_types::RStr;
|
use abi_stable::std_types::RStr;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use chrono::{prelude::*, Duration};
|
use chrono::{prelude::*, Duration};
|
||||||
@ -272,27 +273,29 @@ 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 element_impl = plugin_result_impl(&data);
|
let imp = tools(&data);
|
||||||
|
// let element_impl = plugin_result_impl(&data);
|
||||||
let mut renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
let mut renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||||
let mut canvas = renderer.create_canvas();
|
let mut canvas = renderer.create_canvas();
|
||||||
let mut dialog_cms = CMS::new(Mercator::default().into(), (3000.0, 3000.0));
|
let mut dialog_cms = CMS::new(Mercator::default().into(), (3000.0, 3000.0));
|
||||||
let data_target = element_impl.render(&data, &mut canvas, &mut dialog_cms);
|
// let data_target = element_impl.render(&data, &mut canvas, &mut dialog_cms);
|
||||||
let data_target = DataTarget::new(Some(data), data_target);
|
// let data_target = DataTarget::new(Some(data), data_target);
|
||||||
let element = Element::create_instant(
|
// let element = Element::create_instant(
|
||||||
InstantElementDrawerType::Prepared((data_target, element_impl)),
|
// InstantElementDrawerType::Prepared((data_target, element_impl)),
|
||||||
dialog_dispatcher.clone(),
|
// dialog_dispatcher.clone(),
|
||||||
"ET".to_string(),
|
// "ET".to_string(),
|
||||||
)
|
// )
|
||||||
.get_instance();
|
// .get_instance();
|
||||||
let layer = Layer::new(
|
// let layer = Layer::new(
|
||||||
true,
|
// true,
|
||||||
"New Layer".to_string(),
|
// "New Layer".to_string(),
|
||||||
AssoElement::Instant(element),
|
// AssoElement::Instant(element),
|
||||||
);
|
// );
|
||||||
dialog_sidebar_sender.emit(SideBarInputMsg::AddMetaItems(meta.to_map()));
|
// dialog_sidebar_sender.emit(SideBarInputMsg::AddMetaItems(meta.to_map()));
|
||||||
dialog_render_sender.emit(MonitorInputMsg::SetRenderRange(
|
// dialog_render_sender.emit(MonitorInputMsg::SetRenderRange(
|
||||||
lon_start, lon_end, lat_start, lat_end,
|
// lon_start, lon_end, lat_start, lat_end,
|
||||||
));
|
// ));
|
||||||
|
let layer = Layer::new(true, "New Layer".to_string(), AssoElement::Test);
|
||||||
|
|
||||||
AppMsg::LayerManager(LayerMsg::Add(layer))
|
AppMsg::LayerManager(LayerMsg::Add(layer))
|
||||||
}
|
}
|
||||||
@ -425,8 +428,9 @@ impl AppModel {
|
|||||||
.load(RStr::from_str(path.as_ref().to_str().unwrap()))
|
.load(RStr::from_str(path.as_ref().to_str().unwrap()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let block = result.blocks.first().unwrap();
|
let block = result.blocks.first().unwrap();
|
||||||
data_to_element(block, dispatcher, cms)
|
// data_to_element(block, dispatcher, cms)
|
||||||
.map(|v| (Some(Box::new(result) as Box<dyn Any + Send + Sync>), v))
|
// .map(|v| (Some(Box::new(result) as Box<dyn Any + Send + Sync>), v))
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_file_only(path: impl AsRef<std::path::Path>) -> PluginResult {
|
fn open_file_only(path: impl AsRef<std::path::Path>) -> PluginResult {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::coords::Mapper;
|
use crate::coords::Mapper;
|
||||||
|
use epoxy::XOR;
|
||||||
use geo_types::LineString;
|
use geo_types::LineString;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
@ -48,6 +49,18 @@ impl CMS {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fore_map(&self, loc: (f32, f32)) -> Option<(f64, f64)> {
|
||||||
|
let (x, y) = loc;
|
||||||
|
let (x, y) = (x as f64, y as f64);
|
||||||
|
|
||||||
|
let (x, y) = (
|
||||||
|
self.bounds.0 + x * (self.bounds.1 - self.bounds.0),
|
||||||
|
self.bounds.1 + y * (self.bounds.3 - self.bounds.2),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.mapper.inverse_map((x, y)).ok()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ring_map(&self, line: &LineString) -> Option<LineString<f32>> {
|
pub fn ring_map(&self, line: &LineString) -> Option<LineString<f32>> {
|
||||||
Some(
|
Some(
|
||||||
line.points()
|
line.points()
|
||||||
|
|||||||
@ -18,6 +18,20 @@ pub type Radar2dRef<'a, T> = RadarData2d<T, ViewRepr<&'a T>, ViewRepr<&'a f64>,
|
|||||||
pub type Radar3dRef<'a, T> =
|
pub type Radar3dRef<'a, T> =
|
||||||
RadarData3d<T, ViewRepr<&'a T>, ViewRepr<&'a f64>, ViewRepr<&'a f64>, ViewRepr<&'a f64>>;
|
RadarData3d<T, ViewRepr<&'a T>, ViewRepr<&'a f64>, ViewRepr<&'a f64>, ViewRepr<&'a f64>>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum DataType {
|
||||||
|
F64,
|
||||||
|
I64,
|
||||||
|
U64,
|
||||||
|
F32,
|
||||||
|
I32,
|
||||||
|
U32,
|
||||||
|
I16,
|
||||||
|
U16,
|
||||||
|
I8,
|
||||||
|
U8,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum CoordType {
|
pub enum CoordType {
|
||||||
Polar,
|
Polar,
|
||||||
|
|||||||
@ -1,44 +1,33 @@
|
|||||||
use crate::pipeline::element::ElementImpl;
|
use crate::pipeline::element_imp::*;
|
||||||
use crate::pipeline::GridElementImpl;
|
|
||||||
use crate::utils::*;
|
use crate::utils::*;
|
||||||
use radarg_plugin_interface::{CoordType, DataShape, PluginResult, PluginResultType};
|
use radarg_plugin_interface::{CoordType, DataShape, PluginResult, PluginResultType};
|
||||||
|
use std::any::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
macro_rules! data_to_grid {
|
|
||||||
($_type:ident,$(($branch:path ,$boundary_norm: expr)),+) => {
|
|
||||||
match $_type {
|
|
||||||
$(
|
|
||||||
$branch => {
|
|
||||||
let element_impl = GridElementImpl::new($boundary_norm);
|
|
||||||
Arc::new(element_impl)
|
|
||||||
}
|
|
||||||
),+
|
|
||||||
_ => panic!("Invalid type")
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
pub fn tools(data: &PluginResult) -> ElementImpl {
|
||||||
}
|
let blocks_num = data.blocks.len();
|
||||||
pub fn plugin_result_impl(a: &PluginResult) -> Arc<dyn ElementImpl> {
|
|
||||||
let block = a.blocks.first().unwrap();
|
if blocks_num == 0 {
|
||||||
|
panic!("No blocks found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if blocks_num > 1 {
|
||||||
|
panic!("Too many blocks found");
|
||||||
|
}
|
||||||
|
|
||||||
|
let block = data.blocks.first().unwrap();
|
||||||
|
|
||||||
match block.coord_type {
|
match block.coord_type {
|
||||||
CoordType::Cartesian => {
|
CoordType::Polar => {
|
||||||
let _type = block.data_type;
|
todo!();
|
||||||
data_to_grid!(
|
|
||||||
_type,
|
|
||||||
(PluginResultType::R, create_dbz_boundarynorm()),
|
|
||||||
(PluginResultType::V, create_vel_boundarynorm()),
|
|
||||||
(PluginResultType::CC, create_cc_boundarynorm()),
|
|
||||||
(PluginResultType::ZDR, create_zdr_boundarynorm()),
|
|
||||||
(PluginResultType::PHIDP, create_phidp_boundarynorm()),
|
|
||||||
(PluginResultType::KDP, create_kdp_boundarynorm()),
|
|
||||||
(PluginResultType::DBZ, create_dbz_boundarynorm()),
|
|
||||||
(PluginResultType::VIL, create_vil_boundarynorm()),
|
|
||||||
(PluginResultType::OHP, create_vil_boundarynorm()),
|
|
||||||
(PluginResultType::THP, create_vil_boundarynorm()),
|
|
||||||
(PluginResultType::ET, create_et_boundarynorm())
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
CoordType::Other | CoordType::Polar => {
|
CoordType::Cartesian => match block.shape {
|
||||||
panic!("Invalid type");
|
DataShape::Cube => MultiLayerGridImp().into(),
|
||||||
|
DataShape::Matrix => GridImp().into(),
|
||||||
|
_ => panic!("Invalid shape"),
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
panic!("Invalid type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ mod map_tile;
|
|||||||
mod map_tile_utils;
|
mod map_tile_utils;
|
||||||
mod predefined;
|
mod predefined;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
|
// mod element_imp;
|
||||||
|
|
||||||
#[cfg(target_env = "msvc")]
|
#[cfg(target_env = "msvc")]
|
||||||
declare_surfman!();
|
declare_surfman!();
|
||||||
|
|||||||
351
src/pipeline/element_imp.rs
Normal file
351
src/pipeline/element_imp.rs
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
use super::Target;
|
||||||
|
use crate::coords::cms::CMS;
|
||||||
|
use crate::data::Radar2dRef;
|
||||||
|
use crate::pipeline::offscreen_renderer::CanvasWrapper;
|
||||||
|
use crate::predefined::color_mapper::{CMap, ColorMapper, ColorMapperComb, VMap};
|
||||||
|
use abi_stable::std_types::RVec;
|
||||||
|
use femtovg::{Paint, Path};
|
||||||
|
use ndarray::{ArrayBase, ArrayView1, ArrayView2, ArrayViewD, Axis, Ix2, Ix3};
|
||||||
|
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
||||||
|
use radarg_plugin_interface::{DataShape, PluginResult, VecResult};
|
||||||
|
use std::any::Any;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
const EARTH_RADIUS: f64 = 6371.0;
|
||||||
|
|
||||||
|
macro_rules! impl_element_imp_dispatch {
|
||||||
|
($({$Abc: ident, $t:ty},)+) => {
|
||||||
|
impl ElementImpl {
|
||||||
|
pub fn process<T>(&self,
|
||||||
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
|
input: ArrayViewD<'_, T>,
|
||||||
|
config: &dyn Any,
|
||||||
|
context: &mut Context
|
||||||
|
)
|
||||||
|
where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone + 'static,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
Self::$Abc(imp) => {
|
||||||
|
let config = config.downcast_ref::<<$t as ElementImp>::Config<T>>().unwrap();
|
||||||
|
imp.process(dims, input, config, context);
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_element_try_from_dispatch {
|
||||||
|
($({ $Abc: ident, $t:ty},)+) => {
|
||||||
|
$(
|
||||||
|
impl TryFrom<ElementImpl> for $t {
|
||||||
|
type Error = &'static str;
|
||||||
|
fn try_from(value: ElementImpl) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
ElementImpl::$Abc(imp) => Ok(imp),
|
||||||
|
_ => Err("Invalid type"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_element_into_dispatch {
|
||||||
|
($({ $Abc: ident, $t:ty},)+) => {
|
||||||
|
$(
|
||||||
|
impl From<$t> for ElementImpl {
|
||||||
|
fn from(value: $t) -> Self {
|
||||||
|
Self::$Abc(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! for_all_variants {
|
||||||
|
($macro: tt) => {
|
||||||
|
$macro! {
|
||||||
|
{Grid, GridImp},
|
||||||
|
{MultiLayerGrid, MultiLayerGridImp},
|
||||||
|
{Polar, PolarElementImp},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Context {
|
||||||
|
cms: CMS,
|
||||||
|
canvas: CanvasWrapper,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ElementImp: Debug + TryFrom<ElementImpl> + Into<ElementImpl> {
|
||||||
|
type Config<T: Sync + Send + Debug + PartialOrd + PartialEq>;
|
||||||
|
fn process<T>(
|
||||||
|
&self,
|
||||||
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
|
input: ArrayViewD<'_, T>,
|
||||||
|
config: &Self::Config<T>,
|
||||||
|
context: &mut Context,
|
||||||
|
) where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GridImp();
|
||||||
|
|
||||||
|
pub struct GridImpConfig<T>
|
||||||
|
where
|
||||||
|
T: PartialOrd + PartialEq + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
color_map: ColorMapperComb<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GridImp {
|
||||||
|
fn draw_2d<T>(
|
||||||
|
&self,
|
||||||
|
config: &GridImpConfig<T>,
|
||||||
|
data: ArrayView2<T>,
|
||||||
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
|
context: &mut Context,
|
||||||
|
) where
|
||||||
|
T: PartialEq + PartialOrd + Copy + Clone + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
let cms = &context.cms;
|
||||||
|
let canvas = &mut context.canvas;
|
||||||
|
let shape = data.shape();
|
||||||
|
let mapper = &config.color_map;
|
||||||
|
let (rows, cols) = (shape[0], shape[1]);
|
||||||
|
let (dim1, dim2) = dims;
|
||||||
|
|
||||||
|
let d1_s = dim1[[0, 0]];
|
||||||
|
let d1_e = dim1[[0, cols - 1]];
|
||||||
|
|
||||||
|
let d2_s = dim2[[0, 0]];
|
||||||
|
let d2_e = dim2[[rows - 1, 0]];
|
||||||
|
|
||||||
|
for r in 0..rows - 1 {
|
||||||
|
for c in 0..cols - 1 {
|
||||||
|
let lb_lat = dim2[[r, c]];
|
||||||
|
let lb_lon = dim1[[r, c]];
|
||||||
|
|
||||||
|
let rt_lat = dim2[[r + 1, c + 1]];
|
||||||
|
let rt_lon = dim1[[r + 1, c + 1]];
|
||||||
|
let v = &data[[r, c]];
|
||||||
|
let mapped_color = mapper.color(*v);
|
||||||
|
|
||||||
|
if mapped_color.is_none() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (ox, oy) = cms.map((lb_lon, lb_lat)).unwrap();
|
||||||
|
let (rx, ry) = cms.map((rt_lon, rt_lat)).unwrap();
|
||||||
|
|
||||||
|
let mut path = Path::new();
|
||||||
|
path.rect(ox, oy, (rx - ox) * 1.5, (ry - oy) * 1.5);
|
||||||
|
canvas.fill_path(&path, &Paint::color(mapped_color.unwrap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElementImp for GridImp {
|
||||||
|
type Config<T: Sync + Send + Debug + PartialOrd + PartialEq> = GridImpConfig<T>;
|
||||||
|
fn process<T>(
|
||||||
|
&self,
|
||||||
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
|
input: ArrayViewD<'_, T>,
|
||||||
|
config: &Self::Config<T>,
|
||||||
|
context: &mut Context,
|
||||||
|
) where
|
||||||
|
T: Send + Sync + Debug + PartialOrd + PartialEq + Copy + Clone,
|
||||||
|
{
|
||||||
|
let shape = input.shape();
|
||||||
|
if shape.len() == 2 {
|
||||||
|
let data = input.into_dimensionality::<Ix2>().unwrap();
|
||||||
|
let target = self.draw_2d(config, data, dims, context);
|
||||||
|
} else if shape.len() == 3 {
|
||||||
|
let data = input.into_dimensionality::<Ix3>().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MultiLayerGridImp();
|
||||||
|
|
||||||
|
pub struct MultiLayerGridImpConfig<T>
|
||||||
|
where
|
||||||
|
T: PartialOrd + PartialEq + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
twod: GridImp,
|
||||||
|
two_d_config: GridImpConfig<T>,
|
||||||
|
layer: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElementImp for MultiLayerGridImp {
|
||||||
|
type Config<T: Sync + Send + Debug + PartialOrd + PartialEq> = MultiLayerGridImpConfig<T>;
|
||||||
|
|
||||||
|
fn process<T>(
|
||||||
|
&self,
|
||||||
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
|
input: ArrayViewD<'_, T>,
|
||||||
|
config: &Self::Config<T>,
|
||||||
|
context: &mut Context,
|
||||||
|
) where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone,
|
||||||
|
{
|
||||||
|
let data = input.into_dimensionality::<Ix3>().unwrap();
|
||||||
|
let layer = config.layer;
|
||||||
|
let layer_data = data.index_axis(Axis(0), layer);
|
||||||
|
|
||||||
|
config
|
||||||
|
.twod
|
||||||
|
.process(dims, layer_data.into_dyn(), &config.two_d_config, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PolarElementImp();
|
||||||
|
|
||||||
|
pub struct PolarElementConfig<T>
|
||||||
|
where
|
||||||
|
T: PartialOrd + PartialEq + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
color_map: ColorMapperComb<T>,
|
||||||
|
center: (f64, f64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PolarElementImp {
|
||||||
|
fn closest_value(&self, x: f64, dpi: f64) -> f64 {
|
||||||
|
let n_floor = (x / dpi).floor() as i64;
|
||||||
|
let value_at_n_floor = n_floor as f64 * dpi;
|
||||||
|
let value_at_n_floor_plus_one = (n_floor + 1) as f64 * dpi;
|
||||||
|
if (x - value_at_n_floor).abs() < (value_at_n_floor_plus_one - x).abs() {
|
||||||
|
value_at_n_floor
|
||||||
|
} else {
|
||||||
|
value_at_n_floor_plus_one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_to_polar(
|
||||||
|
&self,
|
||||||
|
center: (f64, f64),
|
||||||
|
dpi: (f64, f64),
|
||||||
|
max_r: f64,
|
||||||
|
point: (f64, f64),
|
||||||
|
) -> Option<(f64, f64)> {
|
||||||
|
let (center_lon, center_lat) = center;
|
||||||
|
let (lon, lat) = point;
|
||||||
|
|
||||||
|
let center_lon_rad = center_lon.to_radians();
|
||||||
|
let center_lat_rad = center_lat.to_radians();
|
||||||
|
let lon_rad = lon.to_radians();
|
||||||
|
let lat_rad = lat.to_radians();
|
||||||
|
|
||||||
|
let delta_lat = lat_rad - center_lat_rad;
|
||||||
|
let delta_lon = lon_rad - center_lon_rad;
|
||||||
|
|
||||||
|
let a = (delta_lat / 2.0).sin().powi(2)
|
||||||
|
+ center_lat_rad.cos() * lat_rad.cos() * (delta_lon / 2.0).sin().powi(2);
|
||||||
|
|
||||||
|
let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());
|
||||||
|
|
||||||
|
let distance = EARTH_RADIUS * c * 1000.0;
|
||||||
|
|
||||||
|
if distance > max_r + dpi.1 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = delta_lon.cos() * lat_rad.sin();
|
||||||
|
let y = center_lat_rad.cos() * lat_rad.sin()
|
||||||
|
- center_lat_rad.sin() * lat_rad.cos() * delta_lon.cos();
|
||||||
|
let ori_degree = y.atan2(x).to_degrees();
|
||||||
|
let degree = (ori_degree + 360.0) % 360.0;
|
||||||
|
|
||||||
|
let distance_dpi = dpi.1;
|
||||||
|
let degree_dpi = dpi.0;
|
||||||
|
let final_degree = self.closest_value(degree, degree_dpi);
|
||||||
|
let final_distance = self.closest_value(distance, distance_dpi);
|
||||||
|
Some((final_degree, final_distance))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw<T>(
|
||||||
|
&self,
|
||||||
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
|
center: (f64, f64),
|
||||||
|
data: ArrayView2<T>,
|
||||||
|
config: &PolarElementConfig<T>,
|
||||||
|
context: &mut Context,
|
||||||
|
) where
|
||||||
|
T: PartialOrd + PartialEq + Send + Sync + Debug + Copy,
|
||||||
|
{
|
||||||
|
let canvas = &mut context.canvas;
|
||||||
|
let mapper = &context.cms;
|
||||||
|
let start_point = mapper.fore_map((0.0, 0.0));
|
||||||
|
|
||||||
|
let dpi = (
|
||||||
|
dims.0[[0, 1]] - dims.0[[0, 0]],
|
||||||
|
dims.1[[1, 1]] - dims.1[[1, 0]],
|
||||||
|
);
|
||||||
|
|
||||||
|
let (azs, rs) = dims;
|
||||||
|
|
||||||
|
let (w, h) = (canvas.width(), canvas.height());
|
||||||
|
|
||||||
|
for x in 0..w {
|
||||||
|
for y in 0..h {
|
||||||
|
let map_point = mapper.fore_map((x as f32 / w as f32, y as f32 / h as f32));
|
||||||
|
if map_point.is_none() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some((_x, _y)) = self.map_to_polar(center, dpi, 0.0, map_point.unwrap()) {
|
||||||
|
let (_x, _y) = (_x as usize, _y as usize);
|
||||||
|
let value = data[[_x, _y]];
|
||||||
|
let color = config.color_map.color(value);
|
||||||
|
|
||||||
|
if color.is_none() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut path = Path::new();
|
||||||
|
path.rect(x as f32, y as f32, 1.0, 1.0);
|
||||||
|
canvas.fill_path(&path, &Paint::color(color.unwrap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElementImp for PolarElementImp {
|
||||||
|
type Config<T: Sync + Send + Debug + PartialOrd + PartialEq> = PolarElementConfig<T>;
|
||||||
|
fn process<T>(
|
||||||
|
&self,
|
||||||
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
|
input: ArrayViewD<'_, T>,
|
||||||
|
config: &Self::Config<T>,
|
||||||
|
context: &mut Context,
|
||||||
|
) where
|
||||||
|
T: Sync + Send + Debug + PartialOrd + PartialEq + Copy + Clone,
|
||||||
|
{
|
||||||
|
let shape = input.shape();
|
||||||
|
if shape.len() == 2 {
|
||||||
|
let data = input.into_dimensionality::<Ix2>().unwrap();
|
||||||
|
self.draw(dims, config.center, data, config, context);
|
||||||
|
} else if shape.len() == 3 {
|
||||||
|
let data = input.into_dimensionality::<Ix3>().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ElementImpl {
|
||||||
|
Grid(GridImp),
|
||||||
|
MultiLayerGrid(MultiLayerGridImp),
|
||||||
|
Polar(PolarElementImp),
|
||||||
|
}
|
||||||
|
|
||||||
|
for_all_variants!(impl_element_into_dispatch);
|
||||||
|
for_all_variants!(impl_element_try_from_dispatch);
|
||||||
|
for_all_variants!(impl_element_imp_dispatch);
|
||||||
@ -1,14 +1,17 @@
|
|||||||
pub mod dispatcher;
|
pub mod dispatcher;
|
||||||
pub mod element;
|
pub mod element;
|
||||||
mod element_impl;
|
// mod element_impl;
|
||||||
|
// mod new_element;
|
||||||
|
// mod new_element_impl;
|
||||||
mod new_pipeline;
|
mod new_pipeline;
|
||||||
pub mod offscreen_renderer;
|
pub mod offscreen_renderer;
|
||||||
mod predefined;
|
// mod predefined;
|
||||||
|
pub mod element_imp;
|
||||||
mod renders;
|
mod renders;
|
||||||
pub mod utils;
|
// pub mod utils;
|
||||||
|
|
||||||
pub use dispatcher::Dispatcher;
|
pub use dispatcher::Dispatcher;
|
||||||
pub use element::*;
|
pub use element::*;
|
||||||
pub use element_impl::*;
|
// pub use element_impl::*;
|
||||||
pub use new_pipeline::Pipeline;
|
pub use new_pipeline::Pipeline;
|
||||||
pub use offscreen_renderer::OffscreenRenderer;
|
pub use offscreen_renderer::OffscreenRenderer;
|
||||||
|
|||||||
196
src/pipeline/new_element.rs
Normal file
196
src/pipeline/new_element.rs
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
use super::dispatcher;
|
||||||
|
use super::new_element_impl::ElementConfig;
|
||||||
|
use super::new_element_impl::ElementImp;
|
||||||
|
use super::offscreen_renderer::CanvasWrapper;
|
||||||
|
use super::Dispatcher;
|
||||||
|
use super::RenderResult;
|
||||||
|
use super::Target;
|
||||||
|
use crate::coords::cms::CMS;
|
||||||
|
use crate::pipeline::OffscreenRenderer;
|
||||||
|
use crate::PLUGIN_MANAGER;
|
||||||
|
use chrono::prelude::*;
|
||||||
|
use num_traits::AsPrimitive;
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
|
use num_traits::Num;
|
||||||
|
use num_traits::NumOps;
|
||||||
|
use quick_cache::sync::Cache;
|
||||||
|
use radarg_plugin_interface::PluginResult;
|
||||||
|
use std::any::Any;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::hash::Hash;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::sync::atomic::AtomicI32;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::RwLock;
|
||||||
|
use std::time::Duration;
|
||||||
|
use tokio::sync::oneshot;
|
||||||
|
use tokio::sync::{mpsc, Mutex};
|
||||||
|
|
||||||
|
static ELEMENT_ID: AtomicI32 = AtomicI32::new(0);
|
||||||
|
pub type ElementID = i32;
|
||||||
|
pub type Buffer<T> = Cache<T, Arc<Mutex<RenderResult>>>;
|
||||||
|
|
||||||
|
pub struct Element<T: Eq + Hash + Send + Clone + Copy + 'static, V>
|
||||||
|
where
|
||||||
|
V: Num + NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
pub id: i32,
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
imp: Arc<ElementImp<V>>,
|
||||||
|
buffer: Arc<Mutex<Buffer<T>>>,
|
||||||
|
config: Arc<RwLock<Box<ElementConfig>>>,
|
||||||
|
subscribers: Arc<Mutex<HashMap<T, Vec<oneshot::Sender<Arc<Mutex<Vec<u8>>>>>>>>,
|
||||||
|
cancellers: Arc<Mutex<HashMap<T, oneshot::Sender<()>>>>,
|
||||||
|
|
||||||
|
dispatcher: Rc<Dispatcher>,
|
||||||
|
cms: Arc<Mutex<CMS>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Eq + Hash + Send + Clone + Copy + 'static, V> Element<T, V>
|
||||||
|
where
|
||||||
|
V: Num + NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
pub fn new(
|
||||||
|
name: String,
|
||||||
|
description: String,
|
||||||
|
imp: ElementImp<V>,
|
||||||
|
config: Box<ElementConfig>,
|
||||||
|
cms: CMS,
|
||||||
|
dispatcher: Rc<Dispatcher>,
|
||||||
|
) -> Self {
|
||||||
|
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
Element {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
imp: Arc::new(imp),
|
||||||
|
buffer: Arc::new(Mutex::new(Buffer::new(100))),
|
||||||
|
subscribers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
config: Arc::new(RwLock::new(config)),
|
||||||
|
cancellers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
cms: Arc::new(Mutex::new(cms)),
|
||||||
|
dispatcher,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_buffer(
|
||||||
|
name: String,
|
||||||
|
description: String,
|
||||||
|
imp: ElementImp<V>,
|
||||||
|
buffer: Buffer<T>,
|
||||||
|
config: Box<ElementConfig>,
|
||||||
|
cms: CMS,
|
||||||
|
dispatcher: Rc<Dispatcher>,
|
||||||
|
) -> Self {
|
||||||
|
let id = ELEMENT_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
Element {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
imp: Arc::new(imp),
|
||||||
|
buffer: Arc::new(Mutex::new(buffer)),
|
||||||
|
subscribers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
config: Arc::new(RwLock::new(config)),
|
||||||
|
cancellers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
|
cms: Arc::new(Mutex::new(cms)),
|
||||||
|
dispatcher,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get(&self, key: T) -> Arc<Mutex<RenderResult>> {
|
||||||
|
{
|
||||||
|
let cache = self.buffer.lock().await;
|
||||||
|
if cache.peek(&key).is_some() {
|
||||||
|
return cache.get(&key).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut subscribers = self.subscribers.lock().await;
|
||||||
|
let (tx, rx) = oneshot::channel();
|
||||||
|
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, vec![tx]);
|
||||||
|
drop(subscribers);
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut cancellers = self.cancellers.lock().await;
|
||||||
|
cancellers.insert(key, canceller_tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
let buffer = self.buffer.clone();
|
||||||
|
let config = self.config.clone();
|
||||||
|
let imp = self.imp.clone();
|
||||||
|
let cancellers = self.cancellers.clone();
|
||||||
|
let subscribers = self.subscribers.clone();
|
||||||
|
|
||||||
|
use tokio::task;
|
||||||
|
tokio::spawn(async move {
|
||||||
|
tokio::select! {
|
||||||
|
_ = async move {
|
||||||
|
|
||||||
|
tokio::time::sleep(Duration::new(5, 0)).await;
|
||||||
|
let handle = task::spawn_blocking(move || {
|
||||||
|
let config = config.read().unwrap();
|
||||||
|
let config: &ElementConfig = &*(*config);
|
||||||
|
|
||||||
|
let loader = PLUGIN_MANAGER.get_plugin_by_name("etws_loader").unwrap();
|
||||||
|
let mut loaded_data = loader.load(path.as_ref().into()).unwrap();
|
||||||
|
let meta = loaded_data.meta.clone().into();
|
||||||
|
let mut offscreen_renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||||
|
|
||||||
|
// imp.render()
|
||||||
|
});
|
||||||
|
let result = handle.await.unwrap();
|
||||||
|
|
||||||
|
{
|
||||||
|
let bf = Arc::new(Mutex::new(result));
|
||||||
|
buffer.lock().await.insert(key, bf.clone());
|
||||||
|
let mut subscribers = subscribers.lock().await;
|
||||||
|
for tx in subscribers.remove(&key).unwrap() {
|
||||||
|
let _ = tx.send(bf.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} => {}
|
||||||
|
_ = canceller_rx => {}
|
||||||
|
}
|
||||||
|
let mut cancellers = cancellers.lock().await;
|
||||||
|
cancellers.remove(&key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
rx.await.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn cancel_task_for_timestamp(&self, key: T) {
|
||||||
|
let mut cancellers = self.cancellers.lock().await;
|
||||||
|
if let Some(canceller) = cancellers.remove(&key) {
|
||||||
|
let _ = canceller.send(()); // 发送取消信号
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn cancel_all_tasks(&self) {
|
||||||
|
let mut cancellers = self.cancellers.lock().await;
|
||||||
|
for (_timestamp, canceller) in cancellers.drain() {
|
||||||
|
let _ = canceller.send(()); // 发送取消信号
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ElementImpl: Debug + Send + Sync + 'static {
|
||||||
|
type Config;
|
||||||
|
fn render(
|
||||||
|
&self,
|
||||||
|
data: &PluginResult,
|
||||||
|
canvas: &mut CanvasWrapper,
|
||||||
|
cms: &mut CMS,
|
||||||
|
config: &Self::Config,
|
||||||
|
) -> Target;
|
||||||
|
}
|
||||||
104
src/pipeline/new_element_impl.rs
Normal file
104
src/pipeline/new_element_impl.rs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
use super::{
|
||||||
|
new_element::ElementImpl, offscreen_renderer::CanvasWrapper, predefined::GridFieldRenderer,
|
||||||
|
renders::DataRenderer, Target,
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
data::{Radar2d, Radar3d},
|
||||||
|
predefined::color_mapper::{BoundaryNorm, ColorMapper},
|
||||||
|
};
|
||||||
|
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
||||||
|
use radarg_plugin_interface::{DataShape, PluginResult};
|
||||||
|
use std::{any::Any, fmt::Debug, marker::PhantomData};
|
||||||
|
|
||||||
|
macro_rules! create_element_imp {
|
||||||
|
($imp: expr) => {{
|
||||||
|
let c: ElementImp = $imp.into();
|
||||||
|
c
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! element {
|
||||||
|
($generic:ident,$(($branch:tt,$imp:ty)),+) => {
|
||||||
|
pub(super) type ElementConfig = dyn Any + Send + Sync + 'static;
|
||||||
|
|
||||||
|
pub enum ElementImp<$generic>
|
||||||
|
where
|
||||||
|
$generic: NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
$(
|
||||||
|
$branch($imp),
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$generic> ElementImp<$generic>
|
||||||
|
where
|
||||||
|
$generic: Num + NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
pub fn render(
|
||||||
|
&self,
|
||||||
|
data: &PluginResult,
|
||||||
|
canvas: &mut CanvasWrapper,
|
||||||
|
cms: &mut crate::coords::cms::CMS,
|
||||||
|
config: &ElementConfig) -> Target
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
ElementImp::$branch(imp) => imp.render(data,canvas,cms,config.downcast_ref::<<$imp as ElementImpl>::Config>().unwrap()),
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(
|
||||||
|
impl<$generic> From<$imp> for ElementImp<$generic>
|
||||||
|
where
|
||||||
|
$generic: NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
||||||
|
{
|
||||||
|
fn from(imp: $imp) -> Self {
|
||||||
|
ElementImp::$branch(imp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// element!(T, (Grid, GridElementImpl<T>));
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GridElementImpl {}
|
||||||
|
|
||||||
|
impl GridElementImpl {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElementImpl for GridElementImpl {
|
||||||
|
type Config = GridFieldRenderer<BoundaryNorm<T>, T>;
|
||||||
|
fn render(
|
||||||
|
&self,
|
||||||
|
data: &PluginResult,
|
||||||
|
canvas: &mut CanvasWrapper,
|
||||||
|
cms: &mut crate::coords::cms::CMS,
|
||||||
|
config: &Self::Config<T>,
|
||||||
|
) -> super::Target {
|
||||||
|
let first_block = data.blocks.first().unwrap();
|
||||||
|
match first_block.shape {
|
||||||
|
DataShape::Vector => {
|
||||||
|
panic!("Vector data is not supported")
|
||||||
|
}
|
||||||
|
DataShape::Matrix => {
|
||||||
|
let data: Radar2d<T> = first_block.clone().into();
|
||||||
|
let data = data.as_ref();
|
||||||
|
let result = config.render(canvas, cms, &data, (3000.0, 3000.0));
|
||||||
|
result
|
||||||
|
}
|
||||||
|
DataShape::Cube => {
|
||||||
|
let data: Radar3d<T> = first_block.clone().into();
|
||||||
|
let data = data.index_axis(ndarray::Axis(0), 0);
|
||||||
|
let result = config.render(canvas, cms, &data, (3000.0, 3000.0));
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ use super::{
|
|||||||
dispatcher::Dispatcher,
|
dispatcher::Dispatcher,
|
||||||
element::{DataTarget, RenderResult},
|
element::{DataTarget, RenderResult},
|
||||||
offscreen_renderer::{CanvasWrapper, OffscreenRenderer},
|
offscreen_renderer::{CanvasWrapper, OffscreenRenderer},
|
||||||
utils::data_to_element,
|
// utils::data_to_element,
|
||||||
};
|
};
|
||||||
use crate::coords::cms::CMS;
|
use crate::coords::cms::CMS;
|
||||||
use crate::pipeline::element::Target;
|
use crate::pipeline::element::Target;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use super::utils::*;
|
// use super::utils::*;
|
||||||
use crate::pipeline::element::Target;
|
use crate::pipeline::element::Target;
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
|
|||||||
@ -1,117 +1,236 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use femtovg::Color;
|
use femtovg::Color;
|
||||||
|
use image::imageops::ColorMap;
|
||||||
use num_traits::{AsPrimitive, FromPrimitive, NumOps};
|
use num_traits::{AsPrimitive, FromPrimitive, NumOps};
|
||||||
pub trait ColorMapper<T: NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64>>:
|
|
||||||
Debug + Send + Sync
|
|
||||||
{
|
|
||||||
fn map_value_to_color(&self, value: T, invalid: T) -> Option<femtovg::Color>;
|
|
||||||
|
|
||||||
fn map_min_to_max(&self) -> Vec<femtovg::Color>;
|
type BoundaryNormDiscrete<T> = ColorMapper<T, Discrete, BoundaryNorm<T>>;
|
||||||
|
macro_rules! color_mapper_comb {
|
||||||
|
($comb: ident, $($key: tt,)+) => {
|
||||||
|
|
||||||
fn labels(&self) -> Vec<String>;
|
impl<T: PartialEq + PartialOrd + Debug> $comb<T> {
|
||||||
|
|
||||||
fn min_max(&self) -> (T, T);
|
pub fn color(&self, value: T) -> Option<femtovg::Color> {
|
||||||
fn invalid(&self) -> T;
|
match self {
|
||||||
|
$(
|
||||||
|
Self::$key(mapper) => mapper.color(value),
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
pub enum ColorMapperComb<T: PartialEq + PartialOrd + Debug> {
|
||||||
pub struct BoundaryNorm<T: NumOps + PartialOrd> {
|
BoundaryNormDiscrete(BoundaryNormDiscrete<T>),
|
||||||
|
}
|
||||||
|
|
||||||
|
color_mapper_comb!(ColorMapperComb, BoundaryNormDiscrete,);
|
||||||
|
|
||||||
|
pub trait VMap {
|
||||||
|
type Ty;
|
||||||
|
fn map(&self, v: Self::Ty) -> Option<f32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait CMap {
|
||||||
|
fn map(&self, v: f32) -> femtovg::Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ColorMapper<T, CMAP, VMAP>
|
||||||
|
where
|
||||||
|
CMAP: CMap,
|
||||||
|
VMAP: VMap<Ty = T>,
|
||||||
|
{
|
||||||
|
cmap: CMAP,
|
||||||
|
vmap: VMAP,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, CMAP, VMAP> ColorMapper<T, CMAP, VMAP>
|
||||||
|
where
|
||||||
|
T: PartialEq + PartialOrd,
|
||||||
|
CMAP: CMap,
|
||||||
|
VMAP: VMap<Ty = T>,
|
||||||
|
{
|
||||||
|
pub fn new(cmap: CMAP, vmap: VMAP) -> Self {
|
||||||
|
Self { cmap, vmap }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn color(&self, value: T) -> Option<femtovg::Color> {
|
||||||
|
self.vmap.map(value).map(|v| self.cmap.map(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BoundaryNorm<T: PartialOrd + PartialEq> {
|
||||||
boundaries: Vec<T>,
|
boundaries: Vec<T>,
|
||||||
extrand: bool,
|
extrand: bool,
|
||||||
colors: Vec<femtovg::Color>,
|
invalid_value: Option<T>,
|
||||||
invalid_value: T,
|
|
||||||
}
|
}
|
||||||
|
impl<T> VMap for BoundaryNorm<T>
|
||||||
impl Default for BoundaryNorm<i8> {
|
where
|
||||||
fn default() -> Self {
|
T: PartialOrd + PartialEq + Debug,
|
||||||
Self {
|
{
|
||||||
boundaries: vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65],
|
type Ty = T;
|
||||||
extrand: true,
|
fn map(&self, v: Self::Ty) -> Option<f32> {
|
||||||
colors: 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),
|
|
||||||
],
|
|
||||||
invalid_value: -125,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: NumOps + PartialOrd> BoundaryNorm<T> {
|
|
||||||
pub fn new(
|
|
||||||
boundaries: Vec<T>,
|
|
||||||
colors: Vec<femtovg::Color>,
|
|
||||||
extrand: bool,
|
|
||||||
invalid_value: T,
|
|
||||||
) -> Self {
|
|
||||||
// assert_eq!(boundaries.len(), colors.len() + 1);
|
|
||||||
BoundaryNorm {
|
|
||||||
boundaries,
|
|
||||||
extrand,
|
|
||||||
colors,
|
|
||||||
invalid_value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_value_to_color(&self, value: T, invalid_value: T) -> Option<femtovg::Color> {
|
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
if value == invalid_value {
|
if let Some(invalid_value) = &self.invalid_value {
|
||||||
return None;
|
if v == *invalid_value {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, boundary) in self.boundaries.iter().enumerate() {
|
for (i, boundary) in self.boundaries.iter().enumerate() {
|
||||||
if value < *boundary {
|
if v < *boundary {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
index = i;
|
index = i;
|
||||||
}
|
}
|
||||||
index = index.saturating_sub(1).min(self.colors.len() - 1);
|
|
||||||
Some(self.colors[index])
|
Some(index as f32 / self.boundaries.len() as f32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ColorMapper<T> for BoundaryNorm<T>
|
#[derive(Debug)]
|
||||||
where
|
pub struct Gradient {}
|
||||||
T: NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
|
||||||
{
|
|
||||||
fn map_value_to_color(&self, value: T, invalid_value: T) -> Option<femtovg::Color> {
|
|
||||||
self.map_value_to_color(value, invalid_value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn min_max(&self) -> (T, T) {
|
#[derive(Debug)]
|
||||||
(
|
pub struct Discrete {
|
||||||
self.boundaries.first().unwrap().clone(),
|
colors: Vec<femtovg::Color>,
|
||||||
self.boundaries.last().unwrap().clone(),
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn invalid(&self) -> T {
|
impl CMap for Discrete {
|
||||||
self.invalid_value.clone()
|
fn map(&self, v: f32) -> Color {
|
||||||
}
|
let size = (self.colors.len() as f32 * v) as usize;
|
||||||
|
self.colors.get(size).unwrap().clone()
|
||||||
fn map_min_to_max(&self) -> Vec<femtovg::Color> {
|
|
||||||
self.boundaries
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.map_value_to_color(*x, self.invalid_value).unwrap())
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn labels(&self) -> Vec<String> {
|
|
||||||
self.boundaries
|
|
||||||
.iter()
|
|
||||||
.map(|x| format!("{:.2}", x.as_()))
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #[derive(Debug, Clone)]
|
||||||
|
// pub struct BoundaryNorm<T: NumOps + PartialOrd> {
|
||||||
|
// boundaries: Vec<T>,
|
||||||
|
// extrand: bool,
|
||||||
|
// colors: Vec<femtovg::Color>,
|
||||||
|
// invalid_value: T,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl Default for BoundaryNorm<i8> {
|
||||||
|
// fn default() -> Self {
|
||||||
|
// Self {
|
||||||
|
// boundaries: vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65],
|
||||||
|
// extrand: true,
|
||||||
|
// colors: 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),
|
||||||
|
// ],
|
||||||
|
// invalid_value: -125,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl<T: NumOps + PartialOrd> BoundaryNorm<T> {
|
||||||
|
// pub fn new(
|
||||||
|
// boundaries: Vec<T>,
|
||||||
|
// colors: Vec<femtovg::Color>,
|
||||||
|
// extrand: bool,
|
||||||
|
// invalid_value: T,
|
||||||
|
// ) -> Self {
|
||||||
|
// // assert_eq!(boundaries.len(), colors.len() + 1);
|
||||||
|
// BoundaryNorm {
|
||||||
|
// boundaries,
|
||||||
|
// extrand,
|
||||||
|
// colors,
|
||||||
|
// invalid_value,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn map_value_to_color(&self, value: f64, invalid_value: f64) -> Option<femtovg::Color> {
|
||||||
|
// let mut index = 0;
|
||||||
|
// if value == invalid_value {
|
||||||
|
// return None;
|
||||||
|
// }
|
||||||
|
// for (i, boundary) in self.boundaries.iter().enumerate() {
|
||||||
|
// if value < *boundary {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// index = i;
|
||||||
|
// }
|
||||||
|
// index = index.saturating_sub(1).min(self.colors.len() - 1);
|
||||||
|
// Some(self.colors[index])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl<T> ColorMapper for BoundaryNorm<T>
|
||||||
|
// where
|
||||||
|
// T: NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync + Debug,
|
||||||
|
// {
|
||||||
|
//
|
||||||
|
// type Ty<V> = T;
|
||||||
|
// fn map_value_to_color<T>(&self, value: Self::Ty<T>, invalid_value: Self::Ty<T>) -> Option<femtovg::Color> {
|
||||||
|
// self.map_value_to_color(value, invalid_value)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn min_max(&self) -> (f64, f64) {
|
||||||
|
// (
|
||||||
|
// self.boundaries.first().unwrap().clone().as_(),
|
||||||
|
// self.boundaries.last().unwrap().clone().as_(),
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn invalid(&self) -> f64 {
|
||||||
|
// self.invalid_value.clone().as_()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn map_min_to_max(&self) -> Vec<femtovg::Color> {
|
||||||
|
// self.boundaries
|
||||||
|
// .iter()
|
||||||
|
// .map(|x| self.map_value_to_color(*x, self.invalid_value).unwrap())
|
||||||
|
// .collect()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub struct BoundaryNorm();
|
||||||
|
//
|
||||||
|
// impl ColorMapper for BoundaryNorm {
|
||||||
|
// type Ty<T> = T;
|
||||||
|
// fn map_value_to_color<T>(&self, value: Self::Ty<T>, invalid: T) -> Option<femtovg::Color> {
|
||||||
|
// let mut index = 0;
|
||||||
|
// if value == invalid_value {
|
||||||
|
// return None;
|
||||||
|
// }
|
||||||
|
// for (i, boundary) in self.boundaries.iter().enumerate() {
|
||||||
|
// if value < *boundary {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// index = i;
|
||||||
|
// }
|
||||||
|
// index = index.saturating_sub(1).min(self.colors.len() - 1);
|
||||||
|
// Some(self.colors[index])
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn map_min_to_max(&self) -> Vec<femtovg::Color> {
|
||||||
|
// vec![]
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn min_max(&self) -> (f64, f64) {
|
||||||
|
// (0.0, 0.0)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn invalid(&self) -> f64 {
|
||||||
|
// 0.0
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|||||||
514
src/utils.rs
514
src/utils.rs
@ -31,272 +31,272 @@ where
|
|||||||
(xx, yy)
|
(xx, yy)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_dbz_boundarynorm() -> BoundaryNorm<i8> {
|
// pub fn create_dbz_boundarynorm() -> BoundaryNorm<i8> {
|
||||||
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,
|
||||||
],
|
// ],
|
||||||
vec![
|
// vec![
|
||||||
Color::rgb(23, 174, 165),
|
// Color::rgb(23, 174, 165),
|
||||||
Color::rgb(198, 195, 253),
|
// Color::rgb(198, 195, 253),
|
||||||
Color::rgb(124, 114, 236),
|
// Color::rgb(124, 114, 236),
|
||||||
Color::rgb(1, 160, 246),
|
// Color::rgb(1, 160, 246),
|
||||||
Color::rgb(0, 236, 236),
|
// Color::rgb(0, 236, 236),
|
||||||
Color::rgb(0, 216, 0),
|
// Color::rgb(0, 216, 0),
|
||||||
Color::rgb(1, 144, 0),
|
// Color::rgb(1, 144, 0),
|
||||||
Color::rgb(255, 255, 0),
|
// Color::rgb(255, 255, 0),
|
||||||
Color::rgb(231, 192, 0),
|
// Color::rgb(231, 192, 0),
|
||||||
Color::rgb(255, 144, 0),
|
// Color::rgb(255, 144, 0),
|
||||||
Color::rgb(255, 0, 0),
|
// Color::rgb(255, 0, 0),
|
||||||
Color::rgb(214, 0, 0),
|
// Color::rgb(214, 0, 0),
|
||||||
Color::rgb(192, 0, 0),
|
// Color::rgb(192, 0, 0),
|
||||||
Color::rgb(255, 0, 240),
|
// Color::rgb(255, 0, 240),
|
||||||
Color::rgb(150, 0, 180),
|
// Color::rgb(150, 0, 180),
|
||||||
Color::rgb(139, 0, 255),
|
// Color::rgb(139, 0, 255),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125,
|
// -125,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_vel_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_vel_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
vec![
|
// vec![
|
||||||
-35.0, -27.0, -20.0, -15.0, -10.0, -5.0, -1.0, 0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 27.0,
|
// -35.0, -27.0, -20.0, -15.0, -10.0, -5.0, -1.0, 0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 27.0,
|
||||||
35.0,
|
// 35.0,
|
||||||
],
|
// ],
|
||||||
vec![
|
// vec![
|
||||||
Color::rgb(0, 224, 255),
|
// Color::rgb(0, 224, 255),
|
||||||
Color::rgb(0, 128, 255),
|
// Color::rgb(0, 128, 255),
|
||||||
Color::rgb(50, 0, 150),
|
// Color::rgb(50, 0, 150),
|
||||||
Color::rgb(0, 251, 144),
|
// Color::rgb(0, 251, 144),
|
||||||
Color::rgb(0, 187, 144),
|
// Color::rgb(0, 187, 144),
|
||||||
Color::rgb(0, 143, 0),
|
// Color::rgb(0, 143, 0),
|
||||||
Color::rgb(205, 192, 159),
|
// Color::rgb(205, 192, 159),
|
||||||
Color::rgb(255, 255, 255),
|
// Color::rgb(255, 255, 255),
|
||||||
Color::rgb(248, 135, 0),
|
// Color::rgb(248, 135, 0),
|
||||||
Color::rgb(255, 207, 0),
|
// Color::rgb(255, 207, 0),
|
||||||
Color::rgb(255, 255, 0),
|
// Color::rgb(255, 255, 0),
|
||||||
Color::rgb(174, 0, 0),
|
// Color::rgb(174, 0, 0),
|
||||||
Color::rgb(208, 112, 0),
|
// Color::rgb(208, 112, 0),
|
||||||
Color::rgb(255, 0, 0),
|
// Color::rgb(255, 0, 0),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125.0,
|
// -125.0,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_phidp_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_phidp_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
vec![
|
// 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,
|
// 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,
|
// 292.0, 314.0, 359.0,
|
||||||
],
|
// ],
|
||||||
vec![
|
// vec![
|
||||||
Color::rgb(0, 60, 255),
|
// Color::rgb(0, 60, 255),
|
||||||
Color::rgb(0, 239, 239),
|
// Color::rgb(0, 239, 239),
|
||||||
Color::rgb(0, 186, 191),
|
// Color::rgb(0, 186, 191),
|
||||||
Color::rgb(0, 131, 125),
|
// Color::rgb(0, 131, 125),
|
||||||
Color::rgb(0, 137, 56),
|
// Color::rgb(0, 137, 56),
|
||||||
Color::rgb(0, 183, 41),
|
// Color::rgb(0, 183, 41),
|
||||||
Color::rgb(0, 218, 13),
|
// Color::rgb(0, 218, 13),
|
||||||
Color::rgb(0, 255, 0),
|
// Color::rgb(0, 255, 0),
|
||||||
Color::rgb(255, 255, 59),
|
// Color::rgb(255, 255, 59),
|
||||||
Color::rgb(255, 240, 0),
|
// Color::rgb(255, 240, 0),
|
||||||
Color::rgb(255, 198, 0),
|
// Color::rgb(255, 198, 0),
|
||||||
Color::rgb(255, 165, 0),
|
// Color::rgb(255, 165, 0),
|
||||||
Color::rgb(255, 114, 0),
|
// Color::rgb(255, 114, 0),
|
||||||
Color::rgb(255, 31, 0),
|
// Color::rgb(255, 31, 0),
|
||||||
Color::rgb(193, 0, 0),
|
// Color::rgb(193, 0, 0),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125.0,
|
// -125.0,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_zdr_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_zdr_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
vec![
|
// 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,
|
// -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![
|
// vec![
|
||||||
Color::rgb(70, 70, 70),
|
// Color::rgb(70, 70, 70),
|
||||||
Color::rgb(80, 80, 80),
|
// Color::rgb(80, 80, 80),
|
||||||
Color::rgb(90, 90, 90),
|
// Color::rgb(90, 90, 90),
|
||||||
Color::rgb(100, 100, 100),
|
// Color::rgb(100, 100, 100),
|
||||||
Color::rgb(110, 110, 110),
|
// Color::rgb(110, 110, 110),
|
||||||
Color::rgb(120, 120, 120),
|
// Color::rgb(120, 120, 120),
|
||||||
Color::rgb(130, 130, 130),
|
// Color::rgb(130, 130, 130),
|
||||||
Color::rgb(140, 140, 140),
|
// Color::rgb(140, 140, 140),
|
||||||
Color::rgb(150, 150, 150),
|
// Color::rgb(150, 150, 150),
|
||||||
Color::rgb(175, 175, 175),
|
// Color::rgb(175, 175, 175),
|
||||||
Color::rgb(200, 200, 200),
|
// Color::rgb(200, 200, 200),
|
||||||
Color::rgb(220, 240, 220),
|
// Color::rgb(220, 240, 220),
|
||||||
Color::rgb(0, 192, 39),
|
// Color::rgb(0, 192, 39),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125.0,
|
// -125.0,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_cc_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_cc_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
vec![
|
// 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,
|
// 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![
|
// vec![
|
||||||
Color::rgb(0, 60, 255),
|
// Color::rgb(0, 60, 255),
|
||||||
Color::rgb(0, 239, 239),
|
// Color::rgb(0, 239, 239),
|
||||||
Color::rgb(0, 186, 191),
|
// Color::rgb(0, 186, 191),
|
||||||
Color::rgb(0, 131, 125),
|
// Color::rgb(0, 131, 125),
|
||||||
Color::rgb(0, 137, 56),
|
// Color::rgb(0, 137, 56),
|
||||||
Color::rgb(0, 183, 41),
|
// Color::rgb(0, 183, 41),
|
||||||
Color::rgb(0, 218, 13),
|
// Color::rgb(0, 218, 13),
|
||||||
Color::rgb(0, 255, 0),
|
// Color::rgb(0, 255, 0),
|
||||||
Color::rgb(255, 255, 59),
|
// Color::rgb(255, 255, 59),
|
||||||
Color::rgb(255, 240, 0),
|
// Color::rgb(255, 240, 0),
|
||||||
Color::rgb(255, 198, 0),
|
// Color::rgb(255, 198, 0),
|
||||||
Color::rgb(255, 165, 0),
|
// Color::rgb(255, 165, 0),
|
||||||
Color::rgb(255, 114, 0),
|
// Color::rgb(255, 114, 0),
|
||||||
Color::rgb(255, 31, 0),
|
// Color::rgb(255, 31, 0),
|
||||||
Color::rgb(193, 0, 0),
|
// Color::rgb(193, 0, 0),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125.0,
|
// -125.0,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_vil_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_vil_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
vec![
|
// vec![
|
||||||
1.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35., 40., 45., 50., 55., 60., 65., 70.,
|
// 1.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35., 40., 45., 50., 55., 60., 65., 70.,
|
||||||
],
|
// ],
|
||||||
vec![
|
// vec![
|
||||||
Color::rgb(156, 156, 156),
|
// Color::rgb(156, 156, 156),
|
||||||
Color::rgb(118, 118, 118),
|
// Color::rgb(118, 118, 118),
|
||||||
Color::rgb(250, 170, 170),
|
// Color::rgb(250, 170, 170),
|
||||||
Color::rgb(238, 140, 140),
|
// Color::rgb(238, 140, 140),
|
||||||
Color::rgb(201, 112, 112),
|
// Color::rgb(201, 112, 112),
|
||||||
Color::rgb(0, 251, 144),
|
// Color::rgb(0, 251, 144),
|
||||||
Color::rgb(0, 187, 0),
|
// Color::rgb(0, 187, 0),
|
||||||
Color::rgb(255, 255, 112),
|
// Color::rgb(255, 255, 112),
|
||||||
Color::rgb(208, 208, 96),
|
// Color::rgb(208, 208, 96),
|
||||||
Color::rgb(255, 96, 96),
|
// Color::rgb(255, 96, 96),
|
||||||
Color::rgb(218, 0, 0),
|
// Color::rgb(218, 0, 0),
|
||||||
Color::rgb(174, 0, 0),
|
// Color::rgb(174, 0, 0),
|
||||||
Color::rgb(0, 0, 255),
|
// Color::rgb(0, 0, 255),
|
||||||
Color::rgb(255, 255, 255),
|
// Color::rgb(255, 255, 255),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125.0,
|
// -125.0,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_hgt_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_hgt_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
vec![
|
// vec![
|
||||||
0.0, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 11., 12., 14., 15., 17., 18., 20., 21.,
|
// 0.0, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 11., 12., 14., 15., 17., 18., 20., 21.,
|
||||||
],
|
// ],
|
||||||
vec![
|
// vec![
|
||||||
Color::rgb(0, 0, 0),
|
// Color::rgb(0, 0, 0),
|
||||||
Color::rgb(118, 118, 118),
|
// Color::rgb(118, 118, 118),
|
||||||
Color::rgb(0, 224, 255),
|
// Color::rgb(0, 224, 255),
|
||||||
Color::rgb(0, 176, 255),
|
// Color::rgb(0, 176, 255),
|
||||||
Color::rgb(0, 144, 204),
|
// Color::rgb(0, 144, 204),
|
||||||
Color::rgb(50, 0, 150),
|
// Color::rgb(50, 0, 150),
|
||||||
Color::rgb(0, 251, 144),
|
// Color::rgb(0, 251, 144),
|
||||||
Color::rgb(0, 187, 0),
|
// Color::rgb(0, 187, 0),
|
||||||
Color::rgb(0, 239, 0),
|
// Color::rgb(0, 239, 0),
|
||||||
Color::rgb(254, 191, 0),
|
// Color::rgb(254, 191, 0),
|
||||||
Color::rgb(255, 255, 0),
|
// Color::rgb(255, 255, 0),
|
||||||
Color::rgb(174, 0, 0),
|
// Color::rgb(174, 0, 0),
|
||||||
Color::rgb(255, 0, 0),
|
// Color::rgb(255, 0, 0),
|
||||||
Color::rgb(255, 255, 255),
|
// Color::rgb(255, 255, 255),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125.0,
|
// -125.0,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_et_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_et_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
vec![
|
// 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,
|
// 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,
|
// 18.0, 20.0, 21.0,
|
||||||
],
|
// ],
|
||||||
vec![
|
// vec![
|
||||||
Color::rgb(204, 253, 255),
|
// Color::rgb(204, 253, 255),
|
||||||
Color::rgb(153, 248, 255),
|
// Color::rgb(153, 248, 255),
|
||||||
Color::rgb(101, 239, 255),
|
// Color::rgb(101, 239, 255),
|
||||||
Color::rgb(50, 227, 255),
|
// Color::rgb(50, 227, 255),
|
||||||
Color::rgb(134, 255, 134),
|
// Color::rgb(134, 255, 134),
|
||||||
Color::rgb(80, 255, 80),
|
// Color::rgb(80, 255, 80),
|
||||||
Color::rgb(0, 241, 1),
|
// Color::rgb(0, 241, 1),
|
||||||
Color::rgb(0, 187, 0),
|
// Color::rgb(0, 187, 0),
|
||||||
Color::rgb(255, 255, 84),
|
// Color::rgb(255, 255, 84),
|
||||||
Color::rgb(255, 240, 0),
|
// Color::rgb(255, 240, 0),
|
||||||
Color::rgb(255, 191, 0),
|
// Color::rgb(255, 191, 0),
|
||||||
Color::rgb(255, 168, 0),
|
// Color::rgb(255, 168, 0),
|
||||||
Color::rgb(255, 89, 89),
|
// Color::rgb(255, 89, 89),
|
||||||
Color::rgb(255, 64, 64),
|
// Color::rgb(255, 64, 64),
|
||||||
Color::rgb(255, 13, 13),
|
// Color::rgb(255, 13, 13),
|
||||||
Color::rgb(237, 0, 0),
|
// Color::rgb(237, 0, 0),
|
||||||
Color::rgb(205, 0, 0),
|
// Color::rgb(205, 0, 0),
|
||||||
Color::rgb(139, 0, 0),
|
// Color::rgb(139, 0, 0),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-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],
|
||||||
vec![
|
// vec![
|
||||||
Color::rgb(201, 196, 191),
|
// Color::rgb(201, 196, 191),
|
||||||
Color::rgb(112, 188, 73),
|
// Color::rgb(112, 188, 73),
|
||||||
Color::rgb(245, 163, 110),
|
// Color::rgb(245, 163, 110),
|
||||||
Color::rgb(208, 119, 52),
|
// Color::rgb(208, 119, 52),
|
||||||
Color::rgb(234, 37, 47),
|
// Color::rgb(234, 37, 47),
|
||||||
Color::rgb(199, 53, 47),
|
// Color::rgb(199, 53, 47),
|
||||||
Color::rgb(145, 71, 152),
|
// Color::rgb(145, 71, 152),
|
||||||
Color::rgb(178, 177, 65),
|
// Color::rgb(178, 177, 65),
|
||||||
Color::rgb(103, 199, 208),
|
// Color::rgb(103, 199, 208),
|
||||||
Color::rgb(55, 90, 165),
|
// Color::rgb(55, 90, 165),
|
||||||
Color::rgb(187, 165, 204),
|
// Color::rgb(187, 165, 204),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125,
|
// -125,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_kdp_boundarynorm() -> BoundaryNorm<f32> {
|
// pub fn create_kdp_boundarynorm() -> BoundaryNorm<f32> {
|
||||||
BoundaryNorm::new(
|
// BoundaryNorm::new(
|
||||||
vec![
|
// 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,
|
// -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![
|
// vec![
|
||||||
Color::rgb(0, 255, 255),
|
// Color::rgb(0, 255, 255),
|
||||||
Color::rgb(0, 239, 239),
|
// Color::rgb(0, 239, 239),
|
||||||
Color::rgb(0, 168, 172),
|
// Color::rgb(0, 168, 172),
|
||||||
Color::rgb(180, 180, 180),
|
// Color::rgb(180, 180, 180),
|
||||||
Color::rgb(180, 180, 180),
|
// Color::rgb(180, 180, 180),
|
||||||
Color::rgb(0, 192, 39),
|
// Color::rgb(0, 192, 39),
|
||||||
Color::rgb(0, 232, 10),
|
// Color::rgb(0, 232, 10),
|
||||||
Color::rgb(36, 255, 36),
|
// Color::rgb(36, 255, 36),
|
||||||
Color::rgb(255, 255, 30),
|
// Color::rgb(255, 255, 30),
|
||||||
Color::rgb(255, 230, 0),
|
// Color::rgb(255, 230, 0),
|
||||||
Color::rgb(255, 188, 0),
|
// Color::rgb(255, 188, 0),
|
||||||
Color::rgb(255, 152, 0),
|
// Color::rgb(255, 152, 0),
|
||||||
Color::rgb(255, 94, 0),
|
// Color::rgb(255, 94, 0),
|
||||||
Color::rgb(242, 15, 0),
|
// Color::rgb(242, 15, 0),
|
||||||
Color::rgb(187, 0, 58),
|
// Color::rgb(187, 0, 58),
|
||||||
Color::rgb(253, 6, 253),
|
// Color::rgb(253, 6, 253),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
-125.0,
|
// -125.0,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn estimate_zoom_level(
|
pub fn estimate_zoom_level(
|
||||||
lat_min: f64,
|
lat_min: f64,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user