diff --git a/etws_loader/src/lib.rs b/etws_loader/src/lib.rs index 28e32bc..00d7b2c 100644 --- a/etws_loader/src/lib.rs +++ b/etws_loader/src/lib.rs @@ -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(); } } diff --git a/etws_loader/target/.rustc_info.json b/etws_loader/target/.rustc_info.json index 978f21d..14533f6 100644 --- a/etws_loader/target/.rustc_info.json +++ b/etws_loader/target/.rustc_info.json @@ -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":{}} \ No newline at end of file +{"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":{}} \ No newline at end of file diff --git a/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/dep-lib-etws_loader b/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/dep-lib-etws_loader index 26301f8..a14b503 100644 Binary files a/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/dep-lib-etws_loader and b/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/dep-lib-etws_loader differ diff --git a/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/lib-etws_loader b/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/lib-etws_loader index 4e96828..928d854 100644 --- a/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/lib-etws_loader +++ b/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/lib-etws_loader @@ -1 +1 @@ -ee6a7bacac3da619 \ No newline at end of file +16f3840281ed1c0f \ No newline at end of file diff --git a/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/lib-etws_loader.json b/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/lib-etws_loader.json index d2b8ad2..2d45bde 100644 --- a/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/lib-etws_loader.json +++ b/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/lib-etws_loader.json @@ -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} \ No newline at end of file +{"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} \ No newline at end of file diff --git a/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/output-lib-etws_loader b/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/output-lib-etws_loader index 8c3a5b0..194757b 100644 --- a/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/output-lib-etws_loader +++ b/etws_loader/target/release/.fingerprint/etws_loader-826e392dbec97b5d/output-lib-etws_loader @@ -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"} diff --git a/etws_loader/target/release/deps/etws_loader.d b/etws_loader/target/release/deps/etws_loader.d index 46f83da..2025c0d 100644 --- a/etws_loader/target/release/deps/etws_loader.d +++ b/etws_loader/target/release/deps/etws_loader.d @@ -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: diff --git a/etws_loader/target/release/deps/libetws_loader.dylib b/etws_loader/target/release/deps/libetws_loader.dylib index 41e2705..09cb86d 100755 Binary files a/etws_loader/target/release/deps/libetws_loader.dylib and b/etws_loader/target/release/deps/libetws_loader.dylib differ diff --git a/etws_loader/target/release/deps/libetws_loader.rlib b/etws_loader/target/release/deps/libetws_loader.rlib index a5be6bd..53a656d 100644 Binary files a/etws_loader/target/release/deps/libetws_loader.rlib and b/etws_loader/target/release/deps/libetws_loader.rlib differ diff --git a/etws_loader/target/release/libetws_loader.d b/etws_loader/target/release/libetws_loader.d index bd370ec..77c9b50 100644 --- a/etws_loader/target/release/libetws_loader.d +++ b/etws_loader/target/release/libetws_loader.d @@ -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 diff --git a/etws_loader/target/release/libetws_loader.dylib b/etws_loader/target/release/libetws_loader.dylib index 41e2705..09cb86d 100755 Binary files a/etws_loader/target/release/libetws_loader.dylib and b/etws_loader/target/release/libetws_loader.dylib differ diff --git a/etws_loader/target/release/libetws_loader.rlib b/etws_loader/target/release/libetws_loader.rlib index a5be6bd..53a656d 100644 Binary files a/etws_loader/target/release/libetws_loader.rlib and b/etws_loader/target/release/libetws_loader.rlib differ diff --git a/radarg_plugin_interface/src/error.rs b/radarg_plugin_interface/src/error.rs index 60249f2..613d699 100644 --- a/radarg_plugin_interface/src/error.rs +++ b/radarg_plugin_interface/src/error.rs @@ -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), } - 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(()), } } } diff --git a/radarg_plugin_interface/src/lib.rs b/radarg_plugin_interface/src/lib.rs index 5e990f0..2e55286 100644 --- a/radarg_plugin_interface/src/lib.rs +++ b/radarg_plugin_interface/src/lib.rs @@ -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)] diff --git a/src/actions.rs b/src/actions.rs index 8531287..2ec2bf6 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -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>(widget: W, sender: ComponentSender) { let add_action: RelmAction = { 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 = { 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 = RelmActionGroup::new(); diff --git a/src/components/app.rs b/src/components/app.rs index 1d147b2..1746618 100644 --- a/src/components/app.rs +++ b/src/components/app.rs @@ -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> = Lazy::new(|| Mutex::new(PathBu pub type ElementKey = String; +#[derive(Debug)] +pub enum LayerMsg { + Add(Layer), + Remove(usize), + SwitchToTime(usize), + Select(Vec), + 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, Option>>>>; type RcDispatcher = Rc; @@ -90,6 +99,7 @@ pub struct AppModel { render: Controller, #[do_not_track] sidebar: Controller, + selected_layer: Vec, #[do_not_track] layers: Rc>>, #[do_not_track] @@ -214,7 +224,7 @@ impl Component for AppModel { ) -> ComponentParts { 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); } diff --git a/src/components/control_panel/control_panel.rs b/src/components/control_panel/control_panel.rs index b53c124..1790760 100644 --- a/src/components/control_panel/control_panel.rs +++ b/src/components/control_panel/control_panel.rs @@ -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; diff --git a/src/components/mod.rs b/src/components/mod.rs index 9e2036c..aa7fded 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -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::*; diff --git a/src/components/monitor/messages.rs b/src/components/monitor/messages.rs index 905faaa..4c28018 100644 --- a/src/components/monitor/messages.rs +++ b/src/components/monitor/messages.rs @@ -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), RemoveWidget, - // AddMetaItem(HashMap), - // ClearMetaItems, - // UpdateMetaItem(HashMap), 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, } diff --git a/src/components/monitor/mod.rs b/src/components/monitor/mod.rs index 6f38e95..62cd692 100644 --- a/src/components/monitor/mod.rs +++ b/src/components/monitor/mod.rs @@ -1,4 +1,6 @@ pub mod messages; pub mod monitor; +pub mod widget; pub use monitor::*; +pub use widget::*; diff --git a/src/components/monitor/monitor.rs b/src/components/monitor/monitor.rs index a1e383a..3757670 100644 --- a/src/components/monitor/monitor.rs +++ b/src/components/monitor/monitor.rs @@ -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}, diff --git a/src/widgets/render/widget/mod.rs b/src/components/monitor/widget/mod.rs similarity index 100% rename from src/widgets/render/widget/mod.rs rename to src/components/monitor/widget/mod.rs diff --git a/src/widgets/render/widget/widget.rs b/src/components/monitor/widget/widget.rs similarity index 72% rename from src/widgets/render/widget/widget.rs rename to src/components/monitor/widget/widget.rs index a4c0bd9..72d10ea 100644 --- a/src/widgets/render/widget/widget.rs +++ b/src/components/monitor/widget/widget.rs @@ -11,8 +11,8 @@ pub enum WidgetType { } pub trait Widget: 'static + Send + Sync { - fn opengl_render(&self, canvas: &mut Canvas, cms: CMS) {} - fn cairo_render(&self, canvas: >k::cairo::Context, w: f32, h: f32) {} + fn opengl_render(&self, layers: &Vec, canvas: &mut Canvas, cms: CMS) {} + fn cairo_render(&self, layers: &Vec, canvas: >k::cairo::Context, w: f32, h: f32) {} fn widget_type(&self) -> WidgetType; fn size(&self) -> (f32, f32); diff --git a/src/components/setting/setting.rs b/src/components/setting/setting.rs index 47f5963..72d4782 100644 --- a/src/components/setting/setting.rs +++ b/src/components/setting/setting.rs @@ -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::*; diff --git a/src/components/sidebar/bottom_bar.rs b/src/components/sidebar/bottom_bar.rs index f13c7bd..0ade008 100644 --- a/src/components/sidebar/bottom_bar.rs +++ b/src/components/sidebar/bottom_bar.rs @@ -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::: &(), } } diff --git a/src/components/sidebar/sidebar.rs b/src/components/sidebar/sidebar.rs index c990132..2cbf2e5 100644 --- a/src/components/sidebar/sidebar.rs +++ b/src/components/sidebar/sidebar.rs @@ -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), 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::>(); + + 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", diff --git a/src/coords/cms.rs b/src/coords/cms.rs index 772b077..9b15764 100644 --- a/src/coords/cms.rs +++ b/src/coords/cms.rs @@ -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 { diff --git a/src/coords/mod.rs b/src/coords/mod.rs index 6a820bd..92d8216 100644 --- a/src/coords/mod.rs +++ b/src/coords/mod.rs @@ -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; diff --git a/src/data/mod.rs b/src/data/mod.rs index 19d15ac..3ffaae6 100644 --- a/src/data/mod.rs +++ b/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 = RadarData2d>; +pub type Radar2d = RadarData2d, OwnedRepr, OwnedRepr>; +pub type Radar3d = RadarData3d, OwnedRepr, OwnedRepr, OwnedRepr>; +pub type Radar2dRef<'a, T> = RadarData2d, ViewRepr<&'a f64>, ViewRepr<&'a f64>>; +pub type Radar3dRef<'a, T> = + RadarData3d, ViewRepr<&'a f64>, ViewRepr<&'a f64>, ViewRepr<&'a f64>>; + +#[derive(Clone, Copy, Debug)] +pub enum CoordType { + Polar, + LatLon, +} pub trait MultiDimensionData where T: Num + Clone + PartialEq + PartialOrd, @@ -24,248 +33,84 @@ where } #[derive(Clone)] -pub struct RadarData2d +pub struct RadarData2d where T: Num + Clone + PartialEq + PartialOrd, - Raw: ndarray::Data + Clone + ndarray::RawDataClone, - X: Num, - Y: Num, + Raw: ndarray::Data + ndarray::RawDataClone, + X: ndarray::Data + ndarray::RawDataClone, + Y: ndarray::Data + ndarray::RawDataClone, { - pub dim1: ArrayBase, I>, - pub dim2: ArrayBase, I>, + pub dim1: ArrayBase, + pub dim2: ArrayBase, pub data: ArrayBase, pub fill_value: T, pub coord_type: CoordType, } -impl Debug for RadarData2d +impl Radar2d where - T: Num + Clone + PartialEq + PartialOrd + Debug, - Raw: ndarray::Data + 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 Radar2d { - pub fn load(path: impl AsRef, meth: impl DataLoader) -> Result { - Ok(meth.load(path)?) - } +#[derive(Clone)] +pub struct RadarData3d +where + T: Num + Clone + PartialEq + PartialOrd, + Raw: ndarray::Data + ndarray::RawDataClone, + X: ndarray::Data + ndarray::RawDataClone, + Y: ndarray::Data + ndarray::RawDataClone, + Z: ndarray::Data + ndarray::RawDataClone, +{ + pub dim1: ArrayBase, + pub dim2: ArrayBase, + pub dim3: ArrayBase, + pub data: ArrayBase, + pub fill_value: T, + pub coord_type: CoordType, } -pub struct RadarData3d +impl RadarData3d where - T: Num, - X: Num, - Y: Num, - Z: Num, + T: Num + Clone + PartialEq + PartialOrd, + X: ndarray::Data + ndarray::RawDataClone, + Y: ndarray::Data + ndarray::RawDataClone, + Z: ndarray::Data + ndarray::RawDataClone, + Raw: ndarray::Data + ndarray::RawDataClone, { - pub dim1: Array1, - pub dim2: Array1, - pub dim3: Array1, - pub data: Array3, -} - -impl RadarData2d -where - T: Num + AsPrimitive + FromPrimitive + Clone + Debug + PartialOrd + PartialEq, - Raw: ndarray::Data + Clone + ndarray::RawDataClone, -{ - pub fn downsample(&self, output_shape: (usize, usize), meth: DownSampleMeth) -> Radar2d { + pub fn index_axis(&self, axis: Axis, slice: usize) -> Radar2dRef { 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 = 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>; 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 MultiDimensionData for RadarData2d +impl MultiDimensionData for RadarData3d where T: Num + Clone, T: PartialEq + PartialOrd, - Raw: ndarray::Data + Clone + RawDataClone + DataMut, + X: ndarray::Data + ndarray::RawDataClone, + Y: ndarray::Data + ndarray::RawDataClone, + Z: ndarray::Data + ndarray::RawDataClone, + Raw: ndarray::Data + RawDataClone + DataMut, { fn map_by_fn(&mut self, f: F) where @@ -275,285 +120,18 @@ where } } -pub trait DataLoader +impl MultiDimensionData for RadarData2d where - V: Num + Clone + PartialEq + PartialOrd, - T: MultiDimensionData, -{ - fn load>(&self, path: P) -> Result; -} - -#[async_trait] -pub trait AsyncDataLoader -where - V: Num + Clone + PartialEq + PartialOrd, - T: MultiDimensionData + Send + Sync, -{ - async fn load + Send>(&self, path: P) -> Result; -} - -pub struct Npz; -impl Npz { - #[inline] - fn load_1d( - &self, - data: &mut NpzArchive, - name: &str, - ) -> Result, DataError> { - // let mut data = npyz::npz::NpzArchive::open(path)?; - let a = data.by_name(name)?.unwrap(); - let b: Vec = a.into_vec().unwrap(); - - Ok(Array1::from_shape_vec(b.len(), b).unwrap()) - } - #[inline] - fn load_2d( - &self, - // path: &Path, - data: &mut NpzArchive, - name: &str, - ) -> Result, 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 = 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>) {} -} - -impl DataLoader>> for Npz -where - T: Num + Clone + Deserialize + FromPrimitive, + T: Num + Clone, T: PartialEq + PartialOrd, + X: ndarray::Data + ndarray::RawDataClone, + Y: ndarray::Data + ndarray::RawDataClone, + Raw: ndarray::Data + RawDataClone + DataMut, { - fn load>(&self, path: P) -> Result>, DataError> { - let mut data: NpzArchive> = npyz::npz::NpzArchive::open(path)?; - let dim1 = self.load_1d::>(&mut data, "lon")?; - let dim2 = self.load_1d::>(&mut data, "lat")?; - let value = self.load_2d::>(&mut data, "value")?; - - Ok(RadarData2d { - dim1: dim1, - dim2: dim2, - fill_value: T::from_f64(-125.0).unwrap(), - data: value, - coord_type: CoordType::LatLon, - }) - } -} - -impl AsyncDataLoader>> 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>, DataError>> - + core::marker::Send - + 'async_trait, - >, - > + fn map_by_fn(&mut self, f: F) where - P: 'async_trait + AsRef + 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::>>(&mut data, "lon")?; - let dim2 = self.load_1d::>>(&mut data, "lat")?; - let value = self.load_2d::>>(&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>, 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, Ix2> = -// Self::_resample(&self.data, width_rate, filter_len); - -// let result: ArrayBase, Ix2> = -// Self::_resample(&width_filtered.t(), height_rate, filter_len) -// .t() -// .to_owned(); - -// let new_dim1: ArrayBase, 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, 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>( -// data: &'a ArrayBase, -// rate: f64, -// filter_len: f64, -// ) -> Array2 -// where -// V: Num + Clone + AsPrimitive + 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 = 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( -// pub Quadtree>>, -// ); - -// impl LevelData -// where -// T: Num + Clone + AsPrimitive + FromPrimitive + Debug + PartialEq + PartialOrd, -// { -// fn value( -// level_data: Vec>>, -// level_num: usize, -// ) -> Vec>> { -// if level_num == 0 { -// return level_data; -// } - -// let mut result: Vec>> = -// 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>, 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>> = -// 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(data: Radar2d, levels: usize) -> Vec> -// where -// T: Num + Clone + AsPrimitive + 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, -} diff --git a/src/data_utils.rs b/src/data_utils.rs index 1975140..17a5b2f 100644 --- a/src/data_utils.rs +++ b/src/data_utils.rs @@ -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)),+) => { diff --git a/src/errors.rs b/src/errors.rs index 0466991..8146cdf 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -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, - } diff --git a/src/map_tile_utils.rs b/src/map_tile_utils.rs index 1aeccff..3288f3b 100644 --- a/src/map_tile_utils.rs +++ b/src/map_tile_utils.rs @@ -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 -} \ No newline at end of file +} diff --git a/src/pipeline/element.rs b/src/pipeline/element.rs index 508add9..0e06ba1 100644 --- a/src/pipeline/element.rs +++ b/src/pipeline/element.rs @@ -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, } +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, @@ -231,6 +235,10 @@ impl TimeSeriesElement { self.cms = cms; } + pub fn imp(&self) -> &Arc { + &self.imp + } + fn register_noti(&self, datetime: DateTime, noti: Arc) { self.registers .lock() diff --git a/src/pipeline/element_impl.rs b/src/pipeline/element_impl.rs index 538d2e4..ea280b8 100644 --- a/src/pipeline/element_impl.rs +++ b/src/pipeline/element_impl.rs @@ -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 @@ -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 = 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 = 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 + } + } } } diff --git a/src/pipeline/mod.rs b/src/pipeline/mod.rs index de3afb7..adf81b4 100644 --- a/src/pipeline/mod.rs +++ b/src/pipeline/mod.rs @@ -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::*; diff --git a/src/pipeline/predefined/grid_field_renderer.rs b/src/pipeline/predefined/grid_field_renderer.rs index f7319bc..2f6165b 100644 --- a/src/pipeline/predefined/grid_field_renderer.rs +++ b/src/pipeline/predefined/grid_field_renderer.rs @@ -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, CMAP: ColorMapper, { - cmap: CMAP, + pub cmap: CMAP, value_phantom: PhantomData, } @@ -61,15 +62,6 @@ impl, 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, 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 DataRenderer for GridFieldRenderer +impl<'a, T, CMAP> DataRenderer<'a> for GridFieldRenderer where T: Num + NumOps + PartialOrd + Copy + Clone + FromPrimitive + AsPrimitive, CMAP: ColorMapper, { - type Data = Radar2d; + 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, Vec> = 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(); diff --git a/src/pipeline/renders.rs b/src/pipeline/renders.rs index 11fbaef..c2e0a8b 100644 --- a/src/pipeline/renders.rs +++ b/src/pipeline/renders.rs @@ -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, diff --git a/src/pipeline/utils.rs b/src/pipeline/utils.rs index 206dae2..dec9d30 100644 --- a/src/pipeline/utils.rs +++ b/src/pipeline/utils.rs @@ -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::*; diff --git a/src/plugin_system/utils.rs b/src/plugin_system/utils.rs index 534b1b2..f1ccbd4 100644 --- a/src/plugin_system/utils.rs +++ b/src/plugin_system/utils.rs @@ -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 = $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::>()).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 From for Radar3d +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"); + } + } +} diff --git a/src/widgets/render/predefined/color_mapper.rs b/src/predefined/color_mapper.rs similarity index 100% rename from src/widgets/render/predefined/color_mapper.rs rename to src/predefined/color_mapper.rs diff --git a/src/predefined/map_tile.rs b/src/predefined/map_tile.rs index 0eddb26..be48e2b 100644 --- a/src/predefined/map_tile.rs +++ b/src/predefined/map_tile.rs @@ -1,20 +1,25 @@ 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] fn test_map_tile_layer() { map_tile_layer((37.7749, 37.7749), (-122.4194, -122.4194), 1000.0, 1000.0); } -} \ No newline at end of file +} diff --git a/src/predefined/mod.rs b/src/predefined/mod.rs index 69ed738..27d7a1e 100644 --- a/src/predefined/mod.rs +++ b/src/predefined/mod.rs @@ -1 +1,5 @@ -pub mod map_tile; \ No newline at end of file +pub mod map_tile; +// pub mod grid_field_renderer; +// pub mod layers; +pub mod color_mapper; +pub mod widgets; diff --git a/src/predefined/widgets.rs b/src/predefined/widgets.rs new file mode 100644 index 0000000..3d4dd0b --- /dev/null +++ b/src/predefined/widgets.rs @@ -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, 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] + } +} diff --git a/src/utils.rs b/src/utils.rs index c29d9f5..614dc21 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -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; diff --git a/src/widgets/dynamic_col/custom_layout/imp.rs b/src/widgets/dynamic_col/custom_layout/imp.rs index e69de29..8b13789 100644 --- a/src/widgets/dynamic_col/custom_layout/imp.rs +++ b/src/widgets/dynamic_col/custom_layout/imp.rs @@ -0,0 +1 @@ + diff --git a/src/widgets/render/cms.rs b/src/widgets/render/cms.rs index 8a15fab..f3bd9f1 100644 --- a/src/widgets/render/cms.rs +++ b/src/widgets/render/cms.rs @@ -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, diff --git a/src/widgets/render/exterior/imp.rs b/src/widgets/render/exterior/imp.rs index 7ac841f..0e0490b 100644 --- a/src/widgets/render/exterior/imp.rs +++ b/src/widgets/render/exterior/imp.rs @@ -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 {} diff --git a/src/widgets/render/interior/imp.rs b/src/widgets/render/interior/imp.rs index 563a69d..a4ef2fd 100644 --- a/src/widgets/render/interior/imp.rs +++ b/src/widgets/render/interior/imp.rs @@ -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 { diff --git a/src/widgets/render/interior/layers.rs b/src/widgets/render/interior/layers.rs index 442ea77..4a6c630 100644 --- a/src/widgets/render/interior/layers.rs +++ b/src/widgets/render/interior/layers.rs @@ -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}, }; diff --git a/src/widgets/render/mod.rs b/src/widgets/render/mod.rs index 97a738d..3e85cc2 100644 --- a/src/widgets/render/mod.rs +++ b/src/widgets/render/mod.rs @@ -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}; diff --git a/src/widgets/render/predefined/mod.rs b/src/widgets/render/predefined/mod.rs index 98790b3..5dc5f46 100644 --- a/src/widgets/render/predefined/mod.rs +++ b/src/widgets/render/predefined/mod.rs @@ -1,5 +1 @@ -pub mod color_mapper; pub mod gis; -// pub mod grid_field_renderer; -// pub mod layers; -pub mod widgets; diff --git a/src/widgets/render/predefined/widgets.rs b/src/widgets/render/predefined/widgets.rs deleted file mode 100644 index 117b21b..0000000 --- a/src/widgets/render/predefined/widgets.rs +++ /dev/null @@ -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 -where - V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive, - T: ColorMapper, -{ - color_mapper: T, - padding: [f32; 4], - width: f32, - height: f32, - margin: [i32; 4], - color_list: Vec, - phantom: std::marker::PhantomData, -} - -impl ColorBar -where - V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive, - T: ColorMapper, -{ - 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 WidgetTrait for ColorBar -where - V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive + Send + Sync, - T: ColorMapper + '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] - } -} diff --git a/src/widgets/render/renders.rs b/src/widgets/render/renders.rs index 7b8dd6d..1afab19 100644 --- a/src/widgets/render/renders.rs +++ b/src/widgets/render/renders.rs @@ -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; diff --git a/src/widgets/widget_frame/imp.rs b/src/widgets/widget_frame/imp.rs index 2592474..d746fb2 100644 --- a/src/widgets/widget_frame/imp.rs +++ b/src/widgets/widget_frame/imp.rs @@ -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::*; diff --git a/src/widgets/widget_frame/mod.rs b/src/widgets/widget_frame/mod.rs index 8de6489..b2a34d3 100644 --- a/src/widgets/widget_frame/mod.rs +++ b/src/widgets/widget_frame/mod.rs @@ -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(); }