diff --git a/Cargo.lock b/Cargo.lock index 74f7d1a..a2681dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -302,9 +302,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "block" @@ -398,20 +398,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab3603c4028a5e368d09b51c8b624b9a46edcd7c3778284077a6125af73c9f0a" dependencies = [ "bitflags 1.3.2", - "cairo-sys-rs", - "glib", + "cairo-sys-rs 0.17.10", + "glib 0.17.10", "libc", "once_cell", "thiserror", ] +[[package]] +name = "cairo-rs" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2650f66005301bd33cc486dec076e1293c4cecf768bc7ba9bf5d2b1be339b99c" +dependencies = [ + "bitflags 2.4.2", + "cairo-sys-rs 0.19.2", + "glib 0.19.2", + "libc", + "thiserror", +] + [[package]] name = "cairo-sys-rs" version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "691d0c66b1fb4881be80a760cb8fe76ea97218312f9dfe2c9cc0f496ca279cb1" dependencies = [ - "glib-sys", + "glib-sys 0.17.10", + "libc", + "system-deps", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3bb3119664efbd78b5e6c93957447944f16bdbced84c17a9f41c7829b81e64" +dependencies = [ + "glib-sys 0.19.0", "libc", "system-deps", ] @@ -501,7 +525,7 @@ dependencies = [ "abi_stable", "anyhow", "async-trait", - "cairo-rs", + "cairo-rs 0.17.10", "chrono", "core_extensions", "crossbeam", @@ -518,9 +542,9 @@ dependencies = [ "geo-types", "geojson 0.24.1", "gl", - "glib", + "glib 0.17.10", "glib-build-tools", - "glib-macros", + "glib-macros 0.17.10", "glow", "glue", "gtk4", @@ -560,7 +584,7 @@ dependencies = [ "thiserror", "tokio", "tokio-condvar", - "toml 0.8.8", + "toml 0.8.11", "topojson", "tracing", "tracing-subscriber", @@ -1086,7 +1110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1e481eb11a482815d3e9d618db8c42a93207134662873809335a92327440c18" dependencies = [ "bit_field", - "flume", + "flume 0.10.14", "half", "lebe", "miniz_oxide", @@ -1116,7 +1140,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3a2d0ff0df09856a5c1c89cc83863a1f0f994c55452186621bb57a01f270b3" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.2", "fnv", "generational-arena", "glow", @@ -1188,6 +1212,18 @@ dependencies = [ "spin", ] +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + [[package]] name = "fns" version = "0.0.7" @@ -1370,58 +1406,55 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "695d6bc846438c5708b07007537b9274d883373dd30858ca881d7d71b5540717" +checksum = "f6a23f8a0b5090494fd04924662d463f8386cc678dd3915015a838c1a3679b92" dependencies = [ - "bitflags 1.3.2", "gdk-pixbuf-sys", "gio", - "glib", + "glib 0.19.2", "libc", - "once_cell", ] [[package]] name = "gdk-pixbuf-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9285ec3c113c66d7d0ab5676599176f1f42f4944ca1b581852215bf5694870cb" +checksum = "3dcbd04c1b2c4834cc008b4828bc917d062483b88d26effde6342e5622028f96" dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.19.0", + "glib-sys 0.19.0", + "gobject-sys 0.19.0", "libc", "system-deps", ] [[package]] name = "gdk4" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3abf96408a26e3eddf881a7f893a1e111767137136e347745e8ea6ed12731ff" +checksum = "9100b25604183f2fd97f55ef087fae96ab4934d7215118a35303e422688e6e4b" dependencies = [ - "bitflags 1.3.2", - "cairo-rs", + "cairo-rs 0.19.2", "gdk-pixbuf", "gdk4-sys", "gio", - "glib", + "glib 0.19.2", "libc", "pango", ] [[package]] name = "gdk4-sys" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc92aa1608c089c49393d014c38ac0390d01e4841e1fedaa75dbcef77aaed64" +checksum = "d0b76874c40bb8d1c7d03a7231e23ac75fa577a456cd53af32ec17ec8f121626" dependencies = [ - "cairo-sys-rs", + "cairo-sys-rs 0.19.2", "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.19.0", + "glib-sys 0.19.0", + "gobject-sys 0.19.0", "libc", "pango-sys", "pkg-config", @@ -1551,19 +1584,17 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "gio" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6973e92937cf98689b6a054a9e56c657ed4ff76de925e36fc331a15f0c5d30a" +checksum = "2eae10b27b6dd27e22ed0d812c6387deba295e6fc004a8b379e459b663b05a02" dependencies = [ - "bitflags 1.3.2", "futures-channel", "futures-core", "futures-io", "futures-util", - "gio-sys", - "glib", + "gio-sys 0.19.0", + "glib 0.19.2", "libc", - "once_cell", "pin-project-lite", "smallvec", "thiserror", @@ -1575,13 +1606,26 @@ version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ccf87c30a12c469b6d958950f6a9c09f2be20b7773f7e70d20b867fdf2628c3" dependencies = [ - "glib-sys", - "gobject-sys", + "glib-sys 0.17.10", + "gobject-sys 0.17.10", "libc", "system-deps", "winapi", ] +[[package]] +name = "gio-sys" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf8e1d9219bb294636753d307b030c1e8a032062cba74f493c431a5c8b81ce4" +dependencies = [ + "glib-sys 0.19.0", + "gobject-sys 0.19.0", + "libc", + "system-deps", + "windows-sys 0.52.0", +] + [[package]] name = "gl" version = "0.14.0" @@ -1625,10 +1669,10 @@ dependencies = [ "futures-executor", "futures-task", "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", + "gio-sys 0.17.10", + "glib-macros 0.17.10", + "glib-sys 0.17.10", + "gobject-sys 0.17.10", "libc", "memchr", "once_cell", @@ -1636,6 +1680,28 @@ dependencies = [ "thiserror", ] +[[package]] +name = "glib" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9e86540b5d8402e905ad4ce7d6aa544092131ab564f3102175af176b90a053" +dependencies = [ + "bitflags 2.4.2", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys 0.19.0", + "glib-macros 0.19.2", + "glib-sys 0.19.0", + "gobject-sys 0.19.0", + "libc", + "memchr", + "smallvec", + "thiserror", +] + [[package]] name = "glib-build-tools" version = "0.17.10" @@ -1650,13 +1716,26 @@ checksum = "eca5c79337338391f1ab8058d6698125034ce8ef31b72a442437fa6c8580de26" dependencies = [ "anyhow", "heck", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro-error", "proc-macro2 1.0.76", "quote 1.0.35", "syn 1.0.109", ] +[[package]] +name = "glib-macros" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f5897ca27a83e4cdc7b4666850bade0a2e73e17689aabafcc9acddad9d823b8" +dependencies = [ + "heck", + "proc-macro-crate 3.1.0", + "proc-macro2 1.0.76", + "quote 1.0.35", + "syn 2.0.48", +] + [[package]] name = "glib-sys" version = "0.17.10" @@ -1667,6 +1746,16 @@ dependencies = [ "system-deps", ] +[[package]] +name = "glib-sys" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630f097773d7c7a0bb3258df4e8157b47dc98bbfa0e60ad9ab56174813feced4" +dependencies = [ + "libc", + "system-deps", +] + [[package]] name = "glob" version = "0.3.1" @@ -1701,29 +1790,40 @@ version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd34c3317740a6358ec04572c1bcfd3ac0b5b6529275fae255b237b314bb8062" dependencies = [ - "glib-sys", + "glib-sys 0.17.10", + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e2b1080b9418dd0c58b498da3a5c826030343e0ef07bde6a955d28de54979" +dependencies = [ + "glib-sys 0.19.0", "libc", "system-deps", ] [[package]] name = "graphene-rs" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def4bb01265b59ed548b05455040d272d989b3012c42d4c1bbd39083cb9b40d9" +checksum = "99e4d388e96c5f29e2b2f67045d229ddf826d0a8d6d282f94ed3b34452222c91" dependencies = [ - "glib", + "glib 0.19.2", "graphene-sys", "libc", ] [[package]] name = "graphene-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1856fc817e6a6675e36cea0bd9a3afe296f5d9709d1e2d3182803ac77f0ab21d" +checksum = "236ed66cc9b18d8adf233716f75de803d0bf6fc806f60d14d948974a12e240d0" dependencies = [ - "glib-sys", + "glib-sys 0.19.0", "libc", "pkg-config", "system-deps", @@ -1731,14 +1831,13 @@ dependencies = [ [[package]] name = "gsk4" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f01ef44fa7cac15e2da9978529383e6bee03e570ba5bf7036b4c10a15cc3a3c" +checksum = "c65036fc8f99579e8cb37b12487969b707ab23ec8ab953682ff347cbd15d396e" dependencies = [ - "bitflags 1.3.2", - "cairo-rs", + "cairo-rs 0.19.2", "gdk4", - "glib", + "glib 0.19.2", "graphene-rs", "gsk4-sys", "libc", @@ -1747,14 +1846,14 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07a84fb4dcf1323d29435aa85e2f5f58bef564342bef06775ec7bd0da1f01b0" +checksum = "bd24c814379f9c3199dc53e52253ee8d0f657eae389ab282c330505289d24738" dependencies = [ - "cairo-sys-rs", + "cairo-sys-rs 0.19.2", "gdk4-sys", - "glib-sys", - "gobject-sys", + "glib-sys 0.19.0", + "gobject-sys 0.19.0", "graphene-sys", "libc", "pango-sys", @@ -1763,35 +1862,33 @@ dependencies = [ [[package]] name = "gtk4" -version = "0.6.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28a32a04cd75cef14a0983f8b0c669e0fe152a0a7725accdeb594e2c764c88b" +checksum = "aa82753b8c26277e4af1446c70e35b19aad4fb794a7b143859e7eeb9a4025d83" dependencies = [ - "bitflags 1.3.2", - "cairo-rs", + "cairo-rs 0.19.2", "field-offset", "futures-channel", "gdk-pixbuf", "gdk4", "gio", - "glib", + "glib 0.19.2", "graphene-rs", "gsk4", "gtk4-macros", "gtk4-sys", "libc", - "once_cell", "pango", ] [[package]] name = "gtk4-macros" -version = "0.6.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4d6b61570f76d3ee542d984da443b1cd69b6105264c61afec3abed08c2500f" +checksum = "40300bf071d2fcd4c94eacc09e84ec6fe73129d2ceb635cf7e55b026b5443567" dependencies = [ "anyhow", - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro-error", "proc-macro2 1.0.76", "quote 1.0.35", @@ -1800,16 +1897,16 @@ dependencies = [ [[package]] name = "gtk4-sys" -version = "0.6.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f8283f707b07e019e76c7f2934bdd4180c277e08aa93f4c0d8dd07b7a34e22f" +checksum = "0db1b104138f087ccdc81d2c332de5dd049b89de3d384437cc1093b17cd2da18" dependencies = [ - "cairo-sys-rs", + "cairo-sys-rs 0.19.2", "gdk-pixbuf-sys", "gdk4-sys", - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.19.0", + "glib-sys 0.19.0", + "gobject-sys 0.19.0", "graphene-sys", "gsk4-sys", "libc", @@ -1819,14 +1916,12 @@ dependencies = [ [[package]] name = "gvdb" -version = "0.4.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7139233c0ecb66f285c47a3c1c02b35c8d52a42ca4c7448d0163e5637bb4bd3" +checksum = "0bb9136c388a1e7b3017d18fe7c2f263b0a2b13f215c48e8eb44935d413ce0f9" dependencies = [ "byteorder", "flate2", - "lazy_static", - "memmap2 0.7.1", "quick-xml", "safe-transmute", "serde", @@ -2206,15 +2301,14 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libadwaita" -version = "0.4.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf" +checksum = "91b4990248b9e1ec5e72094a2ccaea70ec3809f88f6fd52192f2af306b87c5d9" dependencies = [ - "bitflags 1.3.2", "gdk-pixbuf", "gdk4", "gio", - "glib", + "glib 0.19.2", "gtk4", "libadwaita-sys", "libc", @@ -2223,14 +2317,14 @@ dependencies = [ [[package]] name = "libadwaita-sys" -version = "0.4.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404" +checksum = "23a748e4e92be1265cd9e93d569c0b5dfc7814107985aa6743d670ab281ea1a8" dependencies = [ "gdk4-sys", - "gio-sys", - "glib-sys", - "gobject-sys", + "gio-sys 0.19.0", + "glib-sys 0.19.0", + "gobject-sys 0.19.0", "gtk4-sys", "libc", "pango-sys", @@ -2275,7 +2369,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.2", "libc", "redox_syscall 0.4.1", ] @@ -2286,7 +2380,7 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.2", "libc", "redox_syscall 0.4.1", ] @@ -2362,15 +2456,6 @@ dependencies = [ "libc", ] -[[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.6.5" @@ -2729,7 +2814,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2 1.0.76", "quote 1.0.35", "syn 1.0.109", @@ -2741,7 +2826,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2 1.0.76", "quote 1.0.35", "syn 2.0.48", @@ -2833,7 +2918,7 @@ version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.2", "cfg-if", "foreign-types", "libc", @@ -2903,26 +2988,24 @@ dependencies = [ [[package]] name = "pango" -version = "0.17.10" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35be456fc620e61f62dff7ff70fbd54dcbaf0a4b920c0f16de1107c47d921d48" +checksum = "7809e8af4df8d024a066106b72ca6bc7253a484ae3867041a96103ef8a13188d" dependencies = [ - "bitflags 1.3.2", "gio", - "glib", + "glib 0.19.2", "libc", - "once_cell", "pango-sys", ] [[package]] name = "pango-sys" -version = "0.17.10" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da69f9f3850b0d8990d462f8c709561975e95f689c1cdf0fecdebde78b35195" +checksum = "f52ef6a881c19fbfe3b1484df5cad411acaaba29dbec843941c3110d19f340ea" dependencies = [ - "glib-sys", - "gobject-sys", + "glib-sys 0.19.0", + "gobject-sys 0.19.0", "libc", "system-deps", ] @@ -3107,9 +3190,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plotters" @@ -3180,6 +3263,15 @@ dependencies = [ "toml_edit 0.19.11", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.0", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -3288,9 +3380,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" dependencies = [ "memchr", "serde", @@ -3440,12 +3532,11 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "relm4" -version = "0.6.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c16f3fad883034773b7f5af4d7e865532b8f3641e5a8bab2a34561a8d960d81" +checksum = "e6e0e187b58db367305e8486d3228158251da1c8ba1e18baa9de61894e822649" dependencies = [ - "async-trait", - "flume", + "flume 0.11.0", "fragile", "futures", "gtk4", @@ -3458,9 +3549,9 @@ dependencies = [ [[package]] name = "relm4-components" -version = "0.6.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5485d72dc94c12a59c571d80cf9a545e5b9a2f0ebc90ea5fd234929a9376f66d" +checksum = "ffcb6431605810fca4430b3da5d496fcf67d39f32db6a2799bcaac27469154b9" dependencies = [ "once_cell", "relm4", @@ -3469,19 +3560,21 @@ dependencies = [ [[package]] name = "relm4-icons" -version = "0.6.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e28bcc718a587bcfa31b034e0b8f4efe5b70e945b7de9d7d154b45357a0dadc" +checksum = "8603f50e9ed5ca2e3759a9c6033e4058c7b984f1bd22b1fc3b1a162c5612eb64" dependencies = [ "gtk4", "gvdb", + "serde", + "toml 0.8.11", ] [[package]] name = "relm4-macros" -version = "0.6.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9340e2553c0a184a80a0bfa1dcf73c47f3d48933aa6be90724b202f9fbd24735" +checksum = "0774e846889823aa5766f5b62cface3189a5b36280e65b2faaa6df0319da1726" dependencies = [ "proc-macro2 1.0.76", "quote 1.0.35", @@ -3590,7 +3683,7 @@ version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", @@ -3678,7 +3771,7 @@ checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" dependencies = [ "ab_glyph", "log", - "memmap2 0.5.10", + "memmap2", "smithay-client-toolkit", "tiny-skia", ] @@ -3714,18 +3807,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2 1.0.76", "quote 1.0.35", @@ -3895,7 +3988,7 @@ dependencies = [ "dlib", "lazy_static", "log", - "memmap2 0.5.10", + "memmap2", "nix 0.24.3", "pkg-config", "wayland-client", @@ -4044,7 +4137,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.2", "core-foundation", "system-configuration-sys", ] @@ -4300,14 +4393,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.22.7", ] [[package]] @@ -4337,12 +4430,23 @@ name = "toml_edit" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.35", +] + +[[package]] +name = "toml_edit" +version = "0.22.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.5.35", + "winnow 0.6.5", ] [[package]] @@ -5095,6 +5199,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" @@ -5265,7 +5378,7 @@ version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "934d7a7dfc310d6ee06c87ffe88ef4eca7d3e37bb251dece2ef93da8f17d8ecd" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2 1.0.76", "quote 1.0.35", "syn 1.0.109", diff --git a/Cargo.toml b/Cargo.toml index 0593771..9c52a0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,10 +9,7 @@ edition = "2021" [dependencies] cairo-rs = { version = "0.17.0" } glib = "0.17.9" -gtk = { version = "0.6.6", package = "gtk4", features = ["v4_8"] } - -# gtk = "0.15.5" - +gtk = { version = "0.8.1", package = "gtk4", features = ["v4_12"] } geo-types = "0.7.9" shapefile = { version = "0.4", features = ["geo-types"] } thiserror = "1.0.40" @@ -31,8 +28,8 @@ glow = "0.12.2" proj = "0.27.2" image = "0.24.7" anyhow = "1.0.72" -relm4 = { version = "0.6.1", features = ["libadwaita"] } -relm4-components = "0.6.1" +relm4 = { version = "0.8.1", features = ["libadwaita"] } +relm4-components = "0.8.1" rstar = "*" geo = "0.26.0" topojson = "0.5.1" @@ -42,31 +39,11 @@ core_extensions = { version = "1.5.2", default_features = false, features = [ "std", ] } plotters-backend = "0.3.5" -#tokio = { version = "1.35.1", features = [ -# "time", -# "fs", -# "io-std", -# "macros", -# "num_cpus", -# "bytes", -# "io-util", -#] } tokio = { version = "1.36.0", features = ["full"] } async-trait = "0.1.77" lazy_static = "1.4.0" once_cell = "1.19.0" -relm4-icons = { version = "0.6.0", features = [ - "add-filled", - "delete-filled", - "chevron-up-filled", - "chevron-down-filled", - "play-filled", - "rewind-filled", - "fast-forward-filled", - "home-filled", - "settings-filled", - "save-filled", -] } +relm4-icons = { version = "0.8.2" } surfman = "0.8.1" euclid = "0.22.9" gl = "0.14.0" diff --git a/icons.toml b/icons.toml new file mode 100644 index 0000000..0246c9f --- /dev/null +++ b/icons.toml @@ -0,0 +1,21 @@ +# Recommended: Specify your app ID *OR* your base resource path for more robust icon loading +app_id = "org.tsuki.radar_g" +base_resource_path = "/org/tsuki/radar_g" + +# List of icon names you found (shipped with this crate) +# Note: the file ending `-symbolic.svg` isn't part of the icon name. +icons = [ + "add-filled", + "delete-filled", + "chevron-up-filled", + "chevron-down-filled", + "play-filled", + "rewind-filled", + "fast-forward-filled", + "home-filled", + "settings-filled", + "save-filled", +] + +# Optional: Specify a folder containing your own SVG icons +icon_folder = "svg_icons" diff --git a/ne_110m_admin_0_countries.zip b/ne_110m_admin_0_countries.zip deleted file mode 100644 index aca6ab2..0000000 Binary files a/ne_110m_admin_0_countries.zip and /dev/null differ diff --git a/src/components/monitor/messages.rs b/src/components/monitor/messages.rs index 2207053..7d7c0a1 100644 --- a/src/components/monitor/messages.rs +++ b/src/components/monitor/messages.rs @@ -16,7 +16,7 @@ pub enum MonitorInputMsg { RefreshTiles, RefreshLayerList, SetRenderRange(f64, f64, f64, f64), - ChangeZoom(u8), + ChangeZoom(f64), None, } @@ -26,7 +26,9 @@ impl Debug for MonitorInputMsg { MonitorInputMsg::RefreshRender => write!(f, "MonitorInputMsg::RefreshRender"), MonitorInputMsg::RefreshTiles => write!(f, "MonitorInputMsg::RefreshTiles"), MonitorInputMsg::ChangeZoom(_) => write!(f, "MonitorInputMsg::ChangeZoom"), - MonitorInputMsg::SetRenderRange(_, _, _, _) => write!(f, "MonitorInputMsg::SetRenderRange"), + MonitorInputMsg::SetRenderRange(_, _, _, _) => { + write!(f, "MonitorInputMsg::SetRenderRange") + } MonitorInputMsg::RefreshLayerList => write!(f, "MonitorInputMsg::RefreshLayerList"), MonitorInputMsg::None => write!(f, "MonitorInputMsg::None"), MonitorInputMsg::AddWidget(_) => write!(f, "MonitorInputMsg::AddWidget"), diff --git a/src/components/monitor/monitor.rs b/src/components/monitor/monitor.rs index 6d3110d..7eee1c8 100644 --- a/src/components/monitor/monitor.rs +++ b/src/components/monitor/monitor.rs @@ -1,4 +1,3 @@ -use tracing::*; use super::messages::{MonitorInputMsg, MonitorOutputMsg}; use crate::coords::cms::CMS; use crate::pipeline::offscreen_renderer::OffscreenRenderer; @@ -18,12 +17,14 @@ use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; use std::sync::{Arc, Mutex}; +use tracing::*; use super::sidebar::{sidebar::SideBarModel, SideBarInputMsg, SideBarOutputMsg}; use crate::coords::Range; use crate::map_tile::MapTile; use crate::map_tile_utils::lat_lon_to_zoom; use crate::pipeline::element::Target; +use crate::utils::estimate_zoom_level; use adw::prelude::*; use femtovg::ImageId; use fns::debounce; @@ -31,11 +32,10 @@ use relm4::{component::Component, *}; use slippy_map_tiles::Tile; use tokio::task; use tracing::instrument::WithSubscriber; -use crate::utils::estimate_zoom_level; #[derive(Debug)] pub enum MonitorCommand { - LoadedTile(Tile), + LoadedTile, None, } #[tracker::track] @@ -44,8 +44,6 @@ pub struct MonitorModel { render_range: (f64, f64, f64, f64), sidebar_open: bool, sidebar_width: i32, - #[do_not_track] - debouncer: Rc, zoom: u8, #[do_not_track] last_call: Rc>, @@ -105,17 +103,20 @@ impl Component for MonitorModel { connect_render_status_notify[sender] => move |r| { sender.output(MonitorOutputMsg::LayerRenderFinished); }, - // connect_range_changing_notify[sender] => move |r| { - // sender.input(MonitorInputMsg::RefreshTiles); - // }, - // connect_scale_notify => move |r| { - // let ((x1,x2), (y1,y2)) = r.render_range(); - // let (w, h) = r.window_size(); - // let new_zoom = estimate_zoom_level(x1,x2,y1,y2,w as f64, h as f64); - // if model.zoom != new_zoom { - // debouncer(new_zoom); - // } - // }, + connect_range_changing_notify[sender] => move |r| { + sender.input(MonitorInputMsg::RefreshTiles); + }, + connect_scale_notify[sender] => move |r| { + let scale = r.scale(); + { + let initial = r.scale_rate(); + let mut rate_start = initial_rate.lock().unwrap(); + if rate_start.is_none() { + *rate_start = Some(scale); + } + } + debouncer.call(scale); + }, set_interior_layers: model.layers.clone(), }, add_overlay=>k::Button{ @@ -157,9 +158,11 @@ impl Component for MonitorModel { self.sidebar.emit(SideBarInputMsg::AddMetaItems(map)) } MonitorInputMsg::SetRenderRange(lon_start, lon_end, lat_start, lat_end) => { + let current_rate = widgets.renderer.scale_rate(); self.set_render_range((lat_start, lat_end, lon_start, lon_end)); - let r = &widgets.renderer; - (*self.debouncer)(10); + let new_rate = widgets.renderer.scale_rate(); + let zoom: f64 = (current_rate / new_rate).log2(); + sender.input(MonitorInputMsg::ChangeZoom(zoom)); } MonitorInputMsg::ClearMetaItems => self.sidebar.emit(SideBarInputMsg::ClearMetaItems), MonitorInputMsg::UpdateMetaItem(map) => { @@ -167,7 +170,7 @@ impl Component for MonitorModel { self.sidebar.emit(SideBarInputMsg::AddMetaItems(map)) } MonitorInputMsg::RefreshTiles => { - let ((x1 , x2), (y1,y2)) = widgets.renderer.render_range(); + let ((x1, x2), (y1, y2)) = widgets.renderer.render_range(); self.load_tile(&sender, ((y1 as f32, y2 as f32), (x1 as f32, x2 as f32))); } MonitorInputMsg::AddWidget(widget) => match widget.widget_type() { @@ -180,9 +183,10 @@ impl Component for MonitorModel { _ => {} }, MonitorInputMsg::ChangeZoom(zoom) => { - if self.zoom != zoom { - self.zoom = zoom; - self.map_tile_getter.set_zoom(zoom); + let new_zoom = (self.zoom as f64 + zoom).clamp(0.0, 19.0).round() as u8; + if self.zoom != new_zoom { + self.zoom = new_zoom; + self.map_tile_getter.set_zoom(new_zoom); sender.input(MonitorInputMsg::RefreshTiles); } } @@ -211,19 +215,11 @@ impl Component for MonitorModel { }); let render_cfg = RenderConfig { - padding: [20.0, 40.0, 20.0, 40.0], + padding: [0.0, 0.0, 0.0, 0.0], }; let new_sender = sender.clone(); - let _debouncer = fns::debounce(move |new_zoom: u8| { - new_sender.input(MonitorInputMsg::ChangeZoom(new_zoom)); - }, std::time::Duration::from_millis(500)); - - let debouncer = move |zoom: u8| { - _debouncer.call(zoom); - }; - let mut model = MonitorModel { render_range: (4.0, 53.3, 73.3, 135.0), new_layer: 0, @@ -231,17 +227,26 @@ impl Component for MonitorModel { render_cfg, sidebar_open: true, sidebar_width: 400, - last_call : Rc::new(RefCell::new(std::time::Instant::now())), + last_call: Rc::new(RefCell::new(std::time::Instant::now())), layers: init, zoom: 4, - debouncer : Rc::new(debouncer), map_tile_getter: Rc::new(MapTile::default()), sidebar, tracker: 0, }; - let last_call = model.last_call.clone(); - let debouncer = model.debouncer.clone(); + let initial_rate = Arc::new(Mutex::new(None)); + let debouncer_rate = initial_rate.clone(); + let debouncer_sender = sender.clone(); + let debouncer = fns::debounce( + move |zoom: f64| { + let rate: f64 = debouncer_rate.lock().unwrap().take().unwrap(); + let zoom: f64 = (rate / zoom).log2(); + debouncer_sender.input(MonitorInputMsg::ChangeZoom(zoom)); + debouncer_sender.input(MonitorInputMsg::RefreshRender); + }, + std::time::Duration::from_millis(500), + ); let widgets = view_output! {}; ComponentParts { model, widgets } @@ -256,7 +261,7 @@ impl Component for MonitorModel { ) { self.reset(); match message { - MonitorCommand::LoadedTile(tile) => { + MonitorCommand::LoadedTile => { sender.input(MonitorInputMsg::RefreshRender); } _ => {} @@ -265,15 +270,12 @@ impl Component for MonitorModel { } } - impl MonitorModel { - fn load_tile(&self, sender: &ComponentSender, range:((f32,f32), (f32,f32))) { - + fn load_tile(&self, sender: &ComponentSender, range: ((f32, f32), (f32, f32))) { let task = self.map_tile_getter.load_tiles(range, sender.clone()); sender.oneshot_command(async move { task.await; MonitorCommand::None }); } - -} \ No newline at end of file +} diff --git a/src/components/monitor/sidebar/sidebar.rs b/src/components/monitor/sidebar/sidebar.rs index 174b457..b05264e 100644 --- a/src/components/monitor/sidebar/sidebar.rs +++ b/src/components/monitor/sidebar/sidebar.rs @@ -1,28 +1,28 @@ -use abi_stable::type_level::trait_marker::Hash; -use relm4::safe_settings_and_actions::extensions::SafeSimpleAction; use super::actions::*; +use crate::widgets::AssoElement; +use abi_stable::type_level::trait_marker::Hash; +use chrono::{DateTime, Utc}; use glib::clone; use gtk::prelude::WidgetExt; use gtk::prelude::*; +use relm4::actions::{AccelsPlus, RelmAction}; +use relm4::safe_settings_and_actions::extensions::SafeSimpleAction; use relm4::{ - gtk::gio, binding::{Binding, U8Binding}, factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque}, + gtk::gio, prelude::*, typed_list_view::{RelmListItem, TypedColumnView, TypedListView}, RelmObjectExt, }; use std::{cell::RefCell, collections::HashMap, rc::Rc}; -use chrono::{DateTime, Utc}; -use relm4::actions::{AccelsPlus, RelmAction}; -use crate::widgets::AssoElement; +use crate::components::app::AppMsg; use crate::{ chart::Chart, data::Npz, widgets::render::{predefined::color_mapper::BoundaryNorm, Layer}, }; -use crate::components::app::AppMsg; use super::{ bottom_bar::BottomBarModel, @@ -49,7 +49,7 @@ pub enum SideBarInputMsg { #[derive(Debug)] pub enum SideBarOutputMsg { NewLayer(Layer), - SwitchToTimeSeries(usize) + SwitchToTimeSeries(usize), } #[relm4::component(pub)] @@ -168,12 +168,19 @@ impl SimpleComponent for SideBarModel { .borrow() .iter() .enumerate() - .map(|(idx, v)| LayerItem::new(idx as u32,v.name.clone(), v.visiable, v.get_thumbnail(), match v.get_associated_element() { - AssoElement::TimeSeries(_) => LayerStatus::BindToTime(Utc::now()), - AssoElement::Instant(_) => LayerStatus::Instance, - _ => LayerStatus::Instance - - })) + .map(|(idx, v)| { + LayerItem::new( + idx as u32, + v.name.clone(), + v.visiable, + v.get_thumbnail(), + match v.get_associated_element() { + AssoElement::TimeSeries(_) => LayerStatus::BindToTime(Utc::now()), + AssoElement::Instant(_) => LayerStatus::Instance, + _ => LayerStatus::Instance, + }, + ) + }) .collect::>(); model.list_view_wrapper.extend_from_iter(list); } @@ -189,12 +196,19 @@ impl SimpleComponent for SideBarModel { .borrow() .iter() .enumerate() - .map(|(idx, v)| LayerItem::new(idx as u32,v.name.clone(), v.visiable, v.get_thumbnail(),match v.get_associated_element() { - AssoElement::TimeSeries(_) => LayerStatus::BindToTime(Utc::now()), - AssoElement::Instant(_) => LayerStatus::Instance, - _ => LayerStatus::Instance - - })) + .map(|(idx, v)| { + LayerItem::new( + idx as u32, + v.name.clone(), + v.visiable, + v.get_thumbnail(), + match v.get_associated_element() { + AssoElement::TimeSeries(_) => LayerStatus::BindToTime(Utc::now()), + AssoElement::Instant(_) => LayerStatus::Instance, + _ => LayerStatus::Instance, + }, + ) + }) .collect::>(); self.list_view_wrapper.clear(); self.list_view_wrapper.extend_from_iter(list); @@ -216,7 +230,7 @@ impl SimpleComponent for SideBarModel { enum LayerStatus { BindToTime(DateTime), Instance, - BindToOtherLayer(usize) + BindToOtherLayer(usize), } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -229,7 +243,13 @@ struct LayerItem { } impl LayerItem { - fn new(key: u32,name: String, visiable: bool, img: Option, status: LayerStatus) -> Self { + fn new( + key: u32, + name: String, + visiable: bool, + img: Option, + status: LayerStatus, + ) -> Self { Self { key, layer_name: name, @@ -299,7 +319,6 @@ impl RelmListItem for LayerItem { } fn bind(&mut self, widgets: &mut Self::Widgets, _root: &mut Self::Root) { - let Widgets { label, button, @@ -317,7 +336,7 @@ impl RelmListItem for LayerItem { status.set_label(&match self.status { LayerStatus::BindToTime(t) => format!("Bind To Time: {}", t), LayerStatus::Instance => "Instance".to_string(), - LayerStatus::BindToOtherLayer(idx) => format!("Bind To Layer: {}", idx) + LayerStatus::BindToOtherLayer(idx) => format!("Bind To Layer: {}", idx), }); let gesture_click = gtk::GestureClick::new(); diff --git a/src/map_tile.rs b/src/map_tile.rs index 50b02f5..9ffe353 100644 --- a/src/map_tile.rs +++ b/src/map_tile.rs @@ -1,23 +1,40 @@ -use std::cell::{Cell, RefCell}; +use crate::components::messages::MonitorInputMsg; +use crate::components::{MonitorCommand, MonitorModel}; use crate::coords::Range; use crate::map_tile_utils::lat_lon_to_zoom; use crate::pipeline::element::{Target, TargetType}; +use dirs::cache_dir; use femtovg::ImageSource; use futures::future::BoxFuture; use gtk::ffi::gtk_about_dialog_add_credit_section; +use once_cell::sync::Lazy; use quick_cache::sync::Cache; +use relm4::{ComponentSender, Sender}; use reqwest::{Client, Error, Url}; use slippy_map_tiles::{merc_location_to_tile_coords, BBox, Tile}; use smallvec::SmallVec; use sorted_vec::SortedSet; +use std::cell::{Cell, RefCell}; use std::collections::HashSet; +use std::path::PathBuf; use std::sync::Arc; -use relm4::{ComponentSender, Sender}; use tokio::sync::Mutex; use tokio::task; use tracing::{debug, info}; -use crate::components::messages::MonitorInputMsg; -use crate::components::{MonitorCommand, MonitorModel}; + +static TILE_CACHE_PATH: Lazy> = Lazy::new(|| { + let new_path = cache_dir() + .unwrap_or(PathBuf::from("./")) + .join("radar-g/tiles"); + + if !new_path.exists() { + info!("Create cache dir: {:?}", new_path); + std::fs::create_dir_all(&new_path).unwrap(); + } + std::sync::Mutex::new(new_path) +}); + +type TileCache = Cache>>; pub struct MapTile { server: String, @@ -25,7 +42,7 @@ pub struct MapTile { style: String, client: Client, onloading: Arc>>, - cache: Arc>>>>, + cache: Arc>, zoom_level: Cell, } @@ -34,9 +51,10 @@ impl Default for MapTile { Self { server: "https://tiles.stadiamaps.com/tiles/".to_string(), api_key: "06f1aeed-5d91-48e3-9ce5-1e99063f7f73".to_string(), - style: "stamen_toner".to_string(), + // style: "stamen_toner".to_string(), + style: "alidade_smooth_dark".to_string(), client: Client::new(), - onloading: Arc::new(std::sync::Mutex::new( HashSet::new())), + onloading: Arc::new(std::sync::Mutex::new(HashSet::new())), cache: Arc::new(std::sync::Mutex::new(Cache::new(32))), zoom_level: Cell::new(4), } @@ -55,31 +73,54 @@ impl MapTile { tiles } - fn get_tile_task(&self, tile: &Tile) -> BoxFuture<'static, Result, Error>> { - let base_url = Url::parse(&self.server).unwrap(); - let mut request_url = base_url - .join(&format!("{}/", self.style)) - .unwrap() - .join(&format!("{}/{}/{}.png", tile.zoom(), tile.x(), tile.y())) - .unwrap(); - let client = self.client.clone(); - let key = self.api_key.clone(); - Box::pin(async move { - let result = client - .get(request_url) - .query(&[("api_key", &key)]) - .send() - .await?; - let bytes = result.bytes().await?; - Ok(bytes.to_vec()) - }) + fn get_tile_task(&self, tile: &Tile) -> (bool, BoxFuture<'static, Result, Error>>) { + let _cache_path = TILE_CACHE_PATH.lock().unwrap().clone().join(format!( + "{}-{}-{}.png", + tile.zoom(), + tile.x(), + tile.y() + )); + let exists_cache = _cache_path.exists(); + if exists_cache { + let client = self.client.clone(); + let key = self.api_key.clone(); + ( + false, + Box::pin(async move { + info!("Read from cache: {:?}", _cache_path); + let result = tokio::fs::read(_cache_path).await.unwrap(); + Ok(result) + }), + ) + } else { + let base_url = Url::parse(&self.server).unwrap(); + let mut request_url = base_url + .join(&format!("{}/", self.style)) + .unwrap() + .join(&format!("{}/{}/{}@2x.png", tile.zoom(), tile.x(), tile.y())) + .unwrap(); + let client = self.client.clone(); + let key = self.api_key.clone(); + ( + true, + Box::pin(async move { + let result = client + .get(request_url) + .query(&[("api_key", &key)]) + .send() + .await?; + let bytes = result.bytes().await?; + Ok(bytes.to_vec()) + }), + ) + } } pub async fn get_tile(&self, tile: &Tile) -> Result, Error> { let base_url = Url::parse(&self.server).unwrap(); let mut request_url = base_url .join(&self.style) .unwrap() - .join(&format!("{}/{}/{}.png", tile.zoom(), tile.x(), tile.y())) + .join(&format!("{}/{}/{}@2x.png", tile.zoom(), tile.x(), tile.y())) .unwrap(); let result = self @@ -96,6 +137,24 @@ impl MapTile { self.zoom_level.set(zoom); } + fn insert_to_cache(cache: Arc>, result: Vec, tile: Tile) { + let origin = tile.nw_corner(); + let rb = tile.se_corner(); + let bounds = ( + (origin.lon() as f64..rb.lon() as f64).into(), + (origin.lat() as f64..rb.lat() as f64).into(), + ); + let result = Target::new(TargetType::Mem(result), 256.0, 256.0, bounds, None, None); + let cache = cache.lock().unwrap(); + cache.insert(tile, Arc::new(std::sync::Mutex::new(result))); + } + + async fn save_to_cache_path(result: &Vec, tile: Tile) -> Result<(), std::io::Error> { + let _cache_path = TILE_CACHE_PATH.lock().unwrap().clone(); + let path = _cache_path.join(format!("{}-{}-{}.png", tile.zoom(), tile.x(), tile.y())); + tokio::fs::write(path, result).await + } + pub fn load_tiles( &self, range: ((f32, f32), (f32, f32)), @@ -112,47 +171,46 @@ impl MapTile { if new_tiles.len() > 0 { bindings.extend(new_tiles.iter().cloned()); info!("Load new tiles"); - let tasks = new_tiles.into_iter().map(move |tile| { - let _task = self.get_tile_task(&tile); - let sender = sender.clone(); - let cache = self.cache.clone(); - let onloading = self.onloading.clone(); - task::spawn(async move { - let result = _task.await; - if let Ok(result) = result { - let origin = tile.nw_corner(); - let rb = tile.se_corner(); - let bounds = ( - (origin.lon() as f64..rb.lon() as f64).into(), - (origin.lat() as f64..rb.lat() as f64).into(), - ); - let result = Target::new( - TargetType::Mem(result), - 256.0, - 256.0, - bounds, - None, - None - ); - cache.lock().unwrap().insert(tile, Arc::new(std::sync::Mutex::new(result))); - onloading.lock().unwrap().remove(&tile); - sender.command_sender().emit(MonitorCommand::LoadedTile(tile)); - } + let tasks = new_tiles + .into_iter() + .map(move |tile| { + let (need_save, _task) = self.get_tile_task(&tile); + let sender = sender.clone(); + let cache = self.cache.clone(); + let onloading = self.onloading.clone(); + task::spawn(async move { + let result = _task.await; + if let Ok(result) = result { + if let Err(e) = Self::save_to_cache_path(&result, tile).await { + info!("Error saving to cache: {}", e); + } + if need_save { + Self::save_to_cache_path(&result, tile); + } + Self::insert_to_cache(cache, result, tile); + onloading.lock().unwrap().remove(&tile); + sender.command_sender().emit(MonitorCommand::LoadedTile); + } + }) }) - }).collect::>(); + .collect::>(); return Box::pin(async move { for task in tasks { task.await.unwrap(); } }); } else { - info!("No new tiles to load"); + info!("No new tiles need to download"); + return Box::pin(async move { + sender.command_sender().emit(MonitorCommand::LoadedTile); + }); } - - Box::pin(async move {}) } - pub fn current_tiles(&self, range: ((f32, f32), (f32, f32))) -> Vec>> { + pub fn current_tiles( + &self, + range: ((f32, f32), (f32, f32)), + ) -> Vec>> { let zoom = self.zoom_level.get(); let current = self.new_tiles(zoom, range.0, range.1); let mut total_len = 0; @@ -182,7 +240,6 @@ impl MapTile { break; } } - start_zoom -= 1; } } diff --git a/src/utils.rs b/src/utils.rs index 73a6ec7..4444bf6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,6 @@ use chrono::{DateTime, Utc}; use femtovg::Color; -use gtk::glib::{HasParamSpec, ParamSpecInt64, ParamSpecInt64Builder, ToValue}; +use gtk::glib::{HasParamSpec, ParamSpecInt64, ParamSpecInt64Builder}; use std::{borrow::BorrowMut, num::NonZeroU32}; use euclid::Size2D; @@ -12,10 +12,13 @@ use surfman::{ }; use crate::widgets::render::predefined::color_mapper::BoundaryNorm; -use std::sync::Arc; -use std::time::{Duration}; -use tokio::{time, sync::{Mutex, mpsc, oneshot}}; use crate::RUNTIME; +use std::sync::Arc; +use std::time::Duration; +use tokio::{ + sync::{mpsc, oneshot, Mutex}, + time, +}; pub fn meshgrid(x: ArrayView1, y: ArrayView1) -> (Array2, Array2) where @@ -336,12 +339,20 @@ pub fn create_kdp_boundarynorm() -> BoundaryNorm { ) } - -pub fn estimate_zoom_level(lat_min: f64, lon_min: f64, lat_max: f64, lon_max: f64, screen_width: f64, screen_height: f64) -> u8 { +pub fn estimate_zoom_level( + lat_min: f64, + lon_min: f64, + lat_max: f64, + lon_max: f64, + screen_width: f64, + screen_height: f64, +) -> u8 { let r: f64 = 6371.0; let avg_lat = (lat_min + lat_max) / 2.0; // 将经纬度范围转换为在该纬度下的公里数 - let delta_lon = (lon_max - lon_min) * (r * std::f64::consts::PI / 180.0) * (avg_lat * std::f64::consts::PI / 180.0).cos().abs(); + let delta_lon = (lon_max - lon_min) + * (r * std::f64::consts::PI / 180.0) + * (avg_lat * std::f64::consts::PI / 180.0).cos().abs(); let delta_lat = (lat_max - lat_min) * 111.32; // 估算每个像素代表的实际距离(公里/像素) @@ -356,4 +367,4 @@ pub fn estimate_zoom_level(lat_min: f64, lon_min: f64, lat_max: f64, lon_max: f6 let zoom_level_estimation = 14.0 - km_per_pixel.log10(); zoom_level_estimation.round() as u8 -} \ No newline at end of file +} diff --git a/src/widgets/render/mod.rs b/src/widgets/render/mod.rs index 5f7679d..30b0195 100644 --- a/src/widgets/render/mod.rs +++ b/src/widgets/render/mod.rs @@ -1,3 +1,4 @@ +use tracing::info; mod cms; mod exterior; mod imp; @@ -48,6 +49,8 @@ impl Render { this.set_mapper(mapper); } + let scale_acc = Arc::new(Mutex::new(0.0)); + let dpi = this.scale_factor() as f32; let pointer_location_detecture = gtk::EventControllerMotion::new(); pointer_location_detecture.connect_motion( @@ -62,17 +65,8 @@ impl Render { ); let scale_detecture = gtk::EventControllerScroll::new(EventControllerScrollFlags::VERTICAL); - let _r = Mutex::new(this.clone()); - - let debouncer = fns::debounce( - move |scale: f64| { - _r.lock().unwrap().set_scale(scale); - }, - std::time::Duration::from_millis(500), - ); - scale_detecture.connect_scroll(clone!( - @weak this as r => @default-panic,move |_context, _x, y| { + @weak this as r, @strong scale_acc => @default-panic,move |_context, _x, y| { let mut rate = 0.0; r.update_status(|s|{ let scale_rate = s.scale_rate.unwrap(); @@ -81,8 +75,9 @@ impl Render { let (tx, ty) = s.translation; let (px, py) = s.pointer_location; let scaled = scale_rate + scale_flag * step; + // rate = scale_rate / scaled; s.scale_rate = Some(scaled); - rate = scaled / 1.0; + rate = scaled; let sx = scale_flag * step * px as f64; let sy = scale_flag * step * py as f64; s.translation = (tx - sx, ty - sy); @@ -90,7 +85,7 @@ impl Render { s.motion = RenderMotion::Scale; }); r.queue_render(); - debouncer.call(rate); + r.set_scale(rate); Inhibit(true) } )); @@ -268,6 +263,9 @@ impl Render { cvs.delete_image(id); } } -} -unsafe impl Send for Render {} \ No newline at end of file + pub fn scale_rate(&self) -> f64 { + let status = self.imp().status.borrow(); + status.scale_rate.unwrap() + } +} diff --git a/src/widgets/timeline/imp.rs b/src/widgets/timeline/imp.rs index ef796d3..1bc8bba 100644 --- a/src/widgets/timeline/imp.rs +++ b/src/widgets/timeline/imp.rs @@ -1,5 +1,5 @@ use chrono::{prelude::*, Duration}; -use gtk::glib::{self, prelude::*, ParamSpec, Properties, Property, Value}; +use gtk::glib::{self, prelude::*, ParamSpec, Properties, Value}; use gtk::prelude::*; use gtk::subclass::prelude::*; use std::cell::{Cell, RefCell}; @@ -50,7 +50,7 @@ impl Default for TimeLine { start_time: Cell::new(Utc::now()), start_time_stamp: Cell::new(i64::MIN), end_time_stamp: Cell::new(i64::MIN), - dpi: Cell::new(3600f64/30.0), + dpi: Cell::new(3600f64 / 30.0), } } } diff --git a/test.txt b/test.txt deleted file mode 100644 index c9c604e..0000000 --- a/test.txt +++ /dev/null @@ -1,57 +0,0 @@ -COLOR = { - 'dbz': { - 'colors': ['#17AEA5','#C6C3FD',"#7C72EC","#01a0f6", "#00ecec", "#00d800", "#019000", "#ffff00", "#e7c000", "#ff9000", "#ff0000", "#d60000","#c00000", "#ff00f0", "#9600b4", "#8b00ff"], - 'numbar': [-5,0,5,10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75], - }, - - 'vel': { - 'colors': ["#00e0ff", "#0080ff", "#320096", "#00fb90", "#00bb90", "#008f00", "#cdc09f", "#ffffff", "#f88700", - "#ffcf00", "#ffff00", "#ae0000", "#d07000", "#ff0000"], - 'numbar': [-35, -27, -20, -15, -10, -5, -1, 0, 1, 5, 10, 15, 20, 27, 35], - }, - 'W': { - 'colors': ["#e0e0e0", "#7ce0e0", "#00e0e0", "#00b0b0", "#00fefe", "#00c400", "#008000", "#fefe00", "#fed200", - "#fe7c00", "#feb0b0", "#fe5858", "#fe0000", "#fefefe"], - 'numbar': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16], - }, - 'PhiDP': { - 'colors': ["#003cff", "#00efef", "#00babf", "#00837d", "#008938", "#00b729", "#00da0d", "#00ff00", "#ffff3b", - "#fff000", "#ffc600", "#ffa500", "#ff7200", "#ff1f00", "#c10000"], - 'numbar': [0, 22, 46, 68, 90, 112, 136, 158, 180, 202, 224, 248, 270, 292, 314, 359], - }, - 'KDP': { - 'colors': ["#00ffff", "#00efef", "#00a8ac", "#b4b4b4", "#b4b4b4", "#00c027", "#00e80a", "#24ff24", "#ffff1e", - "#ffe600", "#ffbc00", "#ff9800", "#ff5e00", "#f20f00", "#bb003a",'#FD06FD'], - 'numbar': [-0.8, -0.4, -0.2, -0.1, 0.1, 0.15, 0.22, 0.33, 0.5, 0.75, 1.1, 1.7, 2.4, 3.1, 7, 20], - }, - 'ZDR': { - 'colors': ["#464646", '#505050','#5A5A5A','#646464',"#6e6e6e",'#787878', '#828282','#8C8C8C',"#969696", '#AFAFAF', "#c8c8c8","#dcf0dc", "#00c027", "#00e80a", "#24ff24", - "#ffff1e","#FEF133", '#FEE52D',"#ffbc00", "#ff9800", "#ff5e00", "#f20f00", "#bb003a",'#DB009B','#FD06FD'], - 'numbar': [-5,-4.5,-4,-3.5, -3,-2.5,-2,-1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5,3, 3.5, 4, 4.5, 5, 5.5, 6,6.5, 7,8], - }, - 'LDR': { - 'colors': ["#c80300", "#c80300", "#fd250f", "#fe6f02", "#fdaa0a", "#fbcb00", "#f3ee04", "#fbfa38", "#00f400", - "#02d303", "#12c434", "#058e3e", "#058174", "#0ac2c7", "#02f0f0"], - 'numbar': [-30, -28, -26, -24, -22, -20, -18, -16, -14, -12, -10, -9, -8, -7, -6, -5], - }, - 'CC': { - 'colors': ["#003cff", "#00efef", "#00babf", "#00837d", "#008938", "#00b729", "#00da0d", "#00ff00", "#ffff3b", - "#fff000", "#ffc600", "#ffa500", "#ff7200", "#ff1f00", "#c10000"], - 'numbar': [0, 0.1, 0.3, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9, 0.92, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99], - }, - 'VIL': { - 'colors': ["#9c9c9c", "#767676", "#faaaaa", "#ee8c8c", "#c97070", "#00fb90", "#00bb00", "#ffff70", "#d0d060", - "#ff6060", "#da0000", "#ae0000", "#0000ff", "#ffffff"], - 'numbar': [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70], - }, - 'HGT': { - 'colors': ["#000000", "#767676", "#00e0ff", "#00b0ff", "#0090cc", "#320096", "#00fb90", "#00bb00", "#00ef00", - "#febf00", "#ffff00", "#ae0000", "#ff0000", "#ffffff"], - 'numbar': [0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 17, 18, 20, 21], - }, - 'CPC': { - 'colors': ["#C9C4BF", "#70BC49", "#F5A36E", "#D07734", "#EA252F", "#C7352F", "#914798", - "#B2B141", "#67C7D0", "#375AA5", "#BBA5CC"], - 'numbar': [0,1,2,3,4,5,6,7,8,9,10,11], - }, -} \ No newline at end of file diff --git a/test2.txt b/test2.txt deleted file mode 100644 index 8645216..0000000 --- a/test2.txt +++ /dev/null @@ -1 +0,0 @@ -dbz: Self { \ No newline at end of file