three d
This commit is contained in:
parent
09b7e83669
commit
cd4c46f9c6
@ -89,15 +89,24 @@ impl Plugin for ETWSLoader {
|
||||
CoordType::Other
|
||||
};
|
||||
|
||||
let lat = b.info.dimension_values.get(0).unwrap();
|
||||
let lon = b.info.dimension_values.get(1).unwrap();
|
||||
lat_range = [lat[0], lat[lat.len() - 1]];
|
||||
lon_range = [lon[0], lon[lon.len() - 1]];
|
||||
|
||||
|
||||
let shape = match b.info.dimension_size.len() {
|
||||
1 => radarg_plugin_interface::DataShape::Vector,
|
||||
2 => radarg_plugin_interface::DataShape::Matrix,
|
||||
_ => radarg_plugin_interface::DataShape::Scalar,
|
||||
2 => {
|
||||
let lat = b.info.dimension_values.get(0).unwrap();
|
||||
let lon = b.info.dimension_values.get(1).unwrap();
|
||||
lat_range = [lat[0], lat[lat.len() - 1]];
|
||||
lon_range = [lon[0], lon[lon.len() - 1]];
|
||||
radarg_plugin_interface::DataShape::Matrix
|
||||
},
|
||||
_ => {
|
||||
let lat = b.info.dimension_values.get(1).unwrap();
|
||||
let lon = b.info.dimension_values.get(2).unwrap();
|
||||
lat_range = [lat[0], lat[lat.len() - 1]];
|
||||
lon_range = [lon[0], lon[lon.len() - 1]];
|
||||
radarg_plugin_interface::DataShape::Cube
|
||||
},
|
||||
};
|
||||
|
||||
let data_type = match b.info.value_name.as_str() {
|
||||
@ -115,6 +124,7 @@ impl Plugin for ETWSLoader {
|
||||
"HCA" => PluginResultType::HCA,
|
||||
"QPE" => PluginResultType::QPE,
|
||||
"QPF" => PluginResultType::QPF,
|
||||
"FR" => PluginResultType::DBZ,
|
||||
_ => PluginResultType::Unknown,
|
||||
};
|
||||
|
||||
@ -187,7 +197,7 @@ mod tests {
|
||||
|
||||
fn test() {
|
||||
let result =
|
||||
Record::parse_from_path("/Volumes/data2/RadarArray/HangZhou/radarData/OutputProducts/RadarProducts/BasicProductsX/20230624/20230624000800/ZJHZAA_20230624000800_VIL.dat.gz")
|
||||
Record::parse_from_path("/Volumes/data2/RadarArray/HangZhou/radarData/OutputProducts/RadarProducts/FuseDataX/20220727/ZJHZAA_20220727200000_FR.dat.gz")
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
{"rustc_fingerprint":13002805757961277866,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.75.0 (82e1608df 2023-12-21)\nbinary: rustc\ncommit-hash: 82e1608dfa6e0b5569232559e3d385fea5a93112\ncommit-date: 2023-12-21\nhost: x86_64-pc-windows-msvc\nrelease: 1.75.0\nLLVM version: 17.0.6\n","stderr":""},"4287340858553847514":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\qwin7\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""}},"successes":{}}
|
||||
{"rustc_fingerprint":6534886339914138005,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.77.0-nightly (d78329b92 2024-01-13)\nbinary: rustc\ncommit-hash: d78329b92e8d141d19505e7c1527181c4ab87ed4\ncommit-date: 2024-01-13\nhost: aarch64-apple-darwin\nrelease: 1.77.0-nightly\nLLVM version: 17.0.6\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/tsuki/.rustup/toolchains/nightly-aarch64-apple-darwin\noff\npacked\nunpacked\n___\ndebug_assertions\noverflow_checks\npanic=\"unwind\"\nproc_macro\nrelocation_model=\"pic\"\ntarget_abi=\"\"\ntarget_arch=\"aarch64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"aes\"\ntarget_feature=\"crc\"\ntarget_feature=\"dit\"\ntarget_feature=\"dotprod\"\ntarget_feature=\"dpb\"\ntarget_feature=\"dpb2\"\ntarget_feature=\"fcma\"\ntarget_feature=\"fhm\"\ntarget_feature=\"flagm\"\ntarget_feature=\"fp16\"\ntarget_feature=\"frintts\"\ntarget_feature=\"jsconv\"\ntarget_feature=\"lor\"\ntarget_feature=\"lse\"\ntarget_feature=\"neon\"\ntarget_feature=\"paca\"\ntarget_feature=\"pacg\"\ntarget_feature=\"pan\"\ntarget_feature=\"pmuv3\"\ntarget_feature=\"ras\"\ntarget_feature=\"rcpc\"\ntarget_feature=\"rcpc2\"\ntarget_feature=\"rdm\"\ntarget_feature=\"sb\"\ntarget_feature=\"sha2\"\ntarget_feature=\"sha3\"\ntarget_feature=\"ssbs\"\ntarget_feature=\"v8.1a\"\ntarget_feature=\"v8.2a\"\ntarget_feature=\"v8.3a\"\ntarget_feature=\"v8.4a\"\ntarget_feature=\"vh\"\ntarget_has_atomic\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_has_atomic_equal_alignment=\"128\"\ntarget_has_atomic_equal_alignment=\"16\"\ntarget_has_atomic_equal_alignment=\"32\"\ntarget_has_atomic_equal_alignment=\"64\"\ntarget_has_atomic_equal_alignment=\"8\"\ntarget_has_atomic_equal_alignment=\"ptr\"\ntarget_has_atomic_load_store\ntarget_has_atomic_load_store=\"128\"\ntarget_has_atomic_load_store=\"16\"\ntarget_has_atomic_load_store=\"32\"\ntarget_has_atomic_load_store=\"64\"\ntarget_has_atomic_load_store=\"8\"\ntarget_has_atomic_load_store=\"ptr\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"apple\"\nunix\n","stderr":""}},"successes":{}}
|
||||
Binary file not shown.
@ -1 +1 @@
|
||||
ee6a7bacac3da619
|
||||
16f3840281ed1c0f
|
||||
@ -1 +1 @@
|
||||
{"rustc":10493413842677104517,"features":"[]","target":8454914719411586997,"profile":14094339167972473758,"path":17523903030608720598,"deps":[[3470807962260834726,"serde",false,4400031724788451666],[6147374319788932929,"serde_json",false,16164065312130377423],[6644485573429891122,"thiserror",false,18258125545593472374],[6954241390595330609,"nom",false,598865438637657466],[8926101378076943148,"byteorder",false,15440310884809793591],[8944703748776155531,"chrono",false,8244302838404386295],[10043922549268360936,"radarg_plugin_interface",false,14403560275837773923],[11138931377059941435,"num_traits",false,2394100724493043844],[12701726091060201577,"abi_stable",false,15910410634281474657],[12732307821348191974,"anyhow",false,3836683591027896962],[12935855096716563853,"flate2",false,15712347804304961314],[16098302879908240583,"nom_derive",false,43989377100278263]],"local":[{"CheckDepInfo":{"dep_info":"release\\.fingerprint\\etws_loader-826e392dbec97b5d\\dep-lib-etws_loader"}}],"rustflags":["-C","link-args=/LIBPATH:C:\\gtk-build\\gtk\\x64\\release\\lib\\"],"metadata":41698518999418921,"config":2202906307356721367,"compile_kind":0}
|
||||
{"rustc":17942353898403517573,"features":"[]","declared_features":"","target":8454914719411586997,"profile":14094339167972473758,"path":17523903030608720598,"deps":[[3470807962260834726,"serde",false,3464438898850424389],[6147374319788932929,"serde_json",false,4018346002534341099],[6644485573429891122,"thiserror",false,15376366722783231122],[6954241390595330609,"nom",false,17004332135801955629],[8926101378076943148,"byteorder",false,6029042559770906212],[8944703748776155531,"chrono",false,14085117952510397354],[10043922549268360936,"radarg_plugin_interface",false,2929903515477199145],[11138931377059941435,"num_traits",false,16208028648554347177],[12701726091060201577,"abi_stable",false,46919867052192855],[12732307821348191974,"anyhow",false,13132421988549874417],[12935855096716563853,"flate2",false,9880693184163145737],[16098302879908240583,"nom_derive",false,9783335926581460414]],"local":[{"CheckDepInfo":{"dep_info":"release/.fingerprint/etws_loader-826e392dbec97b5d/dep-lib-etws_loader"}}],"rustflags":[],"metadata":41698518999418921,"config":2202906307356721367,"compile_kind":0}
|
||||
@ -1,6 +1,6 @@
|
||||
{"message":"unused imports: `Write`, `self`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"src\\parser.rs","byte_start":335,"byte_end":339,"line_start":13,"line_end":13,"column_start":15,"column_end":19,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":15,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src\\parser.rs","byte_start":347,"byte_end":352,"line_start":13,"line_end":13,"column_start":27,"column_end":32,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":27,"highlight_end":32}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_imports)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"remove the unused imports","code":null,"level":"help","spans":[{"file_name":"src\\parser.rs","byte_start":335,"byte_end":341,"line_start":13,"line_end":13,"column_start":15,"column_end":21,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":15,"highlight_end":21}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"src\\parser.rs","byte_start":345,"byte_end":352,"line_start":13,"line_end":13,"column_start":25,"column_end":32,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":25,"highlight_end":32}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;11mwarning\u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15m: unused imports: `Write`, `self`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m--> \u001b[0m\u001b[0msrc\\parser.rs:13:15\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14m13\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\u001b[0m \u001b[0m\u001b[0muse std::io::{self, Read, Write};\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11m^^^^^\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m= \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15mnote\u001b[0m\u001b[0m: `#[warn(unused_imports)]` on by default\u001b[0m\n\n"}
|
||||
{"message":"unused variable: `hlen2`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src\\parser.rs","byte_start":6848,"byte_end":6853,"line_start":198,"line_end":198,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":" let (input, hlen2) = Self::_parse_u32(input, order)?;","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_variables)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src\\parser.rs","byte_start":6848,"byte_end":6853,"line_start":198,"line_end":198,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":" let (input, hlen2) = Self::_parse_u32(input, order)?;","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":"_hlen2","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;11mwarning\u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15m: unused variable: `hlen2`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m--> \u001b[0m\u001b[0msrc\\parser.rs:198:21\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14m198\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let (input, hlen2) = Self::_parse_u32(input, order)?;\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11m^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11mhelp: if this is intentional, prefix it with an underscore: `_hlen2`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m= \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15mnote\u001b[0m\u001b[0m: `#[warn(unused_variables)]` on by default\u001b[0m\n\n"}
|
||||
{"message":"unused variable: `order`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src\\parser.rs","byte_start":9313,"byte_end":9318,"line_start":279,"line_end":279,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":" order: Order,","highlight_start":9,"highlight_end":14}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src\\parser.rs","byte_start":9313,"byte_end":9318,"line_start":279,"line_end":279,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":" order: Order,","highlight_start":9,"highlight_end":14}],"label":null,"suggested_replacement":"_order","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;11mwarning\u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15m: unused variable: `order`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m--> \u001b[0m\u001b[0msrc\\parser.rs:279:9\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14m279\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m order: Order,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11m^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11mhelp: if this is intentional, prefix it with an underscore: `_order`\u001b[0m\n\n"}
|
||||
{"message":"unused variable: `dimension_len`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src\\lib.rs","byte_start":1151,"byte_end":1164,"line_start":43,"line_end":43,"column_start":26,"column_end":39,"is_primary":true,"text":[{"text":" let (dimension_len, data) = match b.data {","highlight_start":26,"highlight_end":39}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src\\lib.rs","byte_start":1151,"byte_end":1164,"line_start":43,"line_end":43,"column_start":26,"column_end":39,"is_primary":true,"text":[{"text":" let (dimension_len, data) = match b.data {","highlight_start":26,"highlight_end":39}],"label":null,"suggested_replacement":"_dimension_len","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;11mwarning\u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15m: unused variable: `dimension_len`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m--> \u001b[0m\u001b[0msrc\\lib.rs:43:26\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14m43\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let (dimension_len, data) = match b.data {\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11m^^^^^^^^^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11mhelp: if this is intentional, prefix it with an underscore: `_dimension_len`\u001b[0m\n\n"}
|
||||
{"message":"variants `I64` and `U64` are never constructed","code":{"code":"dead_code","explanation":null},"level":"warning","spans":[{"file_name":"src\\parser.rs","byte_start":590,"byte_end":600,"line_start":28,"line_end":28,"column_start":6,"column_end":16,"is_primary":false,"text":[{"text":"enum ValueTypes {","highlight_start":6,"highlight_end":16}],"label":"variants in this enum","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src\\parser.rs","byte_start":608,"byte_end":611,"line_start":29,"line_end":29,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" I64,","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src\\parser.rs","byte_start":648,"byte_end":651,"line_start":33,"line_end":33,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" U64,","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(dead_code)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;11mwarning\u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15m: variants `I64` and `U64` are never constructed\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m--> \u001b[0m\u001b[0msrc\\parser.rs:29:5\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14m28\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\u001b[0m \u001b[0m\u001b[0menum ValueTypes {\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m----------\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14mvariants in this enum\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14m29\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m I64,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11m^^^\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14m...\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;14m33\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m U64,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;11m^^^\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;14m= \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15mnote\u001b[0m\u001b[0m: `#[warn(dead_code)]` on by default\u001b[0m\n\n"}
|
||||
{"message":"5 warnings emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;11mwarning\u001b[0m\u001b[0m\u001b[1m\u001b[38;5;15m: 5 warnings emitted\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused imports: `Write`, `self`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":323,"byte_end":327,"line_start":13,"line_end":13,"column_start":15,"column_end":19,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":15,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":335,"byte_end":340,"line_start":13,"line_end":13,"column_start":27,"column_end":32,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":27,"highlight_end":32}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_imports)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"remove the unused imports","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":323,"byte_end":329,"line_start":13,"line_end":13,"column_start":15,"column_end":21,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":15,"highlight_end":21}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"src/parser.rs","byte_start":333,"byte_end":340,"line_start":13,"line_end":13,"column_start":25,"column_end":32,"is_primary":true,"text":[{"text":"use std::io::{self, Read, Write};","highlight_start":25,"highlight_end":32}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused imports: `Write`, `self`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:13:15\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m13\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0muse std::io::{self, Read, Write};\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(unused_imports)]` on by default\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused variable: `hlen2`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":6651,"byte_end":6656,"line_start":198,"line_end":198,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":" let (input, hlen2) = Self::_parse_u32(input, order)?;","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(unused_variables)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":6651,"byte_end":6656,"line_start":198,"line_end":198,"column_start":21,"column_end":26,"is_primary":true,"text":[{"text":" let (input, hlen2) = Self::_parse_u32(input, order)?;","highlight_start":21,"highlight_end":26}],"label":null,"suggested_replacement":"_hlen2","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `hlen2`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:198:21\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m198\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let (input, hlen2) = Self::_parse_u32(input, order)?;\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_hlen2`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(unused_variables)]` on by default\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused variable: `order`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":9035,"byte_end":9040,"line_start":279,"line_end":279,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":" order: Order,","highlight_start":9,"highlight_end":14}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/parser.rs","byte_start":9035,"byte_end":9040,"line_start":279,"line_end":279,"column_start":9,"column_end":14,"is_primary":true,"text":[{"text":" order: Order,","highlight_start":9,"highlight_end":14}],"label":null,"suggested_replacement":"_order","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `order`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:279:9\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m279\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m order: Order,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_order`\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"unused variable: `dimension_len`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"src/lib.rs","byte_start":1109,"byte_end":1122,"line_start":43,"line_end":43,"column_start":26,"column_end":39,"is_primary":true,"text":[{"text":" let (dimension_len, data) = match b.data {","highlight_start":26,"highlight_end":39}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"src/lib.rs","byte_start":1109,"byte_end":1122,"line_start":43,"line_end":43,"column_start":26,"column_end":39,"is_primary":true,"text":[{"text":" let (dimension_len, data) = match b.data {","highlight_start":26,"highlight_end":39}],"label":null,"suggested_replacement":"_dimension_len","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused variable: `dimension_len`\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/lib.rs:43:26\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m43\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let (dimension_len, data) = match b.data {\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^^^^^^^^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33mhelp: if this is intentional, prefix it with an underscore: `_dimension_len`\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"variants `I64` and `U64` are never constructed","code":{"code":"dead_code","explanation":null},"level":"warning","spans":[{"file_name":"src/parser.rs","byte_start":563,"byte_end":573,"line_start":28,"line_end":28,"column_start":6,"column_end":16,"is_primary":false,"text":[{"text":"enum ValueTypes {","highlight_start":6,"highlight_end":16}],"label":"variants in this enum","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":580,"byte_end":583,"line_start":29,"line_end":29,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" I64,","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"src/parser.rs","byte_start":616,"byte_end":619,"line_start":33,"line_end":33,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" U64,","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`#[warn(dead_code)]` on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: variants `I64` and `U64` are never constructed\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0msrc/parser.rs:29:5\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m28\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0menum ValueTypes {\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m----------\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12mvariants in this enum\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m29\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m I64,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m...\u001b[0m\n\u001b[0m\u001b[1m\u001b[38;5;12m33\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m U64,\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[33m^^^\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0m\u001b[1mnote\u001b[0m\u001b[0m: `#[warn(dead_code)]` on by default\u001b[0m\n\n"}
|
||||
{"$message_type":"diagnostic","message":"5 warnings emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: 5 warnings emitted\u001b[0m\n\n"}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
C:\Users\qwin7\Desktop\radar-g\etws_loader\target\release\deps\etws_loader.dll: src\lib.rs src\error.rs src\parser.rs
|
||||
/Users/tsuki/projects/radar-g/etws_loader/target/release/deps/libetws_loader.dylib: src/lib.rs src/error.rs src/parser.rs
|
||||
|
||||
C:\Users\qwin7\Desktop\radar-g\etws_loader\target\release\deps\libetws_loader.rlib: src\lib.rs src\error.rs src\parser.rs
|
||||
/Users/tsuki/projects/radar-g/etws_loader/target/release/deps/libetws_loader.rlib: src/lib.rs src/error.rs src/parser.rs
|
||||
|
||||
C:\Users\qwin7\Desktop\radar-g\etws_loader\target\release\deps\etws_loader.d: src\lib.rs src\error.rs src\parser.rs
|
||||
/Users/tsuki/projects/radar-g/etws_loader/target/release/deps/etws_loader.d: src/lib.rs src/error.rs src/parser.rs
|
||||
|
||||
src\lib.rs:
|
||||
src\error.rs:
|
||||
src\parser.rs:
|
||||
src/lib.rs:
|
||||
src/error.rs:
|
||||
src/parser.rs:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
C:\Users\qwin7\Desktop\radar-g\etws_loader\target\release\libetws_loader.rlib: C:\Users\qwin7\Desktop\radar-g\etws_loader\src\error.rs C:\Users\qwin7\Desktop\radar-g\etws_loader\src\lib.rs C:\Users\qwin7\Desktop\radar-g\etws_loader\src\parser.rs C:\Users\qwin7\Desktop\radar-g\radarg_plugin_interface\src\error.rs C:\Users\qwin7\Desktop\radar-g\radarg_plugin_interface\src\lib.rs
|
||||
/Users/tsuki/projects/radar-g/etws_loader/target/release/libetws_loader.dylib: /Users/tsuki/projects/radar-g/etws_loader/src/error.rs /Users/tsuki/projects/radar-g/etws_loader/src/lib.rs /Users/tsuki/projects/radar-g/etws_loader/src/parser.rs /Users/tsuki/projects/radar-g/radarg_plugin_interface/src/error.rs /Users/tsuki/projects/radar-g/radarg_plugin_interface/src/lib.rs
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
use abi_stable::{
|
||||
std_types::{ RBoxError, RVec},
|
||||
std_types::{RBoxError, RVec},
|
||||
StableAbi,
|
||||
};
|
||||
|
||||
@ -18,7 +18,6 @@ pub enum Error {
|
||||
Many(RVec<Error>),
|
||||
}
|
||||
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
@ -33,15 +32,15 @@ impl Display for Error {
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
Error::Custom(e) => Display::fmt(e, f),
|
||||
Error::Many(list) => {
|
||||
for e in list {
|
||||
writeln!(f, "{}", e)?;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
_ => { Ok(())}
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,9 +50,9 @@ pub enum VecResult {
|
||||
#[derive(StableAbi, Clone, Copy, Debug)]
|
||||
#[sabi(impl_InterfaceType(Sync, Send, Debug))]
|
||||
pub enum DataShape {
|
||||
Scalar,
|
||||
Vector,
|
||||
Matrix,
|
||||
Cube,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
@ -6,8 +6,8 @@ use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt};
|
||||
use relm4::actions::{AccelsPlus, ActionablePlus, RelmAction, RelmActionGroup};
|
||||
use relm4::{ComponentParts, ComponentSender, RelmApp, RelmWidgetExt, SimpleComponent};
|
||||
|
||||
use crate::components::app::{AppModel, AppMsg};
|
||||
use crate::widgets::Layer;
|
||||
use crate::components::app::{AppModel, AppMsg, LayerMsg};
|
||||
use crate::widgets::{AssoElement, Layer};
|
||||
|
||||
relm4::new_action_group!(pub LayerActionGroup, "layer");
|
||||
relm4::new_stateless_action!(pub AddLayerAction, LayerActionGroup, "add");
|
||||
@ -17,12 +17,18 @@ relm4::new_stateless_action!(pub MoveLayerAction, LayerActionGroup, "move");
|
||||
pub fn register_layer_actions<W: AsRef<gtk::Widget>>(widget: W, sender: ComponentSender<AppModel>) {
|
||||
let add_action: RelmAction<AddLayerAction> = {
|
||||
let sender = sender.clone();
|
||||
RelmAction::new_stateless(move |_| sender.input(AppMsg::AddLayer))
|
||||
RelmAction::new_stateless(move |_| {
|
||||
sender.input(AppMsg::LayerManager(LayerMsg::Add(Layer::new(
|
||||
true,
|
||||
"Test".to_string(),
|
||||
AssoElement::Test,
|
||||
))))
|
||||
})
|
||||
};
|
||||
|
||||
let remove_action: RelmAction<RemoveLayerAction> = {
|
||||
let sender = sender.clone();
|
||||
RelmAction::new_stateless(move |_| sender.input(AppMsg::RemoveSelectedLayer))
|
||||
RelmAction::new_stateless(move |_| sender.input(AppMsg::LayerManager(LayerMsg::Remove(0))))
|
||||
};
|
||||
|
||||
let mut group: RelmActionGroup<LayerActionGroup> = RelmActionGroup::new();
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use super::sidebar::SideBarOutputMsg;
|
||||
use super::{
|
||||
control_panel::{ControlPanelInputMsg, ControlPanelModel},
|
||||
messages::{MonitorInputMsg, MonitorOutputMsg},
|
||||
@ -5,7 +6,9 @@ use super::{
|
||||
setting::SettingModel,
|
||||
ControlPanelOutputMsg, TimelineMsg,
|
||||
};
|
||||
use crate::components::sidebar::{SideBarInputMsg, SideBarModel};
|
||||
use crate::pipeline::{GridElementImpl, OffscreenRenderer};
|
||||
use crate::predefined::widgets::ColorBar;
|
||||
use crate::widgets::{AssoElement, DynamicCol};
|
||||
use crate::{
|
||||
actions::register_layer_actions,
|
||||
@ -53,7 +56,6 @@ use std::{
|
||||
use tokio::{sync::oneshot, task};
|
||||
use tracing::{debug, error, info, warn};
|
||||
use tracing_subscriber::fmt::layer;
|
||||
use crate::components::sidebar::{SideBarInputMsg, SideBarModel};
|
||||
|
||||
relm4::new_action_group!(FileActionGroup, "file");
|
||||
relm4::new_stateless_action!(OpenAction, FileActionGroup, "open");
|
||||
@ -61,17 +63,24 @@ pub static FILE_PATH_ROOT: Lazy<Mutex<PathBuf>> = Lazy::new(|| Mutex::new(PathBu
|
||||
|
||||
pub type ElementKey = String;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LayerMsg {
|
||||
Add(Layer),
|
||||
Remove(usize),
|
||||
SwitchToTime(usize),
|
||||
Select(Vec<usize>),
|
||||
RemoveSelected,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AppMsg {
|
||||
CloseRequest,
|
||||
Close,
|
||||
OpenDialog,
|
||||
AddLayer,
|
||||
RemoveSelectedLayer,
|
||||
SwitchToTime(usize),
|
||||
LayerManager(LayerMsg),
|
||||
Layer,
|
||||
NewElement(Element),
|
||||
DeleteElement(ElementKey),
|
||||
NewLayer(Layer),
|
||||
}
|
||||
pub type Buffer = Rc<RefCell<HashMap<String, BTreeMap<DateTime<Utc>, Option<RenderResult>>>>>;
|
||||
type RcDispatcher = Rc<Dispatcher>;
|
||||
@ -90,6 +99,7 @@ pub struct AppModel {
|
||||
render: Controller<MonitorModel>,
|
||||
#[do_not_track]
|
||||
sidebar: Controller<SideBarModel>,
|
||||
selected_layer: Vec<usize>,
|
||||
#[do_not_track]
|
||||
layers: Rc<RefCell<Vec<Layer>>>,
|
||||
#[do_not_track]
|
||||
@ -214,7 +224,7 @@ impl Component for AppModel {
|
||||
) -> ComponentParts<Self> {
|
||||
let layers = Rc::new(RefCell::new(vec![
|
||||
Layer::new(true, "Layer 1".to_string(), AssoElement::Test),
|
||||
Layer::new(true, "Layer 2".to_string(), AssoElement::Test)
|
||||
Layer::new(true, "Layer 2".to_string(), AssoElement::Test),
|
||||
]));
|
||||
let control = ControlPanelModel::builder().launch(layers.clone()).forward(
|
||||
sender.input_sender(),
|
||||
@ -223,22 +233,28 @@ impl Component for AppModel {
|
||||
},
|
||||
);
|
||||
|
||||
let sidebar = SideBarModel::builder()
|
||||
.launch(layers.clone())
|
||||
.forward(sender.input_sender(), |msg| match msg {
|
||||
_ => AppMsg::Close,
|
||||
});
|
||||
let sidebar =
|
||||
SideBarModel::builder()
|
||||
.launch(layers.clone())
|
||||
.forward(sender.input_sender(), |msg| {
|
||||
AppMsg::LayerManager(match msg {
|
||||
SideBarOutputMsg::SelectLayer(idx) => LayerMsg::Select(idx),
|
||||
SideBarOutputMsg::NewLayer(layer) => LayerMsg::Add(layer),
|
||||
SideBarOutputMsg::SwitchToTimeSeries(idx) => LayerMsg::SwitchToTime(idx),
|
||||
})
|
||||
});
|
||||
let render =
|
||||
MonitorModel::builder()
|
||||
.launch(layers.clone())
|
||||
.forward(sender.input_sender(), |a| match a {
|
||||
MonitorOutputMsg::LayerRenderFinished => AppMsg::Close,
|
||||
MonitorOutputMsg::LayerSwitchToTime(idx) => AppMsg::SwitchToTime(idx),
|
||||
_ => AppMsg::Close,
|
||||
});
|
||||
|
||||
let setting = SettingModel::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |a| AppMsg::Close);
|
||||
|
||||
let mut dispatcher = Rc::new(Dispatcher::new(5, 5, chrono::Duration::minutes(1)));
|
||||
let cms = CMS::new(Mercator::default().into(), (3000.0, 3000.0));
|
||||
|
||||
@ -247,44 +263,51 @@ impl Component for AppModel {
|
||||
let dialog_sidebar_sender = sidebar.sender().clone();
|
||||
let dialog_render_sender = render.sender().clone();
|
||||
OpenDialog::builder()
|
||||
.transient_for_native(&root)
|
||||
.launch(OpenDialogSettings::default())
|
||||
.forward(sender.input_sender(), move |response| match response {
|
||||
OpenDialogResponse::Accept(path) => {
|
||||
*FILE_PATH_ROOT.lock().unwrap() = path.clone();
|
||||
let data = Self::open_file_only(path);
|
||||
let meta: MetaInfo = (&data.meta).clone().into();
|
||||
let (lat_start, lat_end) = meta.lat_range.unwrap();
|
||||
let (lon_start, lon_end) = meta.lon_range.unwrap();
|
||||
let element_impl = plugin_result_impl(&data);
|
||||
let mut renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||
let mut canvas = renderer.create_canvas();
|
||||
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 = DataTarget::new(Some(data), data_target);
|
||||
let element = Element::create_instant(
|
||||
InstantElementDrawerType::Prepared((data_target, element_impl)),
|
||||
dialog_dispatcher.clone(),
|
||||
"ET".to_string(),
|
||||
)
|
||||
.get_instance();
|
||||
let layer =
|
||||
Layer::new(true, "New Layer".to_string(), AssoElement::Instant(element));
|
||||
dialog_sidebar_sender.emit(SideBarInputMsg::AddMetaItems(meta.to_map()));
|
||||
dialog_render_sender.emit(MonitorInputMsg::SetRenderRange(lon_start, lon_end, lat_start, lat_end));
|
||||
AppMsg::NewLayer(layer)
|
||||
}
|
||||
_ => AppMsg::Close,
|
||||
})};
|
||||
.transient_for_native(&root)
|
||||
.launch(OpenDialogSettings::default())
|
||||
.forward(sender.input_sender(), move |response| match response {
|
||||
OpenDialogResponse::Accept(path) => {
|
||||
*FILE_PATH_ROOT.lock().unwrap() = path.clone();
|
||||
let data = Self::open_file_only(path);
|
||||
let meta: MetaInfo = (&data.meta).clone().into();
|
||||
let (lat_start, lat_end) = meta.lat_range.unwrap();
|
||||
let (lon_start, lon_end) = meta.lon_range.unwrap();
|
||||
let element_impl = plugin_result_impl(&data);
|
||||
let mut renderer = OffscreenRenderer::new(3000, 3000).unwrap();
|
||||
let mut canvas = renderer.create_canvas();
|
||||
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 = DataTarget::new(Some(data), data_target);
|
||||
let element = Element::create_instant(
|
||||
InstantElementDrawerType::Prepared((data_target, element_impl)),
|
||||
dialog_dispatcher.clone(),
|
||||
"ET".to_string(),
|
||||
)
|
||||
.get_instance();
|
||||
let layer = Layer::new(
|
||||
true,
|
||||
"New Layer".to_string(),
|
||||
AssoElement::Instant(element),
|
||||
);
|
||||
dialog_sidebar_sender.emit(SideBarInputMsg::AddMetaItems(meta.to_map()));
|
||||
dialog_render_sender.emit(MonitorInputMsg::SetRenderRange(
|
||||
lon_start, lon_end, lat_start, lat_end,
|
||||
));
|
||||
|
||||
AppMsg::LayerManager(LayerMsg::Add(layer))
|
||||
}
|
||||
_ => AppMsg::Close,
|
||||
})
|
||||
};
|
||||
|
||||
let buffer: Buffer = Rc::new(RefCell::new(HashMap::new()));
|
||||
|
||||
let model = AppModel {
|
||||
cms,
|
||||
dispatcher,
|
||||
waiting_for: None,
|
||||
elements: Vec::with_capacity(20),
|
||||
open_dialog: dialog,
|
||||
selected_layer: vec![],
|
||||
sidebar,
|
||||
control,
|
||||
render,
|
||||
@ -318,31 +341,56 @@ impl Component for AppModel {
|
||||
) {
|
||||
self.reset();
|
||||
match msg {
|
||||
AppMsg::NewLayer(layer) => {
|
||||
(*self.layers).borrow_mut().push(layer);
|
||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
||||
}
|
||||
AppMsg::LayerManager(msg) => match msg {
|
||||
LayerMsg::Add(layer) => {
|
||||
(*self.layers).borrow_mut().push(layer);
|
||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
||||
}
|
||||
LayerMsg::SwitchToTime(idx) => {
|
||||
let mut layer = (*self.layers).borrow_mut();
|
||||
let switched_layer = layer.get_mut(idx).unwrap();
|
||||
let asso_element = switched_layer.pop_associated_element();
|
||||
|
||||
if let AssoElement::Instant(e) = asso_element {
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
let cms = self.cms.clone();
|
||||
let (mut series, start_time) = e.to_time_series(dispatcher, cms);
|
||||
switched_layer.set_time(start_time);
|
||||
series.register(start_time).unwrap();
|
||||
let element = Arc::new(Mutex::new(series));
|
||||
switched_layer
|
||||
.set_associated_element(AssoElement::TimeSeries(element.clone()));
|
||||
self.elements.push(element);
|
||||
}
|
||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
||||
}
|
||||
|
||||
LayerMsg::Select(idx) => {
|
||||
self.set_selected_layer(idx);
|
||||
}
|
||||
|
||||
LayerMsg::RemoveSelected => {
|
||||
let mut layer = (*self.layers).borrow_mut();
|
||||
let selected = self.selected_layer.clone();
|
||||
for idx in selected {
|
||||
layer.remove(idx);
|
||||
}
|
||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
||||
}
|
||||
|
||||
LayerMsg::Remove(idx) => {
|
||||
let mut layers = (*self.layers).borrow_mut();
|
||||
let mut layer = layers.remove(idx);
|
||||
if let AssoElement::TimeSeries(e) = layer.pop_associated_element() {
|
||||
let size = Arc::strong_count(&e);
|
||||
}
|
||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
||||
}
|
||||
},
|
||||
AppMsg::CloseRequest => {
|
||||
relm4::main_application().quit();
|
||||
}
|
||||
AppMsg::Close => {}
|
||||
AppMsg::SwitchToTime(idx) => {
|
||||
let mut layer = (*self.layers).borrow_mut();
|
||||
let switched_layer = layer.get_mut(idx).unwrap();
|
||||
let asso_element = switched_layer.pop_associated_element();
|
||||
|
||||
if let AssoElement::Instant(e) = asso_element {
|
||||
let dispatcher = self.dispatcher.clone();
|
||||
let cms = self.cms.clone();
|
||||
let (mut series, start_time) = e.to_time_series(dispatcher, cms);
|
||||
switched_layer.set_time(start_time);
|
||||
series.register(start_time).unwrap();
|
||||
let element = Arc::new(Mutex::new(series));
|
||||
switched_layer.set_associated_element(AssoElement::TimeSeries(element.clone()));
|
||||
self.elements.push(element);
|
||||
}
|
||||
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
|
||||
}
|
||||
AppMsg::OpenDialog => {
|
||||
self.open_dialog.emit(OpenDialogMsg::Open);
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use super::messages::*;
|
||||
use super::thumbnail::{ImgItem, TypedListView};
|
||||
use crate::data::{CoordType, Radar2d, RadarData2d};
|
||||
use crate::plugin_system::init_plugin;
|
||||
use crate::widgets::render::predefined::color_mapper::BoundaryNorm;
|
||||
use crate::predefined::color_mapper::BoundaryNorm;
|
||||
use crate::widgets::render::Layer;
|
||||
use crate::widgets::timeline::{Selection, TimeLine};
|
||||
use abi_stable::std_types::RStr;
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
pub mod app;
|
||||
mod control_panel;
|
||||
mod monitor;
|
||||
pub mod monitor;
|
||||
mod setting;
|
||||
pub mod sidebar;
|
||||
|
||||
|
||||
pub use control_panel::*;
|
||||
pub use monitor::*;
|
||||
|
||||
@ -1,20 +1,12 @@
|
||||
use std::{collections::HashMap, fmt::Debug};
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::{
|
||||
components::app::ElementKey,
|
||||
pipeline::element::ElementID,
|
||||
widgets::{render::Layer, widget::Widget},
|
||||
};
|
||||
use crate::components::monitor::widget::Widget;
|
||||
|
||||
pub enum MonitorInputMsg {
|
||||
RefreshRender,
|
||||
AddWidget(Box<dyn Widget>),
|
||||
RemoveWidget,
|
||||
// AddMetaItem(HashMap<String, String>),
|
||||
// ClearMetaItems,
|
||||
// UpdateMetaItem(HashMap<String, String>),
|
||||
RefreshTiles,
|
||||
// RefreshLayerList,
|
||||
SetRenderRange(f64, f64, f64, f64),
|
||||
ChangeZoom(f64),
|
||||
None,
|
||||
@ -38,10 +30,6 @@ impl Debug for MonitorInputMsg {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MonitorOutputMsg {
|
||||
LayerAdded(usize),
|
||||
LayerRemoved(usize),
|
||||
LayerUpdated(usize),
|
||||
LayerSwitchToTime(usize),
|
||||
LayerRenderFinished,
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
pub mod messages;
|
||||
pub mod monitor;
|
||||
pub mod widget;
|
||||
|
||||
pub use monitor::*;
|
||||
pub use widget::*;
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
use super::messages::{MonitorInputMsg, MonitorOutputMsg};
|
||||
use crate::components::monitor::widget::{Widget, WidgetType};
|
||||
use crate::coords::cms::CMS;
|
||||
use crate::pipeline::offscreen_renderer::OffscreenRenderer;
|
||||
use crate::widgets::predefined::color_mapper::BoundaryNorm;
|
||||
use crate::widgets::predefined::widgets::ColorBar;
|
||||
use crate::predefined::color_mapper::BoundaryNorm;
|
||||
use crate::widgets::render::RenderConfig;
|
||||
use crate::widgets::widget::{Widget, WidgetType};
|
||||
use crate::widgets::WidgetFrame;
|
||||
use crate::{
|
||||
coords::{proj::Mercator, Mapper},
|
||||
|
||||
@ -11,8 +11,8 @@ pub enum WidgetType {
|
||||
}
|
||||
|
||||
pub trait Widget: 'static + Send + Sync {
|
||||
fn opengl_render(&self, canvas: &mut Canvas<OpenGl>, cms: CMS) {}
|
||||
fn cairo_render(&self, canvas: >k::cairo::Context, w: f32, h: f32) {}
|
||||
fn opengl_render(&self, layers: &Vec<Layer>, canvas: &mut Canvas<OpenGl>, cms: CMS) {}
|
||||
fn cairo_render(&self, layers: &Vec<Layer>, canvas: >k::cairo::Context, w: f32, h: f32) {}
|
||||
fn widget_type(&self) -> WidgetType;
|
||||
|
||||
fn size(&self) -> (f32, f32);
|
||||
@ -2,7 +2,8 @@ use super::dispatcher_list::PathItem;
|
||||
use crate::{
|
||||
config::PATH_FORMATS,
|
||||
data::{self, CoordType, Radar2d},
|
||||
widgets::render::{predefined::color_mapper::BoundaryNorm, Layer},
|
||||
predefined::color_mapper::BoundaryNorm,
|
||||
widgets::render::Layer,
|
||||
CONFIG, PLUGIN_MANAGER,
|
||||
};
|
||||
use adw::prelude::*;
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
use crate::actions::*;
|
||||
use gtk::prelude::*;
|
||||
use relm4::{
|
||||
factory::FactoryView,
|
||||
gtk,
|
||||
prelude::{DynamicIndex, FactoryComponent},
|
||||
FactorySender,
|
||||
actions::traits::ActionablePlus, factory::FactoryView, gtk, prelude::*, FactorySender,
|
||||
};
|
||||
|
||||
use super::SideBarInputMsg;
|
||||
@ -40,10 +38,9 @@ impl FactoryComponent for BottomBarModel {
|
||||
|
||||
view! {
|
||||
#[root]
|
||||
gtk::Box{
|
||||
gtk::Button{
|
||||
set_icon_name=self.icon.as_str(),
|
||||
}
|
||||
gtk::Button{
|
||||
set_icon_name=self.icon.as_str(),
|
||||
ActionablePlus::set_stateless_action::<RemoveLayerAction>: &(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -21,11 +21,7 @@ use relm4::{
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
|
||||
use crate::components::app::AppMsg;
|
||||
use crate::{
|
||||
chart::Chart,
|
||||
data::Npz,
|
||||
widgets::render::{predefined::color_mapper::BoundaryNorm, Layer},
|
||||
};
|
||||
use crate::{chart::Chart, predefined::color_mapper::BoundaryNorm, widgets::render::Layer};
|
||||
|
||||
use super::{
|
||||
bottom_bar::BottomBarModel,
|
||||
@ -51,7 +47,7 @@ pub enum SideBarInputMsg {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SideBarOutputMsg {
|
||||
SelectLayer(usize),
|
||||
SelectLayer(Vec<usize>),
|
||||
NewLayer(Layer),
|
||||
SwitchToTimeSeries(usize),
|
||||
}
|
||||
@ -141,8 +137,11 @@ impl SimpleComponent for SideBarModel {
|
||||
list_view_wrapper.selection_model.connect_selection_changed(
|
||||
clone!(@strong sender => move |s,_, _| {
|
||||
let selection = s.selection();
|
||||
let (iter,_) = gtk::BitsetIter::init_first(&selection).unwrap();
|
||||
let positions = iter.collect::<Vec<_>>();
|
||||
|
||||
let (iter, first) = gtk::BitsetIter::init_first(&selection).unwrap();
|
||||
let mut result = vec![first as usize];
|
||||
result.extend(iter.map(|v| v as usize));
|
||||
sender.output(SideBarOutputMsg::SelectLayer(result));
|
||||
}),
|
||||
);
|
||||
// let mut bottom_bar_vec = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
||||
@ -381,7 +380,7 @@ impl RelmListItem for LayerItem {
|
||||
LayerStatus::BindToOtherLayer(idx) => format!("Bind To Layer: {}", idx),
|
||||
});
|
||||
|
||||
status_icon.set_icon_name(Some(match self.status{
|
||||
status_icon.set_icon_name(Some(match self.status {
|
||||
LayerStatus::BindToTime(_) => "timer-filled",
|
||||
LayerStatus::Instance => "timer-filled",
|
||||
LayerStatus::BindToOtherLayer(_) => "timer-filled",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use std::ops::Range;
|
||||
use geo_types::LineString;
|
||||
use crate::coords::Mapper;
|
||||
use geo_types::LineString;
|
||||
use std::ops::Range;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CMS {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use num_traits::AsPrimitive;
|
||||
use num_traits::Num;
|
||||
pub mod cms;
|
||||
pub mod mapper;
|
||||
pub mod proj;
|
||||
pub mod wgs84;
|
||||
pub mod cms;
|
||||
|
||||
pub use mapper::Mapper;
|
||||
// pub use wgs84::LatLonCoord;
|
||||
|
||||
564
src/data/mod.rs
564
src/data/mod.rs
@ -2,18 +2,27 @@ pub mod meta;
|
||||
use crate::errors::DataError;
|
||||
use async_trait::async_trait;
|
||||
pub use meta::MetaInfo;
|
||||
use ndarray::iter::Indices;
|
||||
use ndarray::{
|
||||
s, Array1, Array2, Array3, ArrayBase, DataMut, Dimension, Ix1, Ix2, OwnedRepr, RawDataClone,
|
||||
s, Array, Array1, Array2, Array3, ArrayBase, Axis, DataMut, Dimension, Ix1, Ix2, Ix3,
|
||||
OwnedRepr, RawDataClone, Slice, ViewRepr,
|
||||
};
|
||||
use npyz::{npz::NpzArchive, Deserialize};
|
||||
use num_traits::{AsPrimitive, FromPrimitive, Num};
|
||||
use std::io::{Cursor, Seek};
|
||||
use std::{self, f64::consts::PI, fmt::Debug, io::BufReader, path::Path};
|
||||
use tokio::fs::File;
|
||||
use tokio::io::{self, AsyncReadExt};
|
||||
|
||||
pub type Radar2d<T> = RadarData2d<T, OwnedRepr<T>>;
|
||||
pub type Radar2d<T> = RadarData2d<T, OwnedRepr<T>, OwnedRepr<f64>, OwnedRepr<f64>>;
|
||||
pub type Radar3d<T> = RadarData3d<T, OwnedRepr<T>, OwnedRepr<f64>, OwnedRepr<f64>, OwnedRepr<f64>>;
|
||||
|
||||
pub type Radar2dRef<'a, T> = RadarData2d<T, ViewRepr<&'a T>, ViewRepr<&'a f64>, ViewRepr<&'a f64>>;
|
||||
pub type Radar3dRef<'a, T> =
|
||||
RadarData3d<T, ViewRepr<&'a T>, ViewRepr<&'a f64>, ViewRepr<&'a f64>, ViewRepr<&'a f64>>;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum CoordType {
|
||||
Polar,
|
||||
LatLon,
|
||||
}
|
||||
pub trait MultiDimensionData<T>
|
||||
where
|
||||
T: Num + Clone + PartialEq + PartialOrd,
|
||||
@ -24,248 +33,84 @@ where
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RadarData2d<T, Raw, X = f64, Y = f64, I = Ix1>
|
||||
pub struct RadarData2d<T, Raw, X, Y, I = Ix1>
|
||||
where
|
||||
T: Num + Clone + PartialEq + PartialOrd,
|
||||
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||
X: Num,
|
||||
Y: Num,
|
||||
Raw: ndarray::Data<Elem = T> + ndarray::RawDataClone,
|
||||
X: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Y: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
{
|
||||
pub dim1: ArrayBase<OwnedRepr<X>, I>,
|
||||
pub dim2: ArrayBase<OwnedRepr<Y>, I>,
|
||||
pub dim1: ArrayBase<X, I>,
|
||||
pub dim2: ArrayBase<Y, I>,
|
||||
pub data: ArrayBase<Raw, Ix2>,
|
||||
pub fill_value: T,
|
||||
pub coord_type: CoordType,
|
||||
}
|
||||
|
||||
impl<T, Raw, X, Y, I> Debug for RadarData2d<T, Raw, X, Y, I>
|
||||
impl<T> Radar2d<T>
|
||||
where
|
||||
T: Num + Clone + PartialEq + PartialOrd + Debug,
|
||||
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||
X: Num + Debug,
|
||||
Y: Num + Debug,
|
||||
I: Dimension,
|
||||
T: Num + Clone + PartialEq + PartialOrd,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("RadarData2d")
|
||||
.field("dim1", &self.dim1)
|
||||
.field("dim2", &self.dim2)
|
||||
.field("data", &self.data)
|
||||
.field("fill_value", &self.fill_value)
|
||||
.field("coord_type", &self.coord_type)
|
||||
.finish()
|
||||
pub fn as_ref<'a>(&'a self) -> Radar2dRef<'a, T> {
|
||||
RadarData2d {
|
||||
dim1: self.dim1.view(),
|
||||
dim2: self.dim2.view(),
|
||||
data: self.data.view(),
|
||||
fill_value: self.fill_value.clone(),
|
||||
coord_type: self.coord_type.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Clone + PartialEq + PartialOrd> Radar2d<T> {
|
||||
pub fn load(path: impl AsRef<Path>, meth: impl DataLoader<T, Self>) -> Result<Self, DataError> {
|
||||
Ok(meth.load(path)?)
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct RadarData3d<T, Raw, X, Y, Z, I = Ix1>
|
||||
where
|
||||
T: Num + Clone + PartialEq + PartialOrd,
|
||||
Raw: ndarray::Data<Elem = T> + ndarray::RawDataClone,
|
||||
X: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Y: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Z: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
{
|
||||
pub dim1: ArrayBase<X, I>,
|
||||
pub dim2: ArrayBase<Y, I>,
|
||||
pub dim3: ArrayBase<Z, I>,
|
||||
pub data: ArrayBase<Raw, Ix3>,
|
||||
pub fill_value: T,
|
||||
pub coord_type: CoordType,
|
||||
}
|
||||
|
||||
pub struct RadarData3d<T, X = f64, Y = f64, Z = f64>
|
||||
impl<T, Raw, X, Y, Z> RadarData3d<T, Raw, X, Y, Z>
|
||||
where
|
||||
T: Num,
|
||||
X: Num,
|
||||
Y: Num,
|
||||
Z: Num,
|
||||
T: Num + Clone + PartialEq + PartialOrd,
|
||||
X: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Y: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Z: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Raw: ndarray::Data<Elem = T> + ndarray::RawDataClone,
|
||||
{
|
||||
pub dim1: Array1<X>,
|
||||
pub dim2: Array1<Y>,
|
||||
pub dim3: Array1<Z>,
|
||||
pub data: Array3<T>,
|
||||
}
|
||||
|
||||
impl<T, Raw> RadarData2d<T, Raw>
|
||||
where
|
||||
T: Num + AsPrimitive<f64> + FromPrimitive + Clone + Debug + PartialOrd + PartialEq,
|
||||
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||
{
|
||||
pub fn downsample(&self, output_shape: (usize, usize), meth: DownSampleMeth) -> Radar2d<T> {
|
||||
pub fn index_axis(&self, axis: Axis, slice: usize) -> Radar2dRef<T> {
|
||||
let shape = self.data.shape();
|
||||
assert!(shape[0] > output_shape.0 && shape[1] > output_shape.1);
|
||||
|
||||
if shape[0] == output_shape.0 && shape[1] == output_shape.1 {
|
||||
return Radar2d {
|
||||
dim1: self.dim1.to_owned(),
|
||||
dim2: self.dim2.to_owned(),
|
||||
data: self.data.to_owned(),
|
||||
fill_value: self.fill_value.clone(),
|
||||
coord_type: self.coord_type.clone(),
|
||||
};
|
||||
}
|
||||
|
||||
let scale_x = shape[1] as f64 / output_shape.1 as f64;
|
||||
let scale_y = shape[0] as f64 / output_shape.0 as f64;
|
||||
|
||||
let mut output: Array2<T> = Array2::zeros(output_shape);
|
||||
|
||||
let dim1 = Array1::linspace(
|
||||
*self.dim1.first().unwrap(),
|
||||
*self.dim1.last().unwrap(),
|
||||
output_shape.1,
|
||||
);
|
||||
|
||||
let dim2 = Array1::linspace(
|
||||
*self.dim2.first().unwrap(),
|
||||
*self.dim2.last().unwrap(),
|
||||
output_shape.0,
|
||||
);
|
||||
|
||||
output.iter_mut().enumerate().for_each(|(s, vv)| {
|
||||
let ri = s / output_shape.1;
|
||||
let ci = s % output_shape.1;
|
||||
let src_yf0 = scale_y * ri as f64;
|
||||
let src_yf1 = src_yf0 + scale_y;
|
||||
let src_y0 = src_yf0.floor() as usize;
|
||||
let src_y1 = src_yf1.floor() as usize;
|
||||
let src_xf0 = scale_x * ci as f64;
|
||||
let src_xf1 = src_xf0 + scale_x;
|
||||
let src_x0 = src_xf0.floor() as usize;
|
||||
let src_x1 = src_xf1.floor() as usize;
|
||||
|
||||
match meth {
|
||||
DownSampleMeth::MEAN => {}
|
||||
DownSampleMeth::VAR | DownSampleMeth::STD => self.var(
|
||||
src_yf0, src_yf1, src_xf0, src_xf1, src_y0, src_y1, src_x0, src_x1, vv,
|
||||
),
|
||||
}
|
||||
});
|
||||
|
||||
if let DownSampleMeth::STD = meth {
|
||||
output = output.mapv(|x| T::from_f64(f64::sqrt(x.as_())).unwrap());
|
||||
}
|
||||
|
||||
return Radar2d {
|
||||
println!("shape: {:?}", shape);
|
||||
let dim1 = self.dim1.view();
|
||||
let dim2 = self.dim2.view();
|
||||
let view = self.data.index_axis(axis, slice);
|
||||
RadarData2d {
|
||||
dim1,
|
||||
dim2,
|
||||
data: view,
|
||||
fill_value: self.fill_value.clone(),
|
||||
data: output,
|
||||
coord_type: self.coord_type.clone(),
|
||||
};
|
||||
}
|
||||
|
||||
fn var(
|
||||
&self,
|
||||
src_yf0: f64,
|
||||
src_yf1: f64,
|
||||
src_xf0: f64,
|
||||
src_xf1: f64,
|
||||
src_y0: usize,
|
||||
mut src_y1: usize,
|
||||
src_x0: usize,
|
||||
mut src_x1: usize,
|
||||
row: &mut T,
|
||||
) {
|
||||
let wy0 = 1f64 - (src_yf0 - src_y0 as f64);
|
||||
let mut wy1 = src_yf1 - src_y1 as f64;
|
||||
let wx0 = 1f64 - (src_xf0 - src_x0 as f64);
|
||||
let mut wx1 = src_xf1 - src_x1 as f64;
|
||||
|
||||
if wy1 < f64::EPSILON {
|
||||
wy1 = 1f64;
|
||||
if src_y1 > src_y0 {
|
||||
src_y1 -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if wx1 < f64::EPSILON {
|
||||
wx1 = 1f64;
|
||||
if src_x1 > src_x0 {
|
||||
src_x1 -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mut v_sum: f64 = 0.0;
|
||||
let mut w_sum = 0f64;
|
||||
let mut wv_sum = 0f64;
|
||||
let mut wvv_sum = 0f64;
|
||||
|
||||
for src_y in src_y0..=src_y1 {
|
||||
let wy = if src_y == src_y0 {
|
||||
wy0
|
||||
} else {
|
||||
if src_y == src_y1 {
|
||||
wy1
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
};
|
||||
for src_x in src_x0..=src_x1 {
|
||||
let wx = if src_x == src_x0 {
|
||||
wx0
|
||||
} else {
|
||||
if src_x == src_x1 {
|
||||
wx1
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
};
|
||||
|
||||
let v = self.data[[src_y, src_x]].as_();
|
||||
let w = wx * wy;
|
||||
|
||||
v_sum += v;
|
||||
w_sum += w;
|
||||
wv_sum += w * v;
|
||||
wvv_sum += w * v * v;
|
||||
}
|
||||
|
||||
if w_sum < f64::EPSILON {
|
||||
return;
|
||||
}
|
||||
let v = ((wvv_sum * w_sum - wv_sum * wv_sum) / w_sum / w_sum).clamp(-125f64, 124f64);
|
||||
*row = T::from_f64(v).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn split(&self) -> [RadarData2d<T, ndarray::ViewRepr<&T>>; 4] {
|
||||
let middle_dim1 = self.dim1.len() / 2;
|
||||
let middle_dim2 = self.dim2.len() / 2;
|
||||
|
||||
let lt = self.data.slice(s![..middle_dim1, ..middle_dim2]);
|
||||
let rt = self.data.slice(s![middle_dim1.., ..middle_dim2]);
|
||||
let lb = self.data.slice(s![..middle_dim1, middle_dim2..]);
|
||||
let rb = self.data.slice(s![middle_dim1.., middle_dim2..]);
|
||||
|
||||
return [
|
||||
RadarData2d {
|
||||
dim1: self.dim1.slice(s![..middle_dim1]).to_owned(),
|
||||
dim2: self.dim2.slice(s![..middle_dim2]).to_owned(),
|
||||
data: lt,
|
||||
fill_value: self.fill_value.clone(),
|
||||
coord_type: self.coord_type,
|
||||
},
|
||||
RadarData2d {
|
||||
dim1: self.dim1.slice(s![middle_dim1..]).to_owned(),
|
||||
dim2: self.dim2.slice(s![..middle_dim2]).to_owned(),
|
||||
data: rt,
|
||||
fill_value: self.fill_value.clone(),
|
||||
coord_type: self.coord_type,
|
||||
},
|
||||
RadarData2d {
|
||||
dim1: self.dim1.slice(s![..middle_dim1]).to_owned(),
|
||||
dim2: self.dim2.slice(s![middle_dim2..]).to_owned(),
|
||||
data: lb,
|
||||
fill_value: self.fill_value.clone(),
|
||||
coord_type: self.coord_type,
|
||||
},
|
||||
RadarData2d {
|
||||
dim1: self.dim1.slice(s![middle_dim1..]).to_owned(),
|
||||
dim2: self.dim2.slice(s![middle_dim2..]).to_owned(),
|
||||
data: rb,
|
||||
fill_value: self.fill_value.clone(),
|
||||
coord_type: self.coord_type,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Raw> MultiDimensionData<T> for RadarData2d<T, Raw>
|
||||
impl<T, Raw, X, Y, Z> MultiDimensionData<T> for RadarData3d<T, Raw, X, Y, Z>
|
||||
where
|
||||
T: Num + Clone,
|
||||
T: PartialEq + PartialOrd,
|
||||
Raw: ndarray::Data<Elem = T> + Clone + RawDataClone + DataMut,
|
||||
X: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Y: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Z: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Raw: ndarray::Data<Elem = T> + RawDataClone + DataMut,
|
||||
{
|
||||
fn map_by_fn<F>(&mut self, f: F)
|
||||
where
|
||||
@ -275,285 +120,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DataLoader<V, T>
|
||||
impl<T, Raw, X, Y> MultiDimensionData<T> for RadarData2d<T, Raw, X, Y>
|
||||
where
|
||||
V: Num + Clone + PartialEq + PartialOrd,
|
||||
T: MultiDimensionData<V>,
|
||||
{
|
||||
fn load<P: AsRef<Path>>(&self, path: P) -> Result<T, DataError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait AsyncDataLoader<V, T>
|
||||
where
|
||||
V: Num + Clone + PartialEq + PartialOrd,
|
||||
T: MultiDimensionData<V> + Send + Sync,
|
||||
{
|
||||
async fn load<P: AsRef<Path> + Send>(&self, path: P) -> Result<T, DataError>;
|
||||
}
|
||||
|
||||
pub struct Npz;
|
||||
impl Npz {
|
||||
#[inline]
|
||||
fn load_1d<T: Num + Deserialize, R: std::io::Read + Seek>(
|
||||
&self,
|
||||
data: &mut NpzArchive<R>,
|
||||
name: &str,
|
||||
) -> Result<Array1<T>, DataError> {
|
||||
// let mut data = npyz::npz::NpzArchive::open(path)?;
|
||||
let a = data.by_name(name)?.unwrap();
|
||||
let b: Vec<T> = a.into_vec().unwrap();
|
||||
|
||||
Ok(Array1::from_shape_vec(b.len(), b).unwrap())
|
||||
}
|
||||
#[inline]
|
||||
fn load_2d<T: Num + Deserialize, R: std::io::Read + Seek>(
|
||||
&self,
|
||||
// path: &Path,
|
||||
data: &mut NpzArchive<R>,
|
||||
name: &str,
|
||||
) -> Result<Array2<T>, DataError> {
|
||||
// let mut data = npyz::npz::NpzArchive::open(path)?;
|
||||
let a = data.by_name(name)?.unwrap();
|
||||
|
||||
let shape = a.shape().to_vec();
|
||||
let b: Vec<T> = a.into_vec().unwrap();
|
||||
|
||||
Ok(Array2::from_shape_vec((shape[0] as usize, shape[1] as usize), b).unwrap())
|
||||
}
|
||||
fn load_3d(&self, data: &mut NpzArchive<BufReader<std::fs::File>>) {}
|
||||
}
|
||||
|
||||
impl<T> DataLoader<T, RadarData2d<T, OwnedRepr<T>>> for Npz
|
||||
where
|
||||
T: Num + Clone + Deserialize + FromPrimitive,
|
||||
T: Num + Clone,
|
||||
T: PartialEq + PartialOrd,
|
||||
X: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Y: ndarray::Data<Elem = f64> + ndarray::RawDataClone,
|
||||
Raw: ndarray::Data<Elem = T> + RawDataClone + DataMut,
|
||||
{
|
||||
fn load<P: AsRef<Path>>(&self, path: P) -> Result<RadarData2d<T, OwnedRepr<T>>, DataError> {
|
||||
let mut data: NpzArchive<BufReader<std::fs::File>> = npyz::npz::NpzArchive::open(path)?;
|
||||
let dim1 = self.load_1d::<f64, BufReader<std::fs::File>>(&mut data, "lon")?;
|
||||
let dim2 = self.load_1d::<f64, BufReader<std::fs::File>>(&mut data, "lat")?;
|
||||
let value = self.load_2d::<T, BufReader<std::fs::File>>(&mut data, "value")?;
|
||||
|
||||
Ok(RadarData2d {
|
||||
dim1: dim1,
|
||||
dim2: dim2,
|
||||
fill_value: T::from_f64(-125.0).unwrap(),
|
||||
data: value,
|
||||
coord_type: CoordType::LatLon,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsyncDataLoader<T, RadarData2d<T, OwnedRepr<T>>> for Npz
|
||||
where
|
||||
T: Num + Clone + Deserialize + FromPrimitive,
|
||||
T: PartialEq + PartialOrd + Send + Sync,
|
||||
{
|
||||
fn load<'life0, 'async_trait, P>(
|
||||
&'life0 self,
|
||||
path: P,
|
||||
) -> core::pin::Pin<
|
||||
Box<
|
||||
dyn core::future::Future<Output = Result<RadarData2d<T, OwnedRepr<T>>, DataError>>
|
||||
+ core::marker::Send
|
||||
+ 'async_trait,
|
||||
>,
|
||||
>
|
||||
fn map_by_fn<F>(&mut self, f: F)
|
||||
where
|
||||
P: 'async_trait + AsRef<Path> + Send,
|
||||
'life0: 'async_trait,
|
||||
Self: 'async_trait,
|
||||
F: FnMut(&mut T),
|
||||
{
|
||||
Box::pin(async {
|
||||
let mut f = File::open(path).await?;
|
||||
let mut buffer = Vec::new();
|
||||
f.read_to_end(&mut buffer).await?;
|
||||
|
||||
let mut data = npyz::npz::NpzArchive::new(Cursor::new(buffer))?;
|
||||
let dim1 = self.load_1d::<f64, Cursor<Vec<u8>>>(&mut data, "lon")?;
|
||||
let dim2 = self.load_1d::<f64, Cursor<Vec<u8>>>(&mut data, "lat")?;
|
||||
let value = self.load_2d::<T, Cursor<Vec<u8>>>(&mut data, "value")?;
|
||||
|
||||
Ok(RadarData2d {
|
||||
dim1: dim1,
|
||||
dim2: dim2,
|
||||
fill_value: T::from_f64(-125.0).unwrap(),
|
||||
data: value,
|
||||
coord_type: CoordType::LatLon,
|
||||
})
|
||||
})
|
||||
self.data.map_inplace(f);
|
||||
}
|
||||
}
|
||||
|
||||
// fn resample(
|
||||
// &self,
|
||||
// width_rate: f64,
|
||||
// height_rate: f64,
|
||||
// filter_len: f64,
|
||||
// ) -> Result<RadarData2d<T, OwnedRepr<T>>, DataError> {
|
||||
// let width_rate = width_rate.min(1.0);
|
||||
// let height_rate = height_rate.min(1.0);
|
||||
// match self.coord_type {
|
||||
// CoordType::Polar => Err(DataError::FormatError),
|
||||
// CoordType::LatLon => {
|
||||
// let width_filtered: ArrayBase<ndarray::OwnedRepr<T>, Ix2> =
|
||||
// Self::_resample(&self.data, width_rate, filter_len);
|
||||
|
||||
// let result: ArrayBase<OwnedRepr<T>, Ix2> =
|
||||
// Self::_resample(&width_filtered.t(), height_rate, filter_len)
|
||||
// .t()
|
||||
// .to_owned();
|
||||
|
||||
// let new_dim1: ArrayBase<OwnedRepr<f64>, Ix1> = Self::_resample(
|
||||
// &Array2::from_shape_vec((1, self.dim1.len()), self.dim1.to_vec()).unwrap(),
|
||||
// width_rate,
|
||||
// filter_len,
|
||||
// )
|
||||
// .slice(s![0, ..])
|
||||
// .to_owned();
|
||||
|
||||
// let new_dim2: ArrayBase<OwnedRepr<f64>, Ix1> = Self::_resample(
|
||||
// &Array2::from_shape_vec((1, self.dim2.len()), self.dim2.to_vec()).unwrap(),
|
||||
// height_rate,
|
||||
// filter_len,
|
||||
// )
|
||||
// .slice(s![0, ..])
|
||||
// .to_owned();
|
||||
|
||||
// Ok(RadarData2d {
|
||||
// dim1: new_dim1,
|
||||
// dim2: new_dim2,
|
||||
// data: result,
|
||||
// coord_type: self.coord_type.to_owned(),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// fn _resample<'a, V, R: ndarray::Data<Elem = V>>(
|
||||
// data: &'a ArrayBase<R, Ix2>,
|
||||
// rate: f64,
|
||||
// filter_len: f64,
|
||||
// ) -> Array2<V>
|
||||
// where
|
||||
// V: Num + Clone + AsPrimitive<f64> + FromPrimitive,
|
||||
// {
|
||||
// let ori_width = data.ncols();
|
||||
// let ori_height = data.nrows();
|
||||
|
||||
// let new_width = (ori_width as f64 * rate).ceil() as usize;
|
||||
// let mut result: Array2<V> = Array2::zeros((ori_height, new_width));
|
||||
// (0..ori_height).into_iter().for_each(|height| {
|
||||
// for width in 0..new_width {
|
||||
// let center_x = (width as f64 + 0.5) / new_width as f64 * ori_width as f64;
|
||||
// let filter_start = center_x - filter_len / 2.0;
|
||||
// let start_idx = (filter_start - 0.5).ceil() as usize;
|
||||
|
||||
// let mut value_sum = 0.0;
|
||||
// let mut filter_sum = 0.0;
|
||||
|
||||
// for i in 0..filter_len as usize {
|
||||
// let input_x = start_idx + i;
|
||||
// let weight = windowed_sinc(
|
||||
// (input_x as f64 + 0.5 - center_x) * rate,
|
||||
// (input_x as f64 + 0.5 - filter_start) / filter_len,
|
||||
// );
|
||||
// value_sum += weight * data[[height, input_x.clamp(0, ori_width - 1)]].as_();
|
||||
// filter_sum += weight;
|
||||
// }
|
||||
|
||||
// result[[height, width]] = V::from_f64(value_sum / filter_sum).unwrap();
|
||||
// }
|
||||
// });
|
||||
// result
|
||||
// }
|
||||
|
||||
// pub struct LevelData<T: Num + Clone + PartialEq + PartialOrd>(
|
||||
// pub Quadtree<i64, RadarData2d<T, OwnedRepr<T>>>,
|
||||
// );
|
||||
|
||||
// impl<T> LevelData<T>
|
||||
// where
|
||||
// T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug + PartialEq + PartialOrd,
|
||||
// {
|
||||
// fn value(
|
||||
// level_data: Vec<RadarData2d<T, OwnedRepr<T>>>,
|
||||
// level_num: usize,
|
||||
// ) -> Vec<RadarData2d<T, OwnedRepr<T>>> {
|
||||
// if level_num == 0 {
|
||||
// return level_data;
|
||||
// }
|
||||
|
||||
// let mut result: Vec<RadarData2d<T, OwnedRepr<T>>> =
|
||||
// Vec::with_capacity(level_data.len() * 4);
|
||||
|
||||
// let results = level_data
|
||||
// .iter()
|
||||
// .flat_map(|v| v.split().into_iter().map(|x| x.value_to_owned()));
|
||||
|
||||
// result.extend(results);
|
||||
|
||||
// return Self::value(result, level_num - 1);
|
||||
// }
|
||||
|
||||
// fn new(data: &RadarData2d<T, OwnedRepr<T>>, level: usize, rate: f64) -> Self {
|
||||
// // let rate = 1.0 / level as f64;
|
||||
// let resampled = data.resample(rate, rate, 2.0).unwrap();
|
||||
// let blocks = Self::value(vec![resampled], level);
|
||||
// let mut tree: Quadtree<i64, RadarData2d<T, OwnedRepr<T>>> =
|
||||
// quadtree_rs::Quadtree::new(level);
|
||||
|
||||
// blocks.into_iter().for_each(|block| {
|
||||
// tree.insert(
|
||||
// AreaBuilder::default()
|
||||
// .anchor(quadtree_rs::point::Point {
|
||||
// x: *block.dim1.first().unwrap() as i64,
|
||||
// y: *block.dim2.first().unwrap() as i64,
|
||||
// })
|
||||
// .dimensions((block.dim1.len() as i64, block.dim2.len() as i64))
|
||||
// .build()
|
||||
// .unwrap(),
|
||||
// block,
|
||||
// );
|
||||
// });
|
||||
|
||||
// Self(tree)
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn levels<T>(data: Radar2d<T>, levels: usize) -> Vec<LevelData<T>>
|
||||
// where
|
||||
// T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug,
|
||||
// T: PartialEq + PartialOrd,
|
||||
// {
|
||||
// let numerator = 1.0 / levels as f64;
|
||||
// (0..levels)
|
||||
// .into_iter()
|
||||
// .map(|level| LevelData::new(&data, level + 1, 1.0 - level as f64 * numerator))
|
||||
// .collect()
|
||||
// }
|
||||
|
||||
#[inline]
|
||||
fn windowed_sinc(x: f64, y: f64) -> f64 {
|
||||
let x = x * PI;
|
||||
let sinc = if x != 0.0 { f64::sin(x) / x } else { 1.0 };
|
||||
let window = if 0f64 <= y && y <= 1.0 {
|
||||
1.0 - (y - 0.5).abs() * 2.0
|
||||
} else {
|
||||
0f64
|
||||
};
|
||||
sinc * window
|
||||
}
|
||||
|
||||
pub enum DownSampleMeth {
|
||||
STD,
|
||||
MEAN,
|
||||
VAR,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum CoordType {
|
||||
Polar,
|
||||
LatLon,
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::pipeline::element::ElementImpl;
|
||||
use crate::pipeline::GridElementImpl;
|
||||
use crate::utils::*;
|
||||
use radarg_plugin_interface::{CoordType, PluginResult, PluginResultType};
|
||||
use radarg_plugin_interface::{CoordType, DataShape, PluginResult, PluginResultType};
|
||||
use std::sync::Arc;
|
||||
macro_rules! data_to_grid {
|
||||
($_type:ident,$(($branch:path ,$boundary_norm: expr)),+) => {
|
||||
|
||||
@ -17,7 +17,7 @@ pub enum PipelineError {
|
||||
source: ProjError,
|
||||
},
|
||||
#[error("data error")]
|
||||
DataError(String)
|
||||
DataError(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -50,7 +50,6 @@ pub enum PluginError {
|
||||
PluginError,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PoolError {
|
||||
#[error("")]
|
||||
@ -61,7 +60,6 @@ pub enum PoolError {
|
||||
PoolInitialized(&'static str),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RenderError {
|
||||
#[error("")]
|
||||
@ -70,5 +68,4 @@ pub enum RenderError {
|
||||
None,
|
||||
#[error("Canceled")]
|
||||
Canceled,
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
|
||||
pub fn lat_lon_to_zoom(lat_range: (f64, f64), lon_range: (f64, f64), w: f32, h:f32 ) -> u8 {
|
||||
pub fn lat_lon_to_zoom(lat_range: (f64, f64), lon_range: (f64, f64), w: f32, h: f32) -> u8 {
|
||||
let lat_diff = lat_range.1 - lat_range.0;
|
||||
let lon_diff = lon_range.1 - lon_range.0;
|
||||
let z1 = ( (360.0 * w) as f64 / lon_diff / 256.0).log2();
|
||||
let z2 = ( (180.0 * h) as f64 / lat_diff / 256.0).log2();
|
||||
let z1 = ((360.0 * w) as f64 / lon_diff / 256.0).log2();
|
||||
let z2 = ((180.0 * h) as f64 / lat_diff / 256.0).log2();
|
||||
let z = z1.min(z2);
|
||||
z as u8
|
||||
}
|
||||
@ -1,17 +1,16 @@
|
||||
use super::{offscreen_renderer::CanvasWrapper, Dispatcher, Pipeline};
|
||||
use crate::components::app::AppCommand;
|
||||
use crate::components::ControlPanelInputMsg;
|
||||
use crate::components::Widget;
|
||||
use crate::coords::cms::CMS;
|
||||
use crate::coords::Range;
|
||||
use crate::data::MetaInfo;
|
||||
use crate::errors::{PipelineError, RenderError};
|
||||
use crate::predefined::color_mapper::ColorMapper;
|
||||
use crate::widgets::Render;
|
||||
use crate::RUNTIME;
|
||||
use crate::{coords::Range, widgets::widget::Widget};
|
||||
use chrono::{DateTime, TimeZone, Utc};
|
||||
use core_extensions::SelfOps;
|
||||
use femtovg::rgb::alt::GRAY8;
|
||||
use femtovg::{renderer::OpenGl, Canvas, ImageFlags, ImageId, ImageInfo, PixelFormat};
|
||||
use femtovg::{ImageFlags, ImageId};
|
||||
use futures::StreamExt;
|
||||
use num_traits::{AsPrimitive, FromPrimitive, NumOps};
|
||||
use radarg_plugin_interface::PluginResult;
|
||||
use std::any::Any;
|
||||
use std::borrow::Borrow;
|
||||
@ -21,17 +20,13 @@ use std::ops::{Deref, DerefMut};
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
fmt::Debug,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use tokio::sync::{
|
||||
oneshot::{channel, Receiver, Sender},
|
||||
oneshot::{channel, Receiver},
|
||||
Notify,
|
||||
};
|
||||
use tracing::Instrument;
|
||||
|
||||
pub type ElementID = usize;
|
||||
static ELEMENT_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
@ -122,6 +117,11 @@ pub struct InstantElement {
|
||||
dispatcher: Rc<Dispatcher>,
|
||||
}
|
||||
|
||||
pub enum ElementImplMap {
|
||||
ColorMap,
|
||||
None,
|
||||
}
|
||||
|
||||
pub trait ElementImpl: Debug + Send + Sync + 'static {
|
||||
fn render(&self, data: &PluginResult, canvas: &mut CanvasWrapper, cms: &mut CMS) -> Target;
|
||||
}
|
||||
@ -147,6 +147,10 @@ impl InstantElement {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn imp(&self) -> &InstantElementDrawerType {
|
||||
&self.draw_type
|
||||
}
|
||||
|
||||
pub fn to_time_series(
|
||||
self,
|
||||
dispatcher: Rc<Dispatcher>,
|
||||
@ -231,6 +235,10 @@ impl TimeSeriesElement {
|
||||
self.cms = cms;
|
||||
}
|
||||
|
||||
pub fn imp(&self) -> &Arc<dyn ElementImpl> {
|
||||
&self.imp
|
||||
}
|
||||
|
||||
fn register_noti(&self, datetime: DateTime<Utc>, noti: Arc<Notify>) {
|
||||
self.registers
|
||||
.lock()
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
use super::predefined::GridFieldRenderer;
|
||||
use super::renders::DataRenderer;
|
||||
use crate::data::Radar2d;
|
||||
use crate::pipeline::element::{ElementImpl, Target};
|
||||
use crate::components::Widget;
|
||||
use crate::data::{Radar2d, Radar3d};
|
||||
use crate::pipeline::element::{ElementImpl, ElementImplMap, Target};
|
||||
use crate::pipeline::offscreen_renderer::CanvasWrapper;
|
||||
use crate::widgets::predefined::color_mapper::ColorMapper;
|
||||
use crate::widgets::{LayerImpl};
|
||||
use crate::predefined::color_mapper::ColorMapper;
|
||||
use crate::widgets::LayerImpl;
|
||||
use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps};
|
||||
use radarg_plugin_interface::{DataShape, PluginResult};
|
||||
use std::any::Any;
|
||||
use std::fmt::Debug;
|
||||
use radarg_plugin_interface::PluginResult;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GridElementImpl<CMAP, T>
|
||||
@ -52,8 +53,22 @@ where
|
||||
cms: &mut crate::coords::cms::CMS,
|
||||
) -> crate::pipeline::element::Target {
|
||||
let first_block = data.blocks.first().unwrap();
|
||||
let data = first_block.clone().into();
|
||||
let result = self.renderer.render(canvas, cms, &data, (3000.0, 3000.0));
|
||||
result
|
||||
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 = self.renderer.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 = self.renderer.render(canvas, cms, &data, (3000.0, 3000.0));
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ mod renders;
|
||||
pub mod utils;
|
||||
|
||||
pub use dispatcher::Dispatcher;
|
||||
pub use element::RenderResult;
|
||||
pub use element::*;
|
||||
pub use element_impl::*;
|
||||
pub use new_pipeline::Pipeline;
|
||||
pub use offscreen_renderer::OffscreenRenderer;
|
||||
pub use element_impl::*;
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use super::super::renders::DataRenderer;
|
||||
use crate::coords::cms::CMS;
|
||||
use crate::data::{Radar2dRef, RadarData2d};
|
||||
use crate::pipeline::element::{Target, TargetType};
|
||||
use crate::widgets::predefined::color_mapper::ColorMapper;
|
||||
use crate::predefined::color_mapper::ColorMapper;
|
||||
use crate::{data::Radar2d, utils::meshgrid};
|
||||
use femtovg::ImageInfo;
|
||||
use femtovg::{
|
||||
@ -22,7 +23,7 @@ where
|
||||
T: NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64>,
|
||||
CMAP: ColorMapper<T>,
|
||||
{
|
||||
cmap: CMAP,
|
||||
pub cmap: CMAP,
|
||||
value_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
@ -61,15 +62,6 @@ impl<T: NumOps + PartialOrd + Copy + FromPrimitive + AsPrimitive<f64>, CMAP: Col
|
||||
|
||||
let rt_lat = dim2[[r + 1, c + 1]];
|
||||
let rt_lon = dim1[[r + 1, c + 1]];
|
||||
// let cell: LineString = vec![
|
||||
// (lb_lon, lb_lat),
|
||||
// (rt_lon + 0.001, lb_lat),
|
||||
// (rt_lon + 0.001, rt_lat),
|
||||
// (lb_lon, rt_lat + 0.001),
|
||||
// (lb_lon, lb_lat + 0.001),
|
||||
// ]
|
||||
// .into();
|
||||
|
||||
let v = &data[[r, c]];
|
||||
let mapped_color = self.cmap.map_value_to_color(*v, fill_value);
|
||||
|
||||
@ -77,32 +69,23 @@ impl<T: NumOps + PartialOrd + Copy + FromPrimitive + AsPrimitive<f64>, CMAP: Col
|
||||
continue;
|
||||
}
|
||||
|
||||
// let mapped_ring = cms.ring_map(&cell).unwrap();
|
||||
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();
|
||||
// let mut points = mapped_ring.points();
|
||||
// let first_point = points.next().unwrap();
|
||||
// path.move_to(first_point.x(), first_point.y());
|
||||
//
|
||||
// for point in points {
|
||||
// path.line_to(point.x(), point.y());
|
||||
// }
|
||||
path.rect(ox, oy, (rx - ox) * 1.5, (ry - oy) * 1.5);
|
||||
// path.close();
|
||||
canvas.fill_path(&path, &Paint::color(mapped_color.unwrap()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, CMAP> DataRenderer for GridFieldRenderer<CMAP, T>
|
||||
impl<'a, T, CMAP> DataRenderer<'a> for GridFieldRenderer<CMAP, T>
|
||||
where
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + FromPrimitive + AsPrimitive<f64>,
|
||||
CMAP: ColorMapper<T>,
|
||||
{
|
||||
type Data = Radar2d<T>;
|
||||
type Data = Radar2dRef<'a, T>;
|
||||
|
||||
fn render(
|
||||
&self,
|
||||
@ -156,25 +139,6 @@ where
|
||||
debug_assert_eq!(gl::GetError(), gl::NO_ERROR);
|
||||
}
|
||||
info!("Time to read pixels: {:?}", start.elapsed());
|
||||
|
||||
// let img: ImageBuffer<Rgba<u8>, Vec<u8>> = ImageBuffer::from_raw(w as u32, h as u32, pixels)
|
||||
// .expect("Failed to create ImageBuffer");
|
||||
// let thumbnail = resize(&img, 500, 500, image::imageops::FilterType::Lanczos3);
|
||||
// let mut thumb_buffer = Cursor::new(Vec::new());
|
||||
// img.write_to(&mut thumb_buffer, image::ImageOutputFormat::Png)
|
||||
// .expect("Failed to write PNG buffer");
|
||||
// info!("Time to write PNG: {:?}", start.elapsed());
|
||||
// let thumb_data = thumb_buffer.into_inner();
|
||||
// let thumbnail_tex =
|
||||
// gtk::gdk::Texture::from_bytes(>k::glib::Bytes::from(&thumb_data)).unwrap();
|
||||
|
||||
// 将 ImageBuffer 编码为 PNG
|
||||
// let mut png_buffer = Cursor::new(Vec::new());
|
||||
// img.write_to(&mut png_buffer, image::ImageOutputFormat::Bmp)
|
||||
// .expect("Failed to write PNG buffer");
|
||||
|
||||
// let png_data = png_buffer.into_inner();
|
||||
|
||||
let d1_start = (data.dim1.view()).first().unwrap().clone();
|
||||
let d1_end = (data.dim1.view()).last().unwrap().clone();
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ use crate::coords::cms::CMS;
|
||||
use crate::pipeline::element::Target;
|
||||
use femtovg::{renderer::OpenGl, Canvas};
|
||||
|
||||
pub trait DataRenderer {
|
||||
pub trait DataRenderer<'a> {
|
||||
type Data;
|
||||
fn render(
|
||||
&self,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use crate::{
|
||||
coords::cms::CMS, data::Radar2d, errors::RenderError,
|
||||
widgets::predefined::color_mapper::BoundaryNorm,
|
||||
coords::cms::CMS, data::Radar2d, errors::RenderError, predefined::color_mapper::BoundaryNorm,
|
||||
};
|
||||
use chrono::{prelude::*, Duration};
|
||||
use radarg_plugin_interface::*;
|
||||
|
||||
@ -1,8 +1,42 @@
|
||||
use crate::data::{CoordType, Radar2d};
|
||||
use crate::data::{CoordType, Radar2d, Radar3d};
|
||||
use ndarray::{Array1, Array2, Array3, ShapeBuilder};
|
||||
use num_traits::{AsPrimitive, FromPrimitive, Num};
|
||||
use radarg_plugin_interface::{Block, DataShape, PluginResult, VecResult};
|
||||
|
||||
macro_rules! match_in_macro_3d {
|
||||
// ($(($branch:path, $t:ty)),+, $block:ident)
|
||||
($block:tt, $(($branch:path, $t:path)),+) => {
|
||||
{
|
||||
let data = $block.data;
|
||||
let dim3: Vec<_> = $block.dimension_values.remove(0).into();
|
||||
let dim2: Vec<_> = $block.dimension_values.remove(0).into();
|
||||
let dim1: Vec<_> = $block.dimension_values.remove(0).into();
|
||||
let fill_value = $block.fill_value;
|
||||
let data_shape: Vec<usize> = $block.size.into();
|
||||
let coord_type = match $block.coord_type{
|
||||
radarg_plugin_interface::CoordType::Cartesian => CoordType::LatLon,
|
||||
radarg_plugin_interface::CoordType::Polar => CoordType::Polar,
|
||||
_ => panic!("Unsupported coord type")
|
||||
};
|
||||
match data {
|
||||
$(
|
||||
$branch(x) => {
|
||||
let shape = [data_shape[0], data_shape[1], data_shape[2]];
|
||||
Radar3d {
|
||||
fill_value: T::from_f64(fill_value).unwrap(),
|
||||
data: Array3::from_shape_vec(shape, x.into_iter().map(|x| $t(x).unwrap()).collect::<Vec<T>>()).unwrap(),
|
||||
dim1: Array1::from_vec(dim1),
|
||||
dim2: Array1::from_vec(dim2),
|
||||
dim3: Array1::from_vec(dim3),
|
||||
coord_type: coord_type,
|
||||
}},
|
||||
)+
|
||||
_ => panic!("Unsupported data type"),
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
macro_rules! match_in_macro {
|
||||
// ($(($branch:path, $t:ty)),+, $block:ident)
|
||||
($block:tt, $(($branch:path, $t:path)),+) => {
|
||||
@ -61,3 +95,31 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Block> for Radar3d<T>
|
||||
where
|
||||
T: Num + Copy + PartialOrd + PartialEq,
|
||||
T: FromPrimitive,
|
||||
{
|
||||
fn from(block: Block) -> Self {
|
||||
let mut block = block;
|
||||
let a = &block.dimension_values;
|
||||
println!("{:?}", a);
|
||||
if let DataShape::Cube = block.shape {
|
||||
let result = match_in_macro_3d!(
|
||||
block,
|
||||
(VecResult::I8, T::from_i8),
|
||||
(VecResult::I32, T::from_i32),
|
||||
(VecResult::I64, T::from_i64),
|
||||
(VecResult::U8, T::from_u8),
|
||||
(VecResult::U32, T::from_u32),
|
||||
(VecResult::U64, T::from_u64),
|
||||
(VecResult::F32, T::from_f32),
|
||||
(VecResult::F64, T::from_f64)
|
||||
);
|
||||
result
|
||||
} else {
|
||||
panic!("Expected matrix data shape");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,21 @@
|
||||
use crate::map_tile_utils::*;
|
||||
use slippy_map_tiles::{BBox, merc_location_to_tile_coords, size_bbox_zoom_metatiles, Tile};
|
||||
use slippy_map_tiles::{merc_location_to_tile_coords, size_bbox_zoom_metatiles, BBox, Tile};
|
||||
|
||||
pub fn map_tile_layer(lat_range: (f64, f64), lon_range: (f64, f64), w: f32, h: f32) {
|
||||
let z = lat_lon_to_zoom(lat_range, lon_range, w, h);
|
||||
let bbox = BBox::new(lat_range.0 as f32, lon_range.0 as f32, lat_range.1 as f32, lon_range.1 as f32).unwrap();
|
||||
let bbox = BBox::new(
|
||||
lat_range.0 as f32,
|
||||
lon_range.0 as f32,
|
||||
lat_range.1 as f32,
|
||||
lon_range.1 as f32,
|
||||
)
|
||||
.unwrap();
|
||||
let size = size_bbox_zoom_metatiles(&bbox, z, 4);
|
||||
let t = Tile::new(10, 547, 380).unwrap();
|
||||
println!("size: {:?}", size);
|
||||
println!("tile: {:?}", t);
|
||||
}
|
||||
|
||||
|
||||
mod test {
|
||||
use super::*;
|
||||
#[test]
|
||||
|
||||
@ -1 +1,5 @@
|
||||
pub mod map_tile;
|
||||
// pub mod grid_field_renderer;
|
||||
// pub mod layers;
|
||||
pub mod color_mapper;
|
||||
pub mod widgets;
|
||||
|
||||
100
src/predefined/widgets.rs
Normal file
100
src/predefined/widgets.rs
Normal file
@ -0,0 +1,100 @@
|
||||
use crate::components::widget::{Widget, WidgetType};
|
||||
use crate::predefined::color_mapper::ColorMapper;
|
||||
use crate::widgets::{AssoElement, Layer};
|
||||
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
|
||||
use num_traits::*;
|
||||
use std::any::Any;
|
||||
use topojson::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ColorBar {
|
||||
padding: [f32; 4],
|
||||
width: f32,
|
||||
height: f32,
|
||||
margin: [i32; 4],
|
||||
}
|
||||
|
||||
impl ColorBar {
|
||||
pub fn new(padding: [f32; 4], size: (f32, f32), margin: [i32; 4]) -> Self {
|
||||
Self {
|
||||
padding,
|
||||
width: size.0,
|
||||
height: size.1,
|
||||
margin,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for ColorBar {
|
||||
fn cairo_render(&self, layers: &Vec<Layer>, canvas: >k::cairo::Context, w: f32, h: f32) {
|
||||
let bar_width = 10;
|
||||
let bar_height = h - self.padding[0] - self.padding[2];
|
||||
let (x, y) = (self.padding[3], self.padding[0]);
|
||||
|
||||
let length = layers.len();
|
||||
|
||||
if length == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let first = layers.first().unwrap();
|
||||
|
||||
match first.get_associated_element() {
|
||||
AssoElement::Instant(i) => {
|
||||
let imp = i.imp();
|
||||
}
|
||||
AssoElement::TimeSeries(t) => {
|
||||
let c = t.lock().unwrap();
|
||||
let imp = c.imp();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// for ((i, color), label) in self
|
||||
// .color_list
|
||||
// .iter()
|
||||
// .enumerate()
|
||||
// .zip(self.color_mapper.labels())
|
||||
// {
|
||||
// let y = y + i as f32 * b_h;
|
||||
//
|
||||
// canvas.set_source_rgba(
|
||||
// color.r as f64,
|
||||
// color.g as f64,
|
||||
// color.b as f64,
|
||||
// color.a as f64,
|
||||
// );
|
||||
// canvas.rectangle(x as f64, y as f64, bar_width as f64, b_h as f64);
|
||||
// canvas.fill();
|
||||
//
|
||||
// let extents = canvas.text_extents(&label).unwrap();
|
||||
//
|
||||
// canvas.move_to(
|
||||
// (x + bar_width as f32 + 5.0) as f64,
|
||||
// y as f64 + extents.height() / 2.0 as f64,
|
||||
// );
|
||||
// canvas.set_source_rgba(1.0, 1.0, 1.0, 1.0);
|
||||
// canvas.show_text(&label);
|
||||
// }
|
||||
}
|
||||
|
||||
fn location(&self) -> (gtk::Align, gtk::Align) {
|
||||
(gtk::Align::End, gtk::Align::End)
|
||||
}
|
||||
|
||||
fn size(&self) -> (f32, f32) {
|
||||
(self.width, self.height)
|
||||
}
|
||||
|
||||
fn widget_type(&self) -> WidgetType {
|
||||
WidgetType::Cairo
|
||||
}
|
||||
|
||||
fn margin(&self) -> [i32; 4] {
|
||||
self.margin
|
||||
}
|
||||
|
||||
fn padding(&self) -> [i32; 4] {
|
||||
[10, 10, 10, 10]
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ use surfman::{
|
||||
GLVersion, NativeConnection, NativeContext, SurfaceAccess, SurfaceType,
|
||||
};
|
||||
|
||||
use crate::widgets::render::predefined::color_mapper::BoundaryNorm;
|
||||
use crate::predefined::color_mapper::BoundaryNorm;
|
||||
use crate::RUNTIME;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
@ -0,0 +1 @@
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use std::ops::Range;
|
||||
use geo_types::LineString;
|
||||
use crate::coords::Mapper;
|
||||
use geo_types::LineString;
|
||||
use std::ops::Range;
|
||||
|
||||
pub struct CMS {
|
||||
mapper: Mapper,
|
||||
|
||||
@ -4,8 +4,7 @@ use gtk::subclass::prelude::*;
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ExteriorWidget {
|
||||
}
|
||||
pub struct ExteriorWidget {}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for ExteriorWidget {
|
||||
@ -13,4 +12,4 @@ impl ObjectSubclass for ExteriorWidget {
|
||||
type Type = super::ExteriorWidget;
|
||||
}
|
||||
|
||||
impl ObjectImpl for ExteriorWidget{}
|
||||
impl ObjectImpl for ExteriorWidget {}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
use super::super::WindowCoord;
|
||||
use super::layers::Layer;
|
||||
use gtk::glib;
|
||||
use gtk::subclass::prelude::*;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use super::layers::Layer;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct InteriorWidget {
|
||||
|
||||
@ -1,17 +1,12 @@
|
||||
use super::super::Render;
|
||||
use crate::coords::cms::CMS;
|
||||
use crate::errors::PipelineError;
|
||||
use crate::pipeline::element::{self, Element, ElementID, Target, TargetType};
|
||||
use crate::pipeline::element::{self, Target};
|
||||
use crate::pipeline::offscreen_renderer::CanvasWrapper;
|
||||
use crate::{coords::Range, widgets::widget::Widget};
|
||||
use chrono::{prelude::*, DateTime};
|
||||
use core_extensions::SelfOps;
|
||||
use femtovg::{renderer::OpenGl, Canvas, ImageId};
|
||||
use femtovg::{renderer::OpenGl, Canvas};
|
||||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
fmt::Debug,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
use tracing::info;
|
||||
mod cms;
|
||||
mod exterior;
|
||||
mod imp;
|
||||
mod interior;
|
||||
pub mod predefined;
|
||||
pub mod renders;
|
||||
pub mod widget;
|
||||
|
||||
pub use self::imp::{RenderConfig, RenderMotion, RenderStatus};
|
||||
use crate::components::messages::MonitorInputMsg;
|
||||
use crate::coords::cms::CMS;
|
||||
use crate::coords::{Mapper, Range};
|
||||
use crate::errors::PipelineError;
|
||||
@ -21,9 +19,7 @@ use gtk::prelude::*;
|
||||
use gtk::subclass::prelude::ObjectSubclassIsExt;
|
||||
use gtk::EventControllerScrollFlags;
|
||||
pub use interior::*;
|
||||
use slippy_map_tiles::Tile;
|
||||
use std::cell::{Ref, RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
|
||||
@ -1,5 +1 @@
|
||||
pub mod color_mapper;
|
||||
pub mod gis;
|
||||
// pub mod grid_field_renderer;
|
||||
// pub mod layers;
|
||||
pub mod widgets;
|
||||
|
||||
@ -1,103 +0,0 @@
|
||||
use super::{
|
||||
super::widget::{Widget as WidgetTrait, WidgetType},
|
||||
super::Layer,
|
||||
color_mapper::ColorMapper,
|
||||
};
|
||||
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
|
||||
use num_traits::*;
|
||||
#[derive(Debug)]
|
||||
pub struct ColorBar<V, T>
|
||||
where
|
||||
V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64>,
|
||||
T: ColorMapper<V>,
|
||||
{
|
||||
color_mapper: T,
|
||||
padding: [f32; 4],
|
||||
width: f32,
|
||||
height: f32,
|
||||
margin: [i32; 4],
|
||||
color_list: Vec<femtovg::Color>,
|
||||
phantom: std::marker::PhantomData<V>,
|
||||
}
|
||||
|
||||
impl<V, T> ColorBar<V, T>
|
||||
where
|
||||
V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64>,
|
||||
T: ColorMapper<V>,
|
||||
{
|
||||
pub fn new(color_mapper: T, padding: [f32; 4], size: (f32, f32), margin: [i32; 4]) -> Self {
|
||||
let (l, ll) = color_mapper.min_max();
|
||||
let invalid = color_mapper.invalid();
|
||||
let colors = color_mapper.map_min_to_max();
|
||||
|
||||
Self {
|
||||
color_list: colors,
|
||||
color_mapper,
|
||||
padding,
|
||||
width: size.0,
|
||||
height: size.1,
|
||||
margin,
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, T> WidgetTrait for ColorBar<V, T>
|
||||
where
|
||||
V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync,
|
||||
T: ColorMapper<V> + 'static,
|
||||
{
|
||||
fn cairo_render(&self, canvas: >k::cairo::Context, w: f32, h: f32) {
|
||||
let bar_width = 10;
|
||||
let bar_height = h - self.padding[0] - self.padding[2];
|
||||
let (x, y) = (self.padding[3], self.padding[0]);
|
||||
let b_h = bar_height / self.color_list.len() as f32;
|
||||
|
||||
for ((i, color), label) in self
|
||||
.color_list
|
||||
.iter()
|
||||
.enumerate()
|
||||
.zip(self.color_mapper.labels())
|
||||
{
|
||||
let y = y + i as f32 * b_h;
|
||||
|
||||
canvas.set_source_rgba(
|
||||
color.r as f64,
|
||||
color.g as f64,
|
||||
color.b as f64,
|
||||
color.a as f64,
|
||||
);
|
||||
canvas.rectangle(x as f64, y as f64, bar_width as f64, b_h as f64);
|
||||
canvas.fill();
|
||||
|
||||
let extents = canvas.text_extents(&label).unwrap();
|
||||
|
||||
canvas.move_to(
|
||||
(x + bar_width as f32 + 5.0) as f64,
|
||||
y as f64 + extents.height() / 2.0 as f64,
|
||||
);
|
||||
canvas.set_source_rgba(1.0, 1.0, 1.0, 1.0);
|
||||
canvas.show_text(&label);
|
||||
}
|
||||
}
|
||||
|
||||
fn location(&self) -> (gtk::Align, gtk::Align) {
|
||||
(gtk::Align::End, gtk::Align::End)
|
||||
}
|
||||
|
||||
fn size(&self) -> (f32, f32) {
|
||||
(self.width, self.height)
|
||||
}
|
||||
|
||||
fn widget_type(&self) -> WidgetType {
|
||||
WidgetType::Cairo
|
||||
}
|
||||
|
||||
fn margin(&self) -> [i32; 4] {
|
||||
self.margin
|
||||
}
|
||||
|
||||
fn padding(&self) -> [i32; 4] {
|
||||
[10, 10, 10, 10]
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
use super::Render;
|
||||
use crate::coords::cms::CMS;
|
||||
use femtovg::{renderer::OpenGl, Canvas};
|
||||
use crate::pipeline::element::Target;
|
||||
use femtovg::{renderer::OpenGl, Canvas};
|
||||
|
||||
pub trait DataRenderer {
|
||||
type Data;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::widgets::widget::Widget;
|
||||
use crate::components::monitor::Widget;
|
||||
use chrono::{prelude::*, Duration};
|
||||
use gtk::glib::{self, prelude::*, ParamSpec, Properties, Value};
|
||||
use gtk::prelude::*;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use self::widget::Widget;
|
||||
use crate::components::monitor::Widget;
|
||||
|
||||
pub use super::*;
|
||||
mod imp;
|
||||
@ -66,7 +66,7 @@ impl WidgetFrame {
|
||||
drawing_area.set_draw_func(clone!(@strong widget => move |_, canvas, x, y| {
|
||||
let widget = widget.borrow();
|
||||
let widget = widget.as_ref().unwrap();
|
||||
widget.cairo_render(canvas,x as f32,y as f32);
|
||||
// widget.cairo_render(canvas,x as f32,y as f32);
|
||||
}));
|
||||
drawing_area.queue_draw();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user