sidebar
This commit is contained in:
parent
79189212c2
commit
322461371f
243
Cargo.lock
generated
243
Cargo.lock
generated
@ -78,13 +78,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.73"
|
||||
version = "0.1.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
|
||||
checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -149,8 +149,8 @@ dependencies = [
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
@ -208,6 +208,12 @@ version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
version = "0.4.4"
|
||||
@ -308,6 +314,7 @@ name = "cinrad_g"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"cairo-rs",
|
||||
"epoxy",
|
||||
"femtovg",
|
||||
@ -322,11 +329,13 @@ dependencies = [
|
||||
"glue",
|
||||
"gtk4",
|
||||
"image",
|
||||
"lazy_static",
|
||||
"libadwaita",
|
||||
"libloading 0.8.0",
|
||||
"ndarray",
|
||||
"npyz",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"plotters",
|
||||
"plotters-backend",
|
||||
"proj",
|
||||
@ -335,6 +344,7 @@ dependencies = [
|
||||
"quadtree_rs",
|
||||
"relm4",
|
||||
"relm4-components",
|
||||
"relm4-icons",
|
||||
"rstar",
|
||||
"shapefile",
|
||||
"svg",
|
||||
@ -941,9 +951,9 @@ version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1075,9 +1085,9 @@ dependencies = [
|
||||
name = "geo-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1239,8 +1249,8 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
@ -1380,8 +1390,8 @@ dependencies = [
|
||||
"anyhow",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
@ -1404,6 +1414,24 @@ dependencies = [
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gvdb"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7139233c0ecb66f285c47a3c1c02b35c8d52a42ca4c7448d0163e5637bb4bd3"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"flate2",
|
||||
"lazy_static",
|
||||
"memmap2",
|
||||
"quick-xml",
|
||||
"safe-transmute",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"walkdir",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.2.1"
|
||||
@ -1730,6 +1758,15 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.0"
|
||||
@ -1930,9 +1967,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
@ -2055,9 +2092,9 @@ checksum = "b3e8cba4ec22bada7fc55ffe51e2deb6a0e0db2d0b7ab0b103acc80d2510c190"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2086,9 +2123,9 @@ version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2185,8 +2222,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
@ -2197,8 +2234,8 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
@ -2219,9 +2256,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.63"
|
||||
version = "1.0.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
|
||||
checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -2293,6 +2330,16 @@ dependencies = [
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
@ -2304,11 +2351,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.29"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"proc-macro2 1.0.76",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2420,15 +2467,25 @@ dependencies = [
|
||||
"tracker",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "relm4-icons"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e28bcc718a587bcfa31b034e0b8f4efe5b70e945b7de9d7d154b45357a0dadc"
|
||||
dependencies = [
|
||||
"gtk4",
|
||||
"gvdb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "relm4-macros"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad8d946cf33654b1df3e2e7d1c4952a154f008368cdda03a99c1840a6fcab3b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2500,6 +2557,12 @@ version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
|
||||
[[package]]
|
||||
name = "safe-transmute"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98a01dab6acf992653be49205bdd549f32f17cb2803e8eacf1560bf97259aae8"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
@ -2542,9 +2605,9 @@ version = "1.0.164"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2661,6 +2724,12 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.7.0"
|
||||
@ -2702,19 +2771,19 @@ version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.29"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
@ -2781,9 +2850,9 @@ version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2820,8 +2889,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"tokio-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2888,9 +2970,9 @@ version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2917,9 +2999,9 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca029746fbe0efda3298205de77bf759d7fef23ac97902641e0b49a623b0455f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3053,9 +3135,9 @@ dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -3065,7 +3147,7 @@ version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
|
||||
dependencies = [
|
||||
"quote 1.0.29",
|
||||
"quote 1.0.35",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
@ -3075,9 +3157,9 @@ version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.63",
|
||||
"quote 1.0.29",
|
||||
"syn 2.0.29",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 2.0.48",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -3394,3 +3476,40 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "3.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44b291bee0d960c53170780af148dca5fa260a63cdd24f1962fa82e03e53338c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"libc",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"zvariant_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_derive"
|
||||
version = "3.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "934d7a7dfc310d6ee06c87ffe88ef4eca7d3e37bb251dece2ef93da8f17d8ecd"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 1.0.109",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_utils"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.76",
|
||||
"quote 1.0.35",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
@ -40,14 +40,17 @@ topojson = "0.5.1"
|
||||
geojson = "0.24.1"
|
||||
plotters = "0.3.5"
|
||||
plotters-backend = "0.3.5"
|
||||
tokio = "1.35.1"
|
||||
tokio = { version = "1.35.1", features = ["time", "fs", "io-std", "macros", "num_cpus", "bytes", "io-util"] }
|
||||
async-trait = "0.1.77"
|
||||
lazy_static = "1.4.0"
|
||||
once_cell = "1.19.0"
|
||||
relm4-icons = "0.6.0"
|
||||
# plotters-cairo = "0.5.0"
|
||||
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
glib-build-tools = "0.17.0"
|
||||
|
||||
[dependencies.geo-macros]
|
||||
path = "geo-macros"
|
||||
|
||||
|
||||
178
back.txt
178
back.txt
@ -85,3 +85,181 @@
|
||||
// Npz,
|
||||
// BoundaryNorm::default(),
|
||||
// )
|
||||
|
||||
|
||||
|
||||
// fn resample(
|
||||
// &self,
|
||||
// width_rate: f64,
|
||||
// height_rate: f64,
|
||||
// filter_len: f64,
|
||||
// ) -> Result<RadarData2d<T, OwnedRepr<T>>, DataError> {
|
||||
// let width_rate = width_rate.min(1.0);
|
||||
// let height_rate = height_rate.min(1.0);
|
||||
// match self.coord_type {
|
||||
// CoordType::Polar => Err(DataError::FormatError),
|
||||
// CoordType::LatLon => {
|
||||
// let width_filtered: ArrayBase<ndarray::OwnedRepr<T>, Ix2> =
|
||||
// Self::_resample(&self.data, width_rate, filter_len);
|
||||
|
||||
// let result: ArrayBase<OwnedRepr<T>, Ix2> =
|
||||
// Self::_resample(&width_filtered.t(), height_rate, filter_len)
|
||||
// .t()
|
||||
// .to_owned();
|
||||
|
||||
// let new_dim1: ArrayBase<OwnedRepr<f64>, Ix1> = Self::_resample(
|
||||
// &Array2::from_shape_vec((1, self.dim1.len()), self.dim1.to_vec()).unwrap(),
|
||||
// width_rate,
|
||||
// filter_len,
|
||||
// )
|
||||
// .slice(s![0, ..])
|
||||
// .to_owned();
|
||||
|
||||
// let new_dim2: ArrayBase<OwnedRepr<f64>, Ix1> = Self::_resample(
|
||||
// &Array2::from_shape_vec((1, self.dim2.len()), self.dim2.to_vec()).unwrap(),
|
||||
// height_rate,
|
||||
// filter_len,
|
||||
// )
|
||||
// .slice(s![0, ..])
|
||||
// .to_owned();
|
||||
|
||||
// Ok(RadarData2d {
|
||||
// dim1: new_dim1,
|
||||
// dim2: new_dim2,
|
||||
// data: result,
|
||||
// coord_type: self.coord_type.to_owned(),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// fn _resample<'a, V, R: ndarray::Data<Elem = V>>(
|
||||
// data: &'a ArrayBase<R, Ix2>,
|
||||
// rate: f64,
|
||||
// filter_len: f64,
|
||||
// ) -> Array2<V>
|
||||
// where
|
||||
// V: Num + Clone + AsPrimitive<f64> + FromPrimitive,
|
||||
// {
|
||||
// let ori_width = data.ncols();
|
||||
// let ori_height = data.nrows();
|
||||
|
||||
// let new_width = (ori_width as f64 * rate).ceil() as usize;
|
||||
// let mut result: Array2<V> = Array2::zeros((ori_height, new_width));
|
||||
// (0..ori_height).into_iter().for_each(|height| {
|
||||
// for width in 0..new_width {
|
||||
// let center_x = (width as f64 + 0.5) / new_width as f64 * ori_width as f64;
|
||||
// let filter_start = center_x - filter_len / 2.0;
|
||||
// let start_idx = (filter_start - 0.5).ceil() as usize;
|
||||
|
||||
// let mut value_sum = 0.0;
|
||||
// let mut filter_sum = 0.0;
|
||||
|
||||
// for i in 0..filter_len as usize {
|
||||
// let input_x = start_idx + i;
|
||||
// let weight = windowed_sinc(
|
||||
// (input_x as f64 + 0.5 - center_x) * rate,
|
||||
// (input_x as f64 + 0.5 - filter_start) / filter_len,
|
||||
// );
|
||||
// value_sum += weight * data[[height, input_x.clamp(0, ori_width - 1)]].as_();
|
||||
// filter_sum += weight;
|
||||
// }
|
||||
|
||||
// result[[height, width]] = V::from_f64(value_sum / filter_sum).unwrap();
|
||||
// }
|
||||
// });
|
||||
// result
|
||||
// }
|
||||
|
||||
// pub struct LevelData<T: Num + Clone + PartialEq + PartialOrd>(
|
||||
// pub Quadtree<i64, RadarData2d<T, OwnedRepr<T>>>,
|
||||
// );
|
||||
|
||||
// impl<T> LevelData<T>
|
||||
// where
|
||||
// T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug + PartialEq + PartialOrd,
|
||||
// {
|
||||
// fn value(
|
||||
// level_data: Vec<RadarData2d<T, OwnedRepr<T>>>,
|
||||
// level_num: usize,
|
||||
// ) -> Vec<RadarData2d<T, OwnedRepr<T>>> {
|
||||
// if level_num == 0 {
|
||||
// return level_data;
|
||||
// }
|
||||
|
||||
// let mut result: Vec<RadarData2d<T, OwnedRepr<T>>> =
|
||||
// Vec::with_capacity(level_data.len() * 4);
|
||||
|
||||
// let results = level_data
|
||||
// .iter()
|
||||
// .flat_map(|v| v.split().into_iter().map(|x| x.value_to_owned()));
|
||||
|
||||
// result.extend(results);
|
||||
|
||||
// return Self::value(result, level_num - 1);
|
||||
// }
|
||||
|
||||
// fn new(data: &RadarData2d<T, OwnedRepr<T>>, level: usize, rate: f64) -> Self {
|
||||
// // let rate = 1.0 / level as f64;
|
||||
// let resampled = data.resample(rate, rate, 2.0).unwrap();
|
||||
// let blocks = Self::value(vec![resampled], level);
|
||||
// let mut tree: Quadtree<i64, RadarData2d<T, OwnedRepr<T>>> =
|
||||
// quadtree_rs::Quadtree::new(level);
|
||||
|
||||
// blocks.into_iter().for_each(|block| {
|
||||
// tree.insert(
|
||||
// AreaBuilder::default()
|
||||
// .anchor(quadtree_rs::point::Point {
|
||||
// x: *block.dim1.first().unwrap() as i64,
|
||||
// y: *block.dim2.first().unwrap() as i64,
|
||||
// })
|
||||
// .dimensions((block.dim1.len() as i64, block.dim2.len() as i64))
|
||||
// .build()
|
||||
// .unwrap(),
|
||||
// block,
|
||||
// );
|
||||
// });
|
||||
|
||||
// Self(tree)
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn levels<T>(data: Radar2d<T>, levels: usize) -> Vec<LevelData<T>>
|
||||
// where
|
||||
// T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug,
|
||||
// T: PartialEq + PartialOrd,
|
||||
// {
|
||||
// let numerator = 1.0 / levels as f64;
|
||||
// (0..levels)
|
||||
// .into_iter()
|
||||
// .map(|level| LevelData::new(&data, level + 1, 1.0 - level as f64 * numerator))
|
||||
// .collect()
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#[inline]
|
||||
fn windowed_sinc(x: f64, y: f64) -> f64 {
|
||||
let x = x * PI;
|
||||
let sinc = if x != 0.0 { f64::sin(x) / x } else { 1.0 };
|
||||
let window = if 0f64 <= y && y <= 1.0 {
|
||||
1.0 - (y - 0.5).abs() * 2.0
|
||||
} else {
|
||||
0f64
|
||||
};
|
||||
sinc * window
|
||||
}
|
||||
|
||||
pub enum DownSampleMeth {
|
||||
STD,
|
||||
MEAN,
|
||||
VAR,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum CoordType {
|
||||
Polar,
|
||||
LatLon,
|
||||
}
|
||||
@ -59,21 +59,6 @@ impl SimpleComponent for AppModel {
|
||||
gtk::Inhibit(true)
|
||||
}
|
||||
}
|
||||
// main_window = gtk::ApplicationWindow {
|
||||
// set_default_width: 1200,
|
||||
// set_default_height: 900,
|
||||
// set_focus_on_click:true,
|
||||
// set_titlebar: Some(>k::HeaderBar::new()),
|
||||
// gtk::Box{
|
||||
// set_orientation: gtk::Orientation::Vertical,
|
||||
// set_valign:gtk::Align::Fill,
|
||||
|
||||
// },
|
||||
// connect_close_request[sender] => move |_| {
|
||||
// sender.input(AppMsg::CloseRequest);
|
||||
// gtk::Inhibit(true)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fn init(
|
||||
|
||||
0
src/components/monitor/render/render.rs
Normal file
0
src/components/monitor/render/render.rs
Normal file
@ -1,4 +1,4 @@
|
||||
mod render_panel;
|
||||
mod messages;
|
||||
mod monitor;
|
||||
mod render_panel;
|
||||
pub use render_panel::RenderPanelModel;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
pub mod monitor;
|
||||
pub mod render;
|
||||
pub mod sidebar;
|
||||
pub use monitor::MonitorModel;
|
||||
|
||||
@ -1,11 +1,18 @@
|
||||
use crate::{
|
||||
components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg},
|
||||
render::{Layer, Render},
|
||||
data::Npz,
|
||||
render::{predefined::color_mapper::BoundaryNorm, Layer, Render},
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{render::render::RenderModel, sidebar::{sidebar::SideBarModel, SideBarOutputMsg}};
|
||||
use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg};
|
||||
use adw::prelude::*;
|
||||
use relm4::*;
|
||||
use gtk::subclass::root;
|
||||
use relm4::{
|
||||
component::{AsyncComponent, AsyncComponentParts},
|
||||
loading_widgets::LoadingWidgets,
|
||||
*,
|
||||
};
|
||||
pub struct MonitorModel {
|
||||
sidebar_open: bool,
|
||||
sidebar_width: i32,
|
||||
@ -17,11 +24,12 @@ pub struct MonitorWidgets {
|
||||
paned: gtk::Paned,
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for MonitorModel {
|
||||
#[relm4::component(async, pub)]
|
||||
impl AsyncComponent for MonitorModel {
|
||||
type Init = ();
|
||||
type Output = MonitorOutputMsg;
|
||||
type Input = MonitorInputMsg;
|
||||
type CommandOutput = ();
|
||||
|
||||
view! {
|
||||
adw::BreakpointBin {
|
||||
@ -44,16 +52,18 @@ impl SimpleComponent for MonitorModel {
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
async fn init(
|
||||
init: Self::Init,
|
||||
root: &Self::Root,
|
||||
sender: relm4::ComponentSender<Self>,
|
||||
) -> relm4::ComponentParts<Self> {
|
||||
let sidebar: Controller<SideBarModel> = SideBarModel::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| match msg {
|
||||
SideBarOutputMsg::NewLayer(layer) => MonitorInputMsg::AddLayer(layer),
|
||||
});
|
||||
root: Self::Root,
|
||||
sender: relm4::AsyncComponentSender<Self>,
|
||||
) -> AsyncComponentParts<Self> {
|
||||
let sidebar: Controller<SideBarModel> =
|
||||
SideBarModel::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| match msg {
|
||||
SideBarOutputMsg::NewLayer(layer) => MonitorInputMsg::AddLayer(layer),
|
||||
_ => MonitorInputMsg::None,
|
||||
});
|
||||
let model = MonitorModel {
|
||||
sidebar_open: true,
|
||||
sidebar_width: 400,
|
||||
@ -62,10 +72,16 @@ impl SimpleComponent for MonitorModel {
|
||||
};
|
||||
|
||||
let widgets = view_output! {};
|
||||
ComponentParts { model, widgets }
|
||||
AsyncComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
|
||||
async fn update(
|
||||
&mut self,
|
||||
msg: Self::Input,
|
||||
_sender: AsyncComponentSender<Self>,
|
||||
_root: &Self::Root,
|
||||
) {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
match msg {
|
||||
MonitorInputMsg::AddLayer(layer) => {
|
||||
self.layers.push(layer);
|
||||
@ -73,6 +89,10 @@ impl SimpleComponent for MonitorModel {
|
||||
.output_sender()
|
||||
.send(MonitorOutputMsg::LayerAdded(0))
|
||||
.unwrap();
|
||||
|
||||
self.sidebar
|
||||
.sender()
|
||||
.send(Msg::RefreshList(self.layers.clone()));
|
||||
}
|
||||
MonitorInputMsg::RemoveLayer(index) => {
|
||||
self.layers.remove(index);
|
||||
@ -91,5 +111,4 @@ impl SimpleComponent for MonitorModel {
|
||||
MonitorInputMsg::None => {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
pub mod render;
|
||||
pub use render::*;
|
||||
@ -1,40 +0,0 @@
|
||||
use crate::coords::proj::Mercator;
|
||||
use crate::coords::Mapper;
|
||||
use crate::render::{Render, RenderConfig};
|
||||
use relm4::*;
|
||||
|
||||
pub struct RenderModel {
|
||||
config: RenderConfig,
|
||||
mapper: Mapper,
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for RenderModel {
|
||||
type Init = (Option<Mapper>, Option<RenderConfig>);
|
||||
type Output = ();
|
||||
type Input = ();
|
||||
|
||||
view! {
|
||||
Render{
|
||||
set_mapper = model.mapper.clone(),
|
||||
set_cfg = model.config.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
init: Self::Init,
|
||||
root: &Self::Root,
|
||||
sender: relm4::ComponentSender<Self>,
|
||||
) -> relm4::ComponentParts<Self> {
|
||||
let (mapper, config) = init;
|
||||
let config = config.unwrap_or(RenderConfig::default());
|
||||
let mapper = mapper.unwrap_or(Mercator::default().into());
|
||||
|
||||
let model = RenderModel { config, mapper };
|
||||
let widgets = view_output!();
|
||||
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {}
|
||||
}
|
||||
51
src/components/render_panel/monitor/sidebar/bottom_bar.rs
Normal file
51
src/components/render_panel/monitor/sidebar/bottom_bar.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use gtk::prelude::*;
|
||||
use relm4::{
|
||||
factory::FactoryView,
|
||||
gtk,
|
||||
prelude::{DynamicIndex, FactoryComponent},
|
||||
FactorySender,
|
||||
};
|
||||
|
||||
use super::Msg;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TestMsg {
|
||||
Delete,
|
||||
MoveUp,
|
||||
MoveDown,
|
||||
Add,
|
||||
}
|
||||
|
||||
pub struct BottomBarModel {
|
||||
icon: String,
|
||||
msg: TestMsg,
|
||||
}
|
||||
|
||||
#[relm4::factory(pub)]
|
||||
impl FactoryComponent for BottomBarModel {
|
||||
type ParentWidget = gtk::Box;
|
||||
type ParentInput = Msg;
|
||||
type Input = ();
|
||||
type Output = TextMsg;
|
||||
type Init = BottomBarModel;
|
||||
type CommandOutput = ();
|
||||
|
||||
view! {
|
||||
#[root]
|
||||
gtk::Box{
|
||||
gtk::Button{
|
||||
#[wrap(Some)]
|
||||
set_icon_name= model.icon.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn init_model(init: Self::Init, index: &DynamicIndex, sender: FactorySender<Self>) -> Self {
|
||||
init
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Input, sender: FactorySender<Self>) {
|
||||
match message {}
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod sidebar;
|
||||
pub use sidebar::*;
|
||||
pub mod bottom_bar;
|
||||
|
||||
@ -1,23 +1,30 @@
|
||||
use glib::clone;
|
||||
use gtk::prelude::WidgetExt;
|
||||
use gtk::prelude::*;
|
||||
use relm4::{
|
||||
binding::{Binding, U8Binding},
|
||||
factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque},
|
||||
prelude::*,
|
||||
typed_list_view::{RelmListItem, TypedListView},
|
||||
RelmObjectExt,
|
||||
};
|
||||
|
||||
use crate::{chart::Chart, render::{Layer, predefined::color_mapper::BoundaryNorm}, data::Npz};
|
||||
use crate::{
|
||||
chart::Chart,
|
||||
data::Npz,
|
||||
render::{predefined::color_mapper::BoundaryNorm, Layer},
|
||||
};
|
||||
|
||||
use super::bottom_bar::BottomBarModel;
|
||||
pub struct SideBarModel {
|
||||
counter: u8,
|
||||
list_view_wrapper: TypedListView<MyListItem, gtk::SingleSelection>,
|
||||
list_view_wrapper: TypedListView<LayerItem, gtk::SingleSelection>,
|
||||
bottom_bar_vec: FactoryVecDeque<BottomBarModel>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Msg {
|
||||
Append,
|
||||
Remove,
|
||||
OnlyShowEven(bool),
|
||||
RefreshList(Vec<Layer>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -32,13 +39,24 @@ impl SimpleComponent for SideBarModel {
|
||||
type Input = Msg;
|
||||
|
||||
view! {
|
||||
gtk::Box {
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
set_margin_all: 5,
|
||||
|
||||
gtk::Paned{
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_position: 300,
|
||||
#[wrap(Some)]
|
||||
set_start_child = >k::Box{
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_spacing: 5,
|
||||
set_margin_all: 5,
|
||||
gtk::Notebook {
|
||||
set_vexpand: true,
|
||||
append_page:(&page_1, Some(&label)),
|
||||
#[local]
|
||||
top_panel -> gtk::Notebook{},
|
||||
gtk::Button {
|
||||
set_label: "Add Layers",
|
||||
connect_clicked[sender] => move |_| {
|
||||
},
|
||||
},
|
||||
gtk::Button {
|
||||
set_label: "Add Layer",
|
||||
@ -47,6 +65,7 @@ impl SimpleComponent for SideBarModel {
|
||||
SideBarOutputMsg::NewLayer(
|
||||
Layer::grid_render_layer_with_path(
|
||||
"/users/tsuki/projects/radar-g/test2.npz",
|
||||
"DBZ".to_string(),
|
||||
Npz,
|
||||
BoundaryNorm::default(),
|
||||
)
|
||||
@ -54,13 +73,26 @@ impl SimpleComponent for SideBarModel {
|
||||
).unwrap()
|
||||
},
|
||||
},
|
||||
gtk::ScrolledWindow {
|
||||
set_vexpand: true,
|
||||
#[local_ref]
|
||||
my_view -> gtk::ListView {}
|
||||
}
|
||||
},
|
||||
|
||||
#[wrap(Some)]
|
||||
set_end_child=>k::Box{
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
set_vexpand: true,
|
||||
set_hexpand: true,
|
||||
#[local]
|
||||
bottom_panel -> gtk::Notebook{
|
||||
set_margin_top: 10,
|
||||
set_margin_bottom: 10,
|
||||
},
|
||||
#[local_ref]
|
||||
counter_box -> gtk::Box{}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fn init(
|
||||
init: Self::Init,
|
||||
@ -68,33 +100,33 @@ impl SimpleComponent for SideBarModel {
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
// Initialize the ListView wrapper
|
||||
let mut list_view_wrapper: TypedListView<MyListItem, gtk::SingleSelection> =
|
||||
let mut list_view_wrapper: TypedListView<LayerItem, gtk::SingleSelection> =
|
||||
TypedListView::with_sorting();
|
||||
|
||||
// Add a filter and disable it
|
||||
list_view_wrapper.add_filter(|item| item.value % 2 == 0);
|
||||
list_view_wrapper.set_filter_status(0, false);
|
||||
let bottom_bar_vec = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
||||
|
||||
let model = SideBarModel {
|
||||
counter: 0,
|
||||
list_view_wrapper,
|
||||
bottom_bar_vec,
|
||||
};
|
||||
let my_view = &model.list_view_wrapper.view;
|
||||
|
||||
let page_1 = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
let my_view = &model.list_view_wrapper.view;
|
||||
let top_panel = gtk::Notebook::builder().vexpand(true).build();
|
||||
top_panel.append_page(&Chart::new(), Some(>k::Label::new(Some("Chart"))));
|
||||
|
||||
let bottom_panel = gtk::Notebook::builder().vexpand(true).build();
|
||||
let layer_page = gtk::ScrolledWindow::builder()
|
||||
.vexpand(true)
|
||||
.hexpand(true)
|
||||
.build();
|
||||
|
||||
let chart = Chart::new();
|
||||
let counter_box = model.bottom_bar_vec.widgets();
|
||||
|
||||
chart.connect_resize(clone!(@weak chart as my_view => move |_, w,h|{
|
||||
my_view.set_height_request((w as f32 / 16.0 * 3.0) as i32);
|
||||
}));
|
||||
|
||||
page_1.append(&chart);
|
||||
let label = gtk::Label::new(Some("Page 1"));
|
||||
layer_page.set_child(Some(my_view));
|
||||
layer_page.set_margin_horizontal(5);
|
||||
layer_page.set_margin_vertical(3);
|
||||
bottom_panel.append_page(&layer_page, Some(>k::Label::new(Some("Layers"))));
|
||||
|
||||
let widgets = view_output!();
|
||||
ComponentParts { model, widgets }
|
||||
@ -102,49 +134,33 @@ impl SimpleComponent for SideBarModel {
|
||||
|
||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||
match message {
|
||||
Msg::Append => {
|
||||
// Add 10 items
|
||||
for _ in 0..10 {
|
||||
self.counter = self.counter.wrapping_add(1);
|
||||
self.list_view_wrapper.append(MyListItem::new(self.counter));
|
||||
Msg::RefreshList(layers) => {
|
||||
for layer in layers {
|
||||
self.list_view_wrapper
|
||||
.append(LayerItem::new(layer.name, true));
|
||||
}
|
||||
|
||||
// Count up the first item
|
||||
let first_item = self.list_view_wrapper.get(0).unwrap();
|
||||
let first_binding = &mut first_item.borrow_mut().binding;
|
||||
let mut guard = first_binding.guard();
|
||||
*guard += 1;
|
||||
}
|
||||
Msg::Remove => {
|
||||
// Remove the second item
|
||||
self.list_view_wrapper.remove(1);
|
||||
}
|
||||
Msg::OnlyShowEven(show_only_even) => {
|
||||
// Disable or enable the first filter
|
||||
self.list_view_wrapper.set_filter_status(0, show_only_even);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct MyListItem {
|
||||
value: u8,
|
||||
binding: U8Binding,
|
||||
struct LayerItem {
|
||||
layer_name: String,
|
||||
visiable: bool,
|
||||
}
|
||||
|
||||
impl MyListItem {
|
||||
fn new(value: u8) -> Self {
|
||||
impl LayerItem {
|
||||
fn new(name: String, visiable: bool) -> Self {
|
||||
Self {
|
||||
value,
|
||||
binding: U8Binding::new(0),
|
||||
layer_name: name,
|
||||
visiable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Widgets {
|
||||
label: gtk::Label,
|
||||
label2: gtk::Label,
|
||||
button: gtk::CheckButton,
|
||||
}
|
||||
|
||||
@ -154,7 +170,7 @@ impl Drop for Widgets {
|
||||
}
|
||||
}
|
||||
|
||||
impl RelmListItem for MyListItem {
|
||||
impl RelmListItem for LayerItem {
|
||||
type Root = gtk::Box;
|
||||
type Widgets = Widgets;
|
||||
|
||||
@ -162,34 +178,28 @@ impl RelmListItem for MyListItem {
|
||||
relm4::view! {
|
||||
my_box = gtk::Box {
|
||||
#[name = "label"]
|
||||
gtk::Label,
|
||||
|
||||
#[name = "label2"]
|
||||
gtk::Label,
|
||||
|
||||
gtk::Label{
|
||||
set_halign: gtk::Align::Start,
|
||||
},
|
||||
gtk::Label{
|
||||
set_hexpand: true,
|
||||
},
|
||||
#[name = "button"]
|
||||
gtk::CheckButton,
|
||||
gtk::CheckButton{
|
||||
set_halign: gtk::Align::End,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let widgets = Widgets {
|
||||
label,
|
||||
label2,
|
||||
button,
|
||||
};
|
||||
let widgets = Widgets { label, button };
|
||||
|
||||
(my_box, widgets)
|
||||
}
|
||||
|
||||
fn bind(&mut self, widgets: &mut Self::Widgets, _root: &mut Self::Root) {
|
||||
let Widgets {
|
||||
label,
|
||||
label2,
|
||||
button,
|
||||
} = widgets;
|
||||
let Widgets { label, button } = widgets;
|
||||
|
||||
label.set_label(&format!("Value: {} ", self.value));
|
||||
label2.add_write_only_binding(&self.binding, "label");
|
||||
button.set_active(self.value % 2 == 0);
|
||||
label.set_label(&format!("Layer: {} ", &self.layer_name));
|
||||
button.set_active(self.visiable);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,15 @@
|
||||
use super::messages::RenderInputMsg;
|
||||
use gtk::prelude::*;
|
||||
use super::monitor::MonitorModel;
|
||||
use relm4::*;
|
||||
use gtk::prelude::*;
|
||||
use relm4::component::AsyncComponentController;
|
||||
use relm4::{
|
||||
component::{AsyncComponent, AsyncController},
|
||||
RelmWidgetExt, *,
|
||||
};
|
||||
|
||||
pub struct RenderPanelModel {
|
||||
monitor: Controller<MonitorModel>,
|
||||
// monitor: Controller<MonitorModel>,
|
||||
monitor: AsyncController<MonitorModel>,
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
@ -26,7 +32,8 @@ impl SimpleComponent for RenderPanelModel {
|
||||
root: &Self::Root,
|
||||
sender: relm4::ComponentSender<Self>,
|
||||
) -> relm4::ComponentParts<Self> {
|
||||
let monitor: Controller<MonitorModel> = MonitorModel::builder()
|
||||
|
||||
let monitor: AsyncController<MonitorModel> = MonitorModel::builder()
|
||||
.launch(())
|
||||
.forward(sender.input_sender(), |msg| {});
|
||||
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
use crate::errors::DataError;
|
||||
use image::RgbImage;
|
||||
use async_trait::async_trait;
|
||||
use ndarray::{
|
||||
s, Array, Array1, Array2, Array3, ArrayBase, Axis, DataMut, Dimension, Ix1, Ix2, OwnedRepr,
|
||||
RawDataClone, ViewRepr,
|
||||
s, Array1, Array2, Array3, ArrayBase, DataMut, Dimension, Ix1, Ix2, OwnedRepr, RawDataClone,
|
||||
};
|
||||
use npyz::{npz::NpzArchive, Deserialize};
|
||||
use num_traits::{AsPrimitive, FromPrimitive, Num};
|
||||
use std::io::{Cursor, Seek};
|
||||
use std::{self, f64::consts::PI, fmt::Debug, io::BufReader, path::Path};
|
||||
use tokio::fs::File;
|
||||
use tokio::io::{self, AsyncReadExt};
|
||||
|
||||
pub type Radar2d<T> = RadarData2d<T, OwnedRepr<T>>;
|
||||
|
||||
@ -107,7 +109,6 @@ where
|
||||
*self.dim2.last().unwrap(),
|
||||
output_shape.0,
|
||||
);
|
||||
// let mut dim2 = Array1::zeros(output_shape.0);
|
||||
|
||||
output.iter_mut().enumerate().for_each(|(s, vv)| {
|
||||
let ri = s / output_shape.1;
|
||||
@ -280,13 +281,21 @@ where
|
||||
fn load<P: AsRef<Path>>(&self, path: P) -> Result<T, DataError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait AsyncDataLoader<V, T>
|
||||
where
|
||||
V: Num + Clone + PartialEq + PartialOrd,
|
||||
T: MultiDimensionData<V> + Send + Sync,
|
||||
{
|
||||
async fn load<P: AsRef<Path> + Send>(&self, path: P) -> Result<T, DataError>;
|
||||
}
|
||||
|
||||
pub struct Npz;
|
||||
impl Npz {
|
||||
#[inline]
|
||||
fn load_1d<T: Num + Deserialize>(
|
||||
fn load_1d<T: Num + Deserialize, R: std::io::Read + Seek>(
|
||||
&self,
|
||||
// path: &Path,
|
||||
data: &mut NpzArchive<BufReader<std::fs::File>>,
|
||||
data: &mut NpzArchive<R>,
|
||||
name: &str,
|
||||
) -> Result<Array1<T>, DataError> {
|
||||
// let mut data = npyz::npz::NpzArchive::open(path)?;
|
||||
@ -296,10 +305,10 @@ impl Npz {
|
||||
Ok(Array1::from_shape_vec(b.len(), b).unwrap())
|
||||
}
|
||||
#[inline]
|
||||
fn load_2d<T: Num + Deserialize>(
|
||||
fn load_2d<T: Num + Deserialize, R: std::io::Read + Seek>(
|
||||
&self,
|
||||
// path: &Path,
|
||||
data: &mut NpzArchive<BufReader<std::fs::File>>,
|
||||
data: &mut NpzArchive<R>,
|
||||
name: &str,
|
||||
) -> Result<Array2<T>, DataError> {
|
||||
// let mut data = npyz::npz::NpzArchive::open(path)?;
|
||||
@ -320,9 +329,9 @@ where
|
||||
{
|
||||
fn load<P: AsRef<Path>>(&self, path: P) -> Result<RadarData2d<T, OwnedRepr<T>>, DataError> {
|
||||
let mut data: NpzArchive<BufReader<std::fs::File>> = npyz::npz::NpzArchive::open(path)?;
|
||||
let dim1 = self.load_1d::<f64>(&mut data, "lon")?;
|
||||
let dim2 = self.load_1d::<f64>(&mut data, "lat")?;
|
||||
let value = self.load_2d::<T>(&mut data, "value")?;
|
||||
let dim1 = self.load_1d::<f64, BufReader<std::fs::File>>(&mut data, "lon")?;
|
||||
let dim2 = self.load_1d::<f64, BufReader<std::fs::File>>(&mut data, "lat")?;
|
||||
let value = self.load_2d::<T, BufReader<std::fs::File>>(&mut data, "value")?;
|
||||
|
||||
Ok(RadarData2d {
|
||||
dim1: dim1,
|
||||
@ -334,6 +343,47 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsyncDataLoader<T, RadarData2d<T, OwnedRepr<T>>> for Npz
|
||||
where
|
||||
T: Num + Clone + Deserialize + FromPrimitive,
|
||||
T: PartialEq + PartialOrd + Send + Sync,
|
||||
{
|
||||
fn load<'life0, 'async_trait, P>(
|
||||
&'life0 self,
|
||||
path: P,
|
||||
) -> core::pin::Pin<
|
||||
Box<
|
||||
dyn core::future::Future<Output = Result<RadarData2d<T, OwnedRepr<T>>, DataError>>
|
||||
+ core::marker::Send
|
||||
+ 'async_trait,
|
||||
>,
|
||||
>
|
||||
where
|
||||
P: 'async_trait + AsRef<Path> + Send,
|
||||
'life0: 'async_trait,
|
||||
Self: 'async_trait,
|
||||
{
|
||||
Box::pin(async {
|
||||
let mut f = File::open(path).await?;
|
||||
let mut buffer = Vec::new();
|
||||
f.read_to_end(&mut buffer).await?;
|
||||
|
||||
let mut data = npyz::npz::NpzArchive::new(Cursor::new(buffer))?;
|
||||
let dim1 = self.load_1d::<f64, Cursor<Vec<u8>>>(&mut data, "lon")?;
|
||||
let dim2 = self.load_1d::<f64, Cursor<Vec<u8>>>(&mut data, "lat")?;
|
||||
let value = self.load_2d::<T, Cursor<Vec<u8>>>(&mut data, "value")?;
|
||||
|
||||
Ok(RadarData2d {
|
||||
dim1: dim1,
|
||||
dim2: dim2,
|
||||
fill_value: T::from_f64(-125.0).unwrap(),
|
||||
data: value,
|
||||
coord_type: CoordType::LatLon,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// fn resample(
|
||||
// &self,
|
||||
// width_rate: f64,
|
||||
|
||||
@ -6,10 +6,7 @@ pub enum DataError {
|
||||
#[error("value")]
|
||||
FormatError,
|
||||
#[error("")]
|
||||
IOError {
|
||||
#[from]
|
||||
source: std::io::Error,
|
||||
},
|
||||
IOError(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
||||
@ -3,6 +3,7 @@ use gtk::prelude::*;
|
||||
use gtk::{gio, glib, Application, ApplicationWindow};
|
||||
use relm4::menu;
|
||||
use relm4::RelmApp;
|
||||
use tokio::runtime::Runtime;
|
||||
use std::ptr;
|
||||
mod chart;
|
||||
mod components;
|
||||
@ -14,9 +15,13 @@ mod pipeline;
|
||||
mod render;
|
||||
mod window;
|
||||
use components::app::{AppMode, AppModel};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
||||
|
||||
static RUNTIME: Lazy<Runtime> =
|
||||
Lazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed."));
|
||||
|
||||
fn main() {
|
||||
// Load GL pointers from epoxy (GL context management library used by GTK).
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@ use super::interior::InteriorWidget;
|
||||
use super::{Layer, WindowCoord};
|
||||
use crate::coords::proj::Mercator;
|
||||
use crate::coords::Mapper;
|
||||
use femtovg::{Canvas, Color, FontId};
|
||||
use femtovg::{Canvas, Color, FontId, Renderer};
|
||||
use gtk::glib;
|
||||
use gtk::subclass::prelude::*;
|
||||
use gtk::traits::{GLAreaExt, WidgetExt};
|
||||
@ -119,23 +119,23 @@ impl GLAreaImpl for Render {
|
||||
|
||||
fn render(&self, context: >k::gdk::GLContext) -> bool {
|
||||
self.ensure_canvas();
|
||||
|
||||
let mut canvas = self.canvas.borrow_mut();
|
||||
let canvas = canvas.as_mut().unwrap();
|
||||
|
||||
let dpi = self.obj().scale_factor();
|
||||
let w = canvas.width();
|
||||
let h = canvas.height();
|
||||
|
||||
let configs = self.config.borrow();
|
||||
{
|
||||
let mut canvas = self.canvas.borrow_mut();
|
||||
let canvas = canvas.as_mut().unwrap();
|
||||
|
||||
canvas.clear_rect(
|
||||
0,
|
||||
0,
|
||||
(w as i32 * dpi) as u32,
|
||||
(h as i32 * dpi) as u32,
|
||||
Color::rgba(0, 0, 0, 255),
|
||||
);
|
||||
let dpi = self.obj().scale_factor();
|
||||
let w = canvas.width();
|
||||
let h = canvas.height();
|
||||
|
||||
canvas.clear_rect(
|
||||
0,
|
||||
0,
|
||||
(w as i32 * dpi) as u32,
|
||||
(h as i32 * dpi) as u32,
|
||||
Color::rgba(0, 0, 0, 255),
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let mut status = self.status.borrow_mut();
|
||||
@ -170,20 +170,18 @@ impl GLAreaImpl for Render {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let c = &(*self.interior_layers.borrow());
|
||||
self.interior
|
||||
.borrow()
|
||||
.draw(c, &self.obj(), self.status.borrow(), configs);
|
||||
|
||||
{
|
||||
let mut canvas = self.canvas.borrow_mut();
|
||||
let canvas = canvas.as_mut().unwrap();
|
||||
self.exterior.borrow().draw(canvas, &self.obj());
|
||||
canvas.flush();
|
||||
}
|
||||
|
||||
self.interior.borrow().draw(
|
||||
c,
|
||||
canvas,
|
||||
&self.obj(),
|
||||
self.status.borrow(),
|
||||
configs,
|
||||
);
|
||||
self.exterior.borrow().draw(canvas, &self.obj());
|
||||
|
||||
canvas.flush();
|
||||
true
|
||||
}
|
||||
}
|
||||
@ -219,6 +217,7 @@ impl Render {
|
||||
canvas
|
||||
.add_font_dir("/Users/tsuki/projects/radar-g/src/assets")
|
||||
.unwrap();
|
||||
|
||||
self.canvas.replace(Some(canvas));
|
||||
}
|
||||
|
||||
|
||||
@ -1,19 +1,31 @@
|
||||
use crate::{coords::Range, render::Render};
|
||||
use femtovg::Paint;
|
||||
use femtovg::{renderer::OpenGl, Canvas, ImageId};
|
||||
use ndarray::AssignElem;
|
||||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
fmt::Debug, sync::Arc,
|
||||
fmt::Debug,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
type PrepareFunc =
|
||||
Box<dyn FnOnce(Arc<Layer>, Render) -> Pin<Box<dyn Future<Output = ()>>> + Sync + Send>;
|
||||
type DrawFunc = Box<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>;
|
||||
type LayerImplSync = Box<dyn LayerImpl + Send + Sync>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Layer {
|
||||
pub visiable: bool,
|
||||
pub name: String,
|
||||
snapshot: Option<gtk::gdk::Texture>,
|
||||
target: RefCell<Option<Target>>,
|
||||
imp: RefCell<Option<Arc<dyn LayerImpl>>>,
|
||||
draw: Arc<dyn Fn(&Self, &mut Canvas<OpenGl>, &Render, (f32, f32))>,
|
||||
prepare: Arc<Option<PrepareFunc>>,
|
||||
imp: RefCell<Option<Arc<LayerImplSync>>>,
|
||||
draw: Arc<DrawFunc>,
|
||||
}
|
||||
|
||||
|
||||
impl Debug for Layer {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Layer")
|
||||
@ -25,32 +37,53 @@ impl Debug for Layer {
|
||||
}
|
||||
|
||||
pub trait LayerImpl: Debug {
|
||||
fn draw(&self, canvas: &mut Canvas<OpenGl>, render: &Render) -> Option<Target>;
|
||||
fn draw(&self, render: Render) -> Option<Target>;
|
||||
}
|
||||
|
||||
impl Layer {
|
||||
pub fn new<
|
||||
F: 'static + Fn(&Self, &mut Canvas<OpenGl>, &Render, (f32, f32)),
|
||||
IMP: LayerImpl + 'static,
|
||||
FU: Future<Output = ()> + 'static,
|
||||
F: 'static + Fn(&Self, Render, (f32, f32)) + Send + Sync,
|
||||
PREPARE: FnOnce(Arc<Layer>, Render) -> FU + Send + Sync + 'static,
|
||||
IMP: LayerImpl + Sync + Send + 'static,
|
||||
>(
|
||||
visiable: bool,
|
||||
draw: F,
|
||||
layer_name: String,
|
||||
prepare: Option<PREPARE>,
|
||||
imp: Option<IMP>,
|
||||
) -> Self {
|
||||
Layer {
|
||||
visiable,
|
||||
target: RefCell::new(None),
|
||||
draw: Arc::new(draw),
|
||||
imp: RefCell::new(imp.map(|x| Arc::new(x) as Arc<dyn LayerImpl>)),
|
||||
name: layer_name,
|
||||
snapshot: None,
|
||||
// prepare: Arc::new(prepare),
|
||||
prepare: Arc::new(prepare.map(|p| {
|
||||
Box::new(
|
||||
move |layer: Arc<Layer>, render: Render| -> Pin<Box<dyn Future<Output = ()>>> {
|
||||
Box::pin(p(layer, render))
|
||||
},
|
||||
) as PrepareFunc
|
||||
})),
|
||||
draw: Arc::new(Box::new(draw)),
|
||||
imp: RefCell::new(
|
||||
imp.map(|x| Arc::new(Box::new(x) as Box<dyn LayerImpl + Send + Sync>)),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&self, canvas: &mut Canvas<OpenGl>, render: &Render, window_size: (f32, f32)) {
|
||||
pub fn draw(&self, render: &Render, window_size: (f32, f32)) {
|
||||
if self.visiable {
|
||||
(self.draw)(self, canvas, render, window_size);
|
||||
let drawer = &self.draw;
|
||||
drawer(self, render.clone(), window_size);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_prepare(&self) -> Option<&PrepareFunc> {
|
||||
self.prepare.as_ref().as_ref()
|
||||
}
|
||||
|
||||
pub fn set_render_target(&self, target: Target) {
|
||||
*self.target.borrow_mut() = Some(target);
|
||||
}
|
||||
@ -59,7 +92,7 @@ impl Layer {
|
||||
self.target.borrow().clone()
|
||||
}
|
||||
|
||||
pub fn get_imp(&self) -> Ref<Option<Arc<dyn LayerImpl>>> {
|
||||
pub fn get_imp(&self) -> Ref<Option<Arc<LayerImplSync>>> {
|
||||
let im = self.imp.borrow();
|
||||
im
|
||||
}
|
||||
|
||||
@ -23,19 +23,15 @@ impl InteriorWidget {
|
||||
this
|
||||
}
|
||||
|
||||
|
||||
pub fn draw(
|
||||
&self,
|
||||
layers: &Vec<Layer>,
|
||||
canvas: &mut Canvas<OpenGl>,
|
||||
render: &Render,
|
||||
status: Ref<'_, RenderStatus>,
|
||||
_c: Ref<'_, RenderConfig>,
|
||||
) {
|
||||
|
||||
let (x, y) = (canvas.width(), canvas.height());
|
||||
for layer in layers.iter().filter(|x| x.visiable) {
|
||||
layer.draw(canvas, &render, (x, y));
|
||||
layer.draw(render, (1000.0, 1000.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,24 @@
|
||||
mod cms;
|
||||
mod imp;
|
||||
mod exterior;
|
||||
mod imp;
|
||||
mod interior;
|
||||
pub mod predefined;
|
||||
mod renders;
|
||||
use self::cms::CMS;
|
||||
pub use self::imp::{RenderConfig, RenderMotion, RenderStatus};
|
||||
use crate::coords::Mapper;
|
||||
use crate::RUNTIME;
|
||||
use adw::prelude::{GLAreaExt, GestureDragExt};
|
||||
use geo_types::LineString;
|
||||
use glib::clone;
|
||||
pub use glib::subclass::prelude::*;
|
||||
use gtk::traits::WidgetExt;
|
||||
use gtk::{EventControllerScrollFlags, Inhibit};
|
||||
use std::cell::Ref;
|
||||
pub use glib::subclass::prelude::*;
|
||||
pub use interior::{Layer, LayerImpl, Target};
|
||||
use relm4::once_cell::sync::Lazy;
|
||||
use std::cell::{Ref, RefCell, RefMut};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
pub(super) type WindowCoord = (f32, f32);
|
||||
|
||||
@ -41,7 +45,6 @@ impl Render {
|
||||
this.set_mapper(mapper);
|
||||
}
|
||||
|
||||
|
||||
let pointer_location_detecture = gtk::EventControllerMotion::new();
|
||||
pointer_location_detecture.connect_motion(
|
||||
clone!( @weak this as r => move |_context, x, y| {
|
||||
@ -104,6 +107,10 @@ impl Render {
|
||||
f(&mut cfg);
|
||||
}
|
||||
|
||||
pub fn get_canvas(&self) -> RefMut<'_, Option<femtovg::Canvas<femtovg::renderer::OpenGl>>> {
|
||||
self.imp().canvas.borrow_mut()
|
||||
}
|
||||
|
||||
pub fn set_cfg(&self, cfg: RenderConfig) {
|
||||
self.imp().config.replace(cfg);
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use std::fmt::Debug;
|
||||
|
||||
use femtovg::Color;
|
||||
use num_traits::NumOps;
|
||||
pub trait ColorMapper<T: NumOps + PartialOrd> : Debug {
|
||||
pub trait ColorMapper<T: NumOps + PartialOrd> : Debug + Send + Sync {
|
||||
fn map_value_to_color(&self, value: T, invalid_value: T) -> Option<femtovg::Color>;
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ impl<T: NumOps + PartialOrd> BoundaryNorm<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NumOps + PartialOrd + Debug> ColorMapper<T> for BoundaryNorm<T> {
|
||||
impl<T: NumOps + PartialOrd + Debug + Send + Sync> ColorMapper<T> for BoundaryNorm<T> {
|
||||
fn map_value_to_color(&self, value: T, invalid_value: T) -> Option<femtovg::Color> {
|
||||
self.map_value_to_color(value, invalid_value)
|
||||
}
|
||||
|
||||
@ -1,15 +1,71 @@
|
||||
use crate::coords::Range;
|
||||
use std::borrow::BorrowMut;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::coords::Mapper;
|
||||
use crate::render::Render;
|
||||
use crate::render::{Layer, LayerImpl, Render};
|
||||
use femtovg::renderer::OpenGl;
|
||||
use femtovg::{Canvas, Paint};
|
||||
use geo_types::LineString;
|
||||
use geojson::GeoJson;
|
||||
|
||||
pub struct MapRender;
|
||||
impl Layer {
|
||||
pub fn map_layer_with_geojson_by_path(path: impl AsRef<Path>) -> Self {
|
||||
let geojson = std::fs::read_to_string(path).unwrap();
|
||||
let json = geojson.parse::<GeoJson>().unwrap();
|
||||
Self::map_layer_with_geojson(json)
|
||||
}
|
||||
|
||||
impl MapRender {
|
||||
pub fn test(geojson: &GeoJson, canvas: &mut Canvas<OpenGl>, render: &Render) {
|
||||
pub fn map_layer_with_geojson(json: GeoJson) -> Self {
|
||||
let mut layer = Layer::new(
|
||||
true,
|
||||
|s, render, _| {
|
||||
if let Some(renderer) = s.get_imp().as_ref() {
|
||||
renderer.draw(render.clone());
|
||||
}
|
||||
},
|
||||
"Map".into(),
|
||||
Some(|_, _| async {}),
|
||||
Some(GeoJsonMapImpl::new(json)),
|
||||
);
|
||||
layer
|
||||
}
|
||||
|
||||
pub fn meshgrid_layer() -> Self {
|
||||
let mut layer = Layer::new(
|
||||
true,
|
||||
|s, render, _| {
|
||||
if let Some(renderer) = s.get_imp().as_ref() {
|
||||
renderer.draw(render.clone());
|
||||
}
|
||||
},
|
||||
"MeshGrid".into(),
|
||||
Some(|_, _| async {}),
|
||||
Some(MeshGridImpl),
|
||||
);
|
||||
|
||||
layer
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct GeoJsonMapImpl {
|
||||
geojson: GeoJson,
|
||||
}
|
||||
|
||||
impl GeoJsonMapImpl {
|
||||
fn new(json: GeoJson) -> Self {
|
||||
Self { geojson: json }
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerImpl for GeoJsonMapImpl {
|
||||
fn draw(&self, render: Render) -> Option<crate::render::Target> {
|
||||
let paint = Paint::color(femtovg::Color::rgb(255, 255, 255));
|
||||
let geojson = &self.geojson;
|
||||
|
||||
let mut canvas = render.get_canvas();
|
||||
let canvas = canvas.as_mut().unwrap();
|
||||
|
||||
if let GeoJson::FeatureCollection(ref feature_collection) = geojson {
|
||||
for feature in &feature_collection.features {
|
||||
@ -59,5 +115,45 @@ impl MapRender {
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MeshGridImpl;
|
||||
|
||||
impl LayerImpl for MeshGridImpl {
|
||||
fn draw(&self, render: Render) -> Option<crate::render::Target> {
|
||||
let mut canvas = render.get_canvas();
|
||||
let canvas = canvas.as_mut().unwrap();
|
||||
|
||||
let (lon_range, lat_range) = render.render_range();
|
||||
let (lon_range, lat_range): (Range, Range) = (lon_range.into(), lat_range.into());
|
||||
|
||||
let lon_keypoints = lon_range.key_points(10);
|
||||
let lat_keypoints = lat_range.key_points(5);
|
||||
|
||||
for lon in lon_keypoints.iter() {
|
||||
let mut path = femtovg::Path::new();
|
||||
render
|
||||
.map((*lon, lat_range.0))
|
||||
.map(|(x, y)| path.move_to(x, y));
|
||||
render
|
||||
.map((*lon, lat_range.1))
|
||||
.map(|(x, y)| path.line_to(x, y));
|
||||
canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255)));
|
||||
}
|
||||
for lat in lat_keypoints.iter() {
|
||||
let mut path = femtovg::Path::new();
|
||||
render
|
||||
.map((lon_range.0, *lat))
|
||||
.map(|(x, y)| path.move_to(x, y));
|
||||
render
|
||||
.map((lon_range.1, *lat))
|
||||
.map(|(x, y)| path.line_to(x, y));
|
||||
canvas.stroke_path(&mut path, &Paint::color(femtovg::Color::rgb(255, 255, 255)));
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,12 +3,13 @@ use femtovg::{ImageFlags, Paint, Path, PixelFormat::Rgba8, RenderTarget};
|
||||
use geo_types::LineString;
|
||||
use ndarray::ArrayView2;
|
||||
use num_traits::{Num, NumOps};
|
||||
use std::{marker::PhantomData, fmt::Debug};
|
||||
use std::{fmt::Debug, marker::PhantomData};
|
||||
|
||||
use super::super::renders::DataRenderer;
|
||||
use crate::{
|
||||
data::Radar2d,
|
||||
utils::meshgrid, render::{Render, Target, LayerImpl},
|
||||
render::{LayerImpl, Render, Target},
|
||||
utils::meshgrid,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -37,7 +38,6 @@ impl<T: NumOps + PartialOrd + Copy, CMAP: ColorMapper<T>> GridFieldRenderer<CMAP
|
||||
window_size: (f32, f32),
|
||||
fill_value: T,
|
||||
) {
|
||||
|
||||
let shape = data.shape();
|
||||
let (rows, cols) = (shape[0], shape[1]);
|
||||
let (dim1, dim2) = dims;
|
||||
@ -96,12 +96,10 @@ where
|
||||
CMAP: ColorMapper<T>,
|
||||
{
|
||||
type Data = Radar2d<T>;
|
||||
fn render(
|
||||
&self,
|
||||
render: &Render,
|
||||
canvas: &mut femtovg::Canvas<femtovg::renderer::OpenGl>,
|
||||
data: &Self::Data,
|
||||
) -> Target {
|
||||
fn render(&self, render: Render, data: &Self::Data) -> Target {
|
||||
let mut canvas = render.get_canvas();
|
||||
let canvas = canvas.as_mut().unwrap();
|
||||
|
||||
let new_img = canvas
|
||||
.create_image_empty(3000, 3000, Rgba8, ImageFlags::empty())
|
||||
.expect("Can't Create Image");
|
||||
@ -116,7 +114,7 @@ where
|
||||
self.draw_2d(
|
||||
canvas,
|
||||
_data,
|
||||
render,
|
||||
&render,
|
||||
(_dim1.view(), _dim2.view()),
|
||||
(3000.0, 3000.0),
|
||||
data.fill_value,
|
||||
@ -144,7 +142,7 @@ where
|
||||
#[derive(Debug)]
|
||||
pub struct GridLayerImpl<CMAP, T>
|
||||
where
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone,
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + Send + Sync + Debug,
|
||||
CMAP: ColorMapper<T>,
|
||||
{
|
||||
renderer: GridFieldRenderer<CMAP, T>,
|
||||
@ -155,7 +153,7 @@ pub type DbzGridLayerImpl = GridLayerImpl<BoundaryNorm<i8>, i8>;
|
||||
|
||||
impl<CMAP, T> GridLayerImpl<CMAP, T>
|
||||
where
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone,
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + Send + Sync + Debug,
|
||||
CMAP: ColorMapper<T>,
|
||||
{
|
||||
pub fn new(renderer: GridFieldRenderer<CMAP, T>, data: Radar2d<T>) -> Self {
|
||||
@ -165,14 +163,10 @@ where
|
||||
|
||||
impl<CMAP, T> LayerImpl for GridLayerImpl<CMAP, T>
|
||||
where
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + Debug,
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + Debug + Send + Sync,
|
||||
CMAP: ColorMapper<T> + Debug,
|
||||
{
|
||||
fn draw(
|
||||
&self,
|
||||
canvas: &mut femtovg::Canvas<femtovg::renderer::OpenGl>,
|
||||
render: &Render,
|
||||
) -> Option<Target> {
|
||||
Some(self.renderer.render(render, canvas, &self.data))
|
||||
fn draw(&self, render: Render) -> Option<Target> {
|
||||
Some(self.renderer.render(render, &self.data))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use femtovg::Paint;
|
||||
use femtovg::{renderer::OpenGl, Canvas, Paint};
|
||||
use num_traits::{Num, NumOps};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
data::{DataLoader, Radar2d},
|
||||
render::Layer
|
||||
data::{AsyncDataLoader, DataLoader, Radar2d},
|
||||
render::{Layer, Render},
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -13,18 +14,20 @@ use super::{
|
||||
};
|
||||
|
||||
impl Layer {
|
||||
pub fn grid_render_layer<T, CMAP>(data: Radar2d<T>, color_map: CMAP) -> Self
|
||||
pub fn grid_render_layer<T, CMAP>(data: Radar2d<T>, layer_name: String, color_map: CMAP) -> Self
|
||||
where
|
||||
T: std::fmt::Debug + Num + NumOps + PartialOrd + Copy + Clone + 'static,
|
||||
T: std::fmt::Debug + Num + NumOps + PartialOrd + Copy + Clone + 'static + Send + Sync,
|
||||
CMAP: ColorMapper<T> + 'static,
|
||||
{
|
||||
Self::new(
|
||||
true,
|
||||
|s, c, render, _| {
|
||||
|s, render, _| {
|
||||
if let Some(target) = s.render_target() {
|
||||
let mut c = render.get_canvas();
|
||||
let c = c.as_mut().unwrap();
|
||||
if let Ok(_) = c.image_size(target.target) {
|
||||
let (x, y) = target.size(render);
|
||||
let (ox, oy) = target.origin(render);
|
||||
let (x, y) = target.size(&render);
|
||||
let (ox, oy) = target.origin(&render);
|
||||
let painter = Paint::image(target.target, ox, oy, x, y, 0.0, 1.0);
|
||||
let mut path = femtovg::Path::new();
|
||||
path.rect(ox, oy, x, y);
|
||||
@ -32,36 +35,60 @@ impl Layer {
|
||||
}
|
||||
} else {
|
||||
if let Some(renderer) = s.get_imp().as_ref() {
|
||||
let img = renderer.draw(c, render).unwrap();
|
||||
let img = renderer.draw(render.clone()).unwrap();
|
||||
|
||||
let mut c = render.get_canvas();
|
||||
let c = c.as_mut().unwrap();
|
||||
if let Ok(_) = c.image_size(img.target) {
|
||||
let (x, y) = img.size(render);
|
||||
let (ox, oy) = img.origin(render);
|
||||
let (x, y) = img.size(&render);
|
||||
let (ox, oy) = img.origin(&render);
|
||||
println!("{} {} {} {}", x, y, ox, oy);
|
||||
let painter = Paint::image(img.target, ox, oy, x, y, 0.0, 1.0);
|
||||
let mut path = femtovg::Path::new();
|
||||
path.rect(ox, oy, x, y);
|
||||
s.set_render_target(img);
|
||||
c.fill_path(&path, &painter);
|
||||
c.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
layer_name,
|
||||
Some(|s: Arc<Layer>, render: Render| async move {
|
||||
if let None = s.render_target() {
|
||||
if let Some(renderer) = s.get_imp().as_ref() {}
|
||||
}
|
||||
}),
|
||||
Some(GridLayerImpl::new(GridFieldRenderer::new(color_map), data)),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn grid_render_layer_with_path<T, CMAP, LOADER>(
|
||||
path: impl AsRef<Path>,
|
||||
layer_name: String,
|
||||
loader: LOADER,
|
||||
color_map: CMAP,
|
||||
) -> Self
|
||||
where
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + 'static + std::fmt::Debug,
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + 'static + std::fmt::Debug + Sync + Send,
|
||||
CMAP: ColorMapper<T> + 'static,
|
||||
LOADER: DataLoader<T, Radar2d<T>>,
|
||||
{
|
||||
let data = loader.load(path).unwrap();
|
||||
self::Layer::grid_render_layer(data, color_map)
|
||||
self::Layer::grid_render_layer(data, layer_name, color_map)
|
||||
}
|
||||
|
||||
pub async fn grid_render_layer_with_path_async<T, CMAP, LOADER>(
|
||||
path: impl AsRef<Path> + Send,
|
||||
layer_name: String,
|
||||
loader: LOADER,
|
||||
color_map: CMAP,
|
||||
) -> Self
|
||||
where
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + 'static + std::fmt::Debug + Send + Sync,
|
||||
CMAP: ColorMapper<T> + 'static,
|
||||
LOADER: AsyncDataLoader<T, Radar2d<T>>,
|
||||
{
|
||||
let data = loader.load(path).await.unwrap();
|
||||
self::Layer::grid_render_layer(data, layer_name, color_map)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,8 @@
|
||||
use femtovg::{renderer::OpenGl, Canvas};
|
||||
use super::Target;
|
||||
use super::Render;
|
||||
use super::Target;
|
||||
use femtovg::{renderer::OpenGl, Canvas};
|
||||
|
||||
pub trait DataRenderer {
|
||||
type Data;
|
||||
fn render(
|
||||
&self,
|
||||
render: &Render,
|
||||
canvas: &mut Canvas<OpenGl>,
|
||||
data: &Self::Data,
|
||||
) -> Target;
|
||||
fn render(&self, render: Render, data: &Self::Data) -> Target;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user