add exterior

This commit is contained in:
Tsuki 2023-09-20 19:54:38 +08:00
parent ada325c230
commit c048a165f6
14 changed files with 288 additions and 33 deletions

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/radar-g.iml" filepath="$PROJECT_DIR$/.idea/radar-g.iml" />
</modules>
</component>
</project>

11
.idea/radar-g.iml generated Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

117
Cargo.lock generated
View File

@ -72,6 +72,15 @@ dependencies = [
"syn 2.0.29",
]
[[package]]
name = "atomic-polyfill"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
dependencies = [
"critical-section",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -273,6 +282,7 @@ dependencies = [
"cairo-rs",
"epoxy",
"femtovg",
"geo",
"geo-macros",
"geo-types",
"glib",
@ -293,6 +303,7 @@ dependencies = [
"quadtree_rs",
"relm4",
"relm4-components",
"rstar",
"shapefile",
"svg",
"thiserror",
@ -373,6 +384,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "critical-section"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
@ -513,6 +530,16 @@ dependencies = [
"subtle",
]
[[package]]
name = "earcutr"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0812b44697951d35fde8fcb0da81c9de7e809e825a66bbf1ecb79d9829d4ca3d"
dependencies = [
"itertools",
"num-traits",
]
[[package]]
name = "either"
version = "1.8.1"
@ -628,6 +655,12 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "float_next_after"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
[[package]]
name = "flume"
version = "0.10.14"
@ -821,6 +854,22 @@ dependencies = [
"version_check",
]
[[package]]
name = "geo"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1645cf1d7fea7dac1a66f7357f3df2677ada708b8d9db8e9b043878930095a96"
dependencies = [
"earcutr",
"float_next_after",
"geo-types",
"geographiclib-rs",
"log",
"num-traits",
"robust",
"rstar",
]
[[package]]
name = "geo-macros"
version = "0.1.0"
@ -832,15 +881,25 @@ dependencies = [
[[package]]
name = "geo-types"
version = "0.7.10"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1019f6d372c5b53143f08deee4168d05c22920fe5e0f51f0dfb0e8ffb67ec11e"
checksum = "9705398c5c7b26132e74513f4ee7c1d7dafd786004991b375c172be2be0eecaa"
dependencies = [
"approx",
"num-traits",
"rstar",
"serde",
]
[[package]]
name = "geographiclib-rs"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea804e7bd3c6a4ca6a01edfa35231557a8a81d4d3f3e1e2b650d028c42592be"
dependencies = [
"lazy_static",
]
[[package]]
name = "getrandom"
version = "0.2.10"
@ -1127,12 +1186,34 @@ dependencies = [
"crunchy",
]
[[package]]
name = "hash32"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
dependencies = [
"byteorder",
]
[[package]]
name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]]
name = "heapless"
version = "0.7.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
dependencies = [
"atomic-polyfill",
"hash32",
"rustc_version",
"spin",
"stable_deref_trait",
]
[[package]]
name = "heck"
version = "0.4.1"
@ -1219,6 +1300,15 @@ dependencies = [
"generic-array",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "jobserver"
version = "0.1.26"
@ -1997,6 +2087,23 @@ dependencies = [
"bytemuck",
]
[[package]]
name = "robust"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf4a6aa5f6d6888f39e980649f3ad6b666acdce1d78e95b8a2cb076e687ae30"
[[package]]
name = "rstar"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73111312eb7a2287d229f06c00ff35b51ddee180f017ab6dec1f69d62ac098d6"
dependencies = [
"heapless",
"num-traits",
"smallvec",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
@ -2169,6 +2276,12 @@ dependencies = [
"lock_api",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "strsim"
version = "0.7.0"

View File

@ -34,6 +34,8 @@ anyhow = "1.0.72"
proj5 = { version = "0.1.7", features = ["multithreading"] }
relm4 = "0.6.1"
relm4-components = "0.6.1"
rstar = "*"
geo = "0.26.0"

View File

@ -2,6 +2,7 @@ use super::{control_panel::ControlPanelModel, render_panel::RenderPanelModel};
use gtk::{prelude::{
ApplicationExt, ButtonExt, DialogExt, GtkWindowExt, ToggleButtonExt, WidgetExt,
}, traits::OrientableExt};
use gtk::prelude::GtkApplicationExt;
use relm4::*;
#[derive(Debug)]
@ -23,6 +24,9 @@ pub struct AppModel {
control: Controller<ControlPanelModel>,
render: Controller<RenderPanelModel>,
}
relm4::new_action_group!(WindowActionGroup, "win");
relm4::new_stateless_action!(ExampleAction, WindowActionGroup, "example");
relm4::new_stateful_action!(ExampleU8Action, WindowActionGroup, "example2", u8, u8);
#[relm4::component(pub)]
impl SimpleComponent for AppModel {
@ -31,12 +35,13 @@ impl SimpleComponent for AppModel {
type Output = ();
view! {
main_window = gtk::Window {
set_default_width: 1000,
main_window = gtk::ApplicationWindow {
set_default_width: 1200,
set_default_height: 700,
set_focus_on_click:true,
set_titlebar: Some(&gtk::HeaderBar::new()),
gtk::Box{
set_orientation: gtk::Orientation::Vertical,
set_orientation: gtk::Orientation::Horizontal,
set_valign:gtk::Align::Fill,
model.control.widget(),
model.render.widget(),
@ -61,6 +66,42 @@ impl SimpleComponent for AppModel {
.launch(0)
.forward(sender.input_sender(), |a| AppMsg::Close);
relm4::menu! {
main_menu: {
custom: "my_widget",
"Example" => ExampleAction,
"Example2" => ExampleAction,
"Example toggle" => ExampleU8Action(1_u8),
section! {
"Section example" => ExampleAction,
"Example toggle" => ExampleU8Action(1_u8),
},
section! {
"Example" => ExampleAction,
"Example2" => ExampleAction,
"Example Value" => ExampleU8Action(1_u8),
},
"submenu1" {
"Example" => ExampleAction,
"Example2" => ExampleAction,
"Example toggle" => ExampleU8Action(1_u8),
"submenu2" {
"Example" => ExampleAction,
"Example2" => ExampleAction,
"Example toggle" => ExampleU8Action(1_u8),
"submenu3" {
"Example" => ExampleAction,
"Example2" => ExampleAction,
"Example toggle" => ExampleU8Action(1_u8),
}
}
}
}
};
let app = relm4::main_application();
app.set_menubar(Some(&main_menu));
let model = AppModel {
mode: AppMode::View,
control: control,

View File

@ -49,7 +49,7 @@ impl Mapper {
pub fn fore_map(&self, coord: WindowCoord) -> Result<(f64, f64), ProjError> {
let (x, y) = coord;
let c = (x as f64) * (self.bounds.1 - self.bounds.0) + self.bounds.0;
let d = (y as f64) * (self.bounds.3 - self.bounds.2) + self.bounds.2;
let d = ((1.0 - y) as f64) * (self.bounds.3 - self.bounds.2) + self.bounds.2;
let (lon, lat) = self.proj.project((c, d), true)?;
Ok((lon.to_degrees(), lat.to_degrees()))
}
@ -75,7 +75,7 @@ impl Mapper {
let x = (p1 - self.bounds.0) / (self.bounds.1 - self.bounds.0);
let y = (p2 - self.bounds.2) / (self.bounds.3 - self.bounds.2);
Ok((x, y))
Ok((x, (1.0 - y)))
}
pub fn set_lon_range(&mut self, range: std::ops::Range<f64>) -> &mut Self {

View File

@ -8,6 +8,7 @@ use gtk::prelude::*;
use gtk::{gio, glib, Application, ApplicationWindow};
use relm4::RelmApp;
use std::ptr;
use relm4::menu;
mod components;
mod coords;
mod data;
@ -50,8 +51,7 @@ fn main() {
// app.connect_activate(build_ui);
// // Run the application
// app.run()
let relm = RelmApp::new(APP_ID);
let relm = relm4::RelmApp::new(APP_ID);
relm.run::<AppModel>(AppMode::Edit);
}

View File

@ -23,6 +23,9 @@ impl Monitor {
pointer_location_detecture.connect_motion(
clone!(@weak this as s => move |_context, x, y| {
s.imp().renderer.borrow_mut().change_pointer(x as f32, y as f32);
let c = s.imp().renderer.borrow();
let cc = c.imp().config.borrow();
println!("pointer location: {},{}", cc.pointer_lon_lat.0, cc.pointer_lon_lat.1);
}
),
);
@ -43,7 +46,7 @@ impl Monitor {
});
r.set_translate((
px as f32 * (scale - 1.0),
py as f32 * (scale - 1.0)
(1.0-py) as f32 * (scale - 1.0)
));
r.queue_render();
Inhibit(false)

View File

@ -0,0 +1,17 @@
use geo_types::MultiPolygon;
use gtk::glib;
use gtk::subclass::prelude::*;
use std::cell::RefCell;
#[derive(Default)]
pub struct ExteriorWidget {
}
#[glib::object_subclass]
impl ObjectSubclass for ExteriorWidget {
const NAME: &'static str = "ExteriorWidget";
type Type = super::ExteriorWidget;
}
impl ObjectImpl for ExteriorWidget{}

View File

@ -0,0 +1,38 @@
mod imp;
use crate::coords::{Mapper, Range};
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
use geo_types::{line_string, LineString, Point};
use glib::subclass::types::ObjectSubclassIsExt;
use std::cell::Ref;
glib::wrapper! {
pub struct ExteriorWidget(ObjectSubclass<imp::ExteriorWidget>);
}
impl Default for ExteriorWidget {
fn default() -> Self {
Self::new()
}
}
impl ExteriorWidget {
pub fn new() -> Self {
let this: Self = glib::Object::new();
this
}
pub(super) fn draw(&self, canvas: &mut Canvas<OpenGl>, mapper: Ref<'_, Mapper>) {
let imp = self.imp();
let canvas_width = canvas.width();
let canvas_height = canvas.height();
let padding = [30.0,30.0,30.0,30.0];
let w = canvas_width - padding[1] - padding[3];
let h = canvas_height - padding[0] - padding[2];
let paint = Paint::color(Color::white());
let mut path = Path::new();
path.rect(padding[3], padding[0], w, h);
canvas.stroke_path(&path, &paint);
}
}

View File

@ -1,9 +1,10 @@
use super::background::BackgroundWidget;
use super::exterior::ExteriorWidget;
use super::foreground::ForegroundWidget;
use super::WindowCoord;
use crate::coords::proj::Mercator;
use crate::coords::Mapper;
use femtovg::{Color, FontId, Paint, Path};
use femtovg::{Color, FontId, Paint, Path, Transform2D};
use gtk::glib;
use gtk::prelude::WidgetExtManual;
use gtk::subclass::prelude::*;
@ -32,6 +33,7 @@ struct Fonts {
pub struct Render {
pub(super) background: RefCell<BackgroundWidget>,
pub(super) foreground: RefCell<ForegroundWidget>,
pub(super) exterior: RefCell<ExteriorWidget>,
pub config: RefCell<RenderConfig>,
pub mapper: RefCell<Mapper>,
pub(super) canvas: RefCell<Option<femtovg::Canvas<femtovg::renderer::OpenGl>>>,
@ -42,6 +44,7 @@ impl Default for Render {
Self {
background: RefCell::new(BackgroundWidget::default()),
foreground: RefCell::new(ForegroundWidget::default()),
exterior: RefCell::new(ExteriorWidget::default()),
config: RefCell::new(RenderConfig::default()),
mapper: RefCell::new(Mercator::new().into()),
canvas: RefCell::new(None),
@ -94,6 +97,7 @@ impl GLAreaImpl for Render {
let w = canvas.width();
let h = canvas.height();
let configs = self.config.borrow();
canvas.clear_rect(
0,
0,
@ -101,30 +105,32 @@ impl GLAreaImpl for Render {
(h as i32 * dpi) as u32,
Color::rgba(0, 0, 0, 255),
);
let mapper = self.mapper.borrow();
let (lon_range, lat_range) = mapper.range.clone();
{
let background_widget = self.background.borrow_mut();
background_widget.set_lat_lines(lat_range.key_points(9));
}
{
let background_widget = self.background.borrow_mut();
background_widget.set_lon_lines(lon_range.key_points(20));
}
let translate = self.translate();
self.foreground
.borrow()
.draw(canvas, configs.scale, dpi, self.mapper.borrow());
self.background.borrow().draw(
canvas,
configs.scale,
dpi,
translate,
self.mapper.borrow(),
(lon_range, lat_range),
);
let (lon_range, lat_range) = mapper.range.clone();
// {
// let background_widget = self.background.borrow_mut();
// background_widget.set_lat_lines(lat_range.key_points(9));
// }
// {
// let background_widget = self.background.borrow_mut();
// background_widget.set_lon_lines(lon_range.key_points(20));
// }
let translate = self.translate();
self.exterior.borrow().draw(canvas,self.mapper.borrow());
// self.foreground
// .borrow()
// .draw(canvas, configs.scale, dpi, self.mapper.borrow());
// self.background.borrow().draw(
// canvas,
// configs.scale,
// dpi,
// translate,
// self.mapper.borrow(),
// (lon_range, lat_range),
// );
canvas.flush();
true
}

View File

@ -1,5 +1,6 @@
mod background;
mod foreground;
mod exterior;
mod imp;
use crate::coords::Mapper;
use crate::data::{MultiDimensionData, RadarData2d};
@ -8,6 +9,7 @@ use crate::pipeline::{Pipeline, ShadePipe};
use std::fmt::Debug;
pub use self::background::{BackgroundConfig, BackgroundWidget};
use self::exterior::ExteriorWidget;
pub use self::foreground::{ForegroundConfig, ForegroundWidget};
use self::imp::RenderConfig;
use crate::data::DownSampleMeth;