add renderer
This commit is contained in:
parent
42e001d00d
commit
9a929b3493
@ -1,3 +1,5 @@
|
|||||||
|
use crate::render::WindowCoord;
|
||||||
|
|
||||||
use super::{proj::ProjectionS, Range};
|
use super::{proj::ProjectionS, Range};
|
||||||
use geo_types::{coord, Coord as GCoord, LineString};
|
use geo_types::{coord, Coord as GCoord, LineString};
|
||||||
use proj::{Proj, ProjError};
|
use proj::{Proj, ProjError};
|
||||||
@ -7,6 +9,9 @@ pub struct Mapper {
|
|||||||
proj: Proj,
|
proj: Proj,
|
||||||
pub range: (Range, Range),
|
pub range: (Range, Range),
|
||||||
bounds: (f64, f64, f64, f64),
|
bounds: (f64, f64, f64, f64),
|
||||||
|
scale: f32,
|
||||||
|
translate: (f32, f32),
|
||||||
|
focus_point: Option<(f64, f64)>,
|
||||||
}
|
}
|
||||||
impl From<Proj> for Mapper {
|
impl From<Proj> for Mapper {
|
||||||
fn from(proj: Proj) -> Self {
|
fn from(proj: Proj) -> Self {
|
||||||
@ -16,6 +21,9 @@ impl From<Proj> for Mapper {
|
|||||||
proj: proj,
|
proj: proj,
|
||||||
range: (default_range.0.into(), default_range.1.into()),
|
range: (default_range.0.into(), default_range.1.into()),
|
||||||
bounds,
|
bounds,
|
||||||
|
scale: 1.0,
|
||||||
|
translate: (0.0, 0.0),
|
||||||
|
focus_point: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,34 +40,92 @@ impl Mapper {
|
|||||||
proj: Proj,
|
proj: Proj,
|
||||||
lon_range: std::ops::Range<f64>,
|
lon_range: std::ops::Range<f64>,
|
||||||
lat_range: std::ops::Range<f64>,
|
lat_range: std::ops::Range<f64>,
|
||||||
|
scale: f32,
|
||||||
|
translate: (f32, f32),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let bounds = Self::bound(&proj, (lon_range.clone().into(), lat_range.clone().into())).unwrap();
|
let bounds =
|
||||||
|
Self::bound(&proj, (lon_range.clone().into(), lat_range.clone().into())).unwrap();
|
||||||
let range = (lon_range.into(), lat_range.into());
|
let range = (lon_range.into(), lat_range.into());
|
||||||
Self {
|
Self {
|
||||||
proj: proj,
|
proj: proj,
|
||||||
range,
|
range,
|
||||||
bounds,
|
bounds,
|
||||||
|
scale,
|
||||||
|
translate,
|
||||||
|
focus_point: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fore_map(&self, coord: WindowCoord) -> Result<(f64, f64), ProjError> {
|
||||||
|
let (t1, t2) = if let Some(_) = self.focus_point {
|
||||||
|
let (a, b) = self.translate;
|
||||||
|
(a * (self.scale - 1.0), b * (self.scale - 1.0))
|
||||||
|
} else {
|
||||||
|
self.translate
|
||||||
|
};
|
||||||
|
let (x, y) = coord;
|
||||||
|
let c = (x as f64 + t1 as f64) / self.scale as f64 * (self.bounds.1 - self.bounds.0)
|
||||||
|
+ self.bounds.0;
|
||||||
|
let d = (y as f64 + t2 as f64) / self.scale 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()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_scale(&mut self, scale: f32) {
|
||||||
|
self.scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_translate(&mut self, translate: (f32, f32)) {
|
||||||
|
self.translate = translate;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_focus_point(&mut self, point: (f64, f64)) {
|
||||||
|
self.focus_point = Some(point);
|
||||||
|
let (rx, ry) = self.map(point).unwrap();
|
||||||
|
self.translate = (rx as f32, ry as f32);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn point_in_bound(&self, point: (f64, f64)) -> bool {
|
||||||
|
let (x, y) = point;
|
||||||
|
let (lon_range, lat_range) = self.range;
|
||||||
|
return (x <= lon_range.1 && x >= lon_range.0) && (y <= lat_range.1 && y >= lat_range.0);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn map(&self, point: (f64, f64)) -> Result<(f64, f64), ProjError> {
|
pub fn map(&self, point: (f64, f64)) -> Result<(f64, f64), ProjError> {
|
||||||
|
let mut point = point;
|
||||||
|
if !self.point_in_bound(point) {
|
||||||
|
point = (
|
||||||
|
point.0.clamp(self.range.0 .0, self.range.0 .1),
|
||||||
|
point.1.clamp(self.range.1 .0, self.range.1 .1),
|
||||||
|
);
|
||||||
|
}
|
||||||
let (p1, p2) = self
|
let (p1, p2) = self
|
||||||
.proj
|
.proj
|
||||||
.convert((point.0.to_radians(), point.1.to_radians()))?;
|
.convert((point.0.to_radians(), point.1.to_radians()))?;
|
||||||
|
|
||||||
let x = (p1 - self.bounds.0) / (self.bounds.1 - self.bounds.0);
|
let (t1, t2) = if let Some(_) = self.focus_point {
|
||||||
let y = (p2 - self.bounds.2) / (self.bounds.3 - self.bounds.2);
|
let (a, b) = self.translate;
|
||||||
|
(a * (self.scale - 1.0), b * (self.scale - 1.0))
|
||||||
|
} else {
|
||||||
|
self.translate
|
||||||
|
};
|
||||||
|
|
||||||
|
let x = (p1 - self.bounds.0) / (self.bounds.1 - self.bounds.0) * self.scale as f64
|
||||||
|
- t1 as f64 * self.scale as f64;
|
||||||
|
let y = (p2 - self.bounds.2) / (self.bounds.3 - self.bounds.2) * self.scale as f64
|
||||||
|
- t2 as f64 * self.scale as f64;
|
||||||
|
|
||||||
Ok((x, y))
|
Ok((x, y))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_lon_range(&mut self, range: std::ops::Range<f64>)->&mut Self {
|
pub fn set_lon_range(&mut self, range: std::ops::Range<f64>) -> &mut Self {
|
||||||
self.range.0 = range.into();
|
self.range.0 = range.into();
|
||||||
self.bounds = Self::bound(&self.proj, self.range.clone()).unwrap();
|
self.bounds = Self::bound(&self.proj, self.range.clone()).unwrap();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_lat_range(&mut self, range: std::ops::Range<f64>)->&mut Self {
|
pub fn set_lat_range(&mut self, range: std::ops::Range<f64>) -> &mut Self {
|
||||||
self.range.1 = range.into();
|
self.range.1 = range.into();
|
||||||
self.bounds = Self::bound(&self.proj, self.range.clone()).unwrap();
|
self.bounds = Self::bound(&self.proj, self.range.clone()).unwrap();
|
||||||
self
|
self
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
mod imp;
|
mod imp;
|
||||||
use crate::data::RadarData2d;
|
use crate::data::RadarData2d;
|
||||||
use crate::render::Render;
|
use crate::render::Render;
|
||||||
|
use adw::prelude::{GLAreaExt, GestureDragExt};
|
||||||
use glib::clone;
|
use glib::clone;
|
||||||
use glib::subclass::prelude::*;
|
use glib::subclass::prelude::*;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
use gtk::traits::WidgetExt;
|
use gtk::traits::WidgetExt;
|
||||||
use gtk::{EventControllerScrollFlags, Inhibit};
|
use gtk::{EventControllerScrollFlags, Inhibit};
|
||||||
use num_traits::{AsPrimitive, FromPrimitive, Num};
|
use num_traits::{AsPrimitive, FromPrimitive, Num};
|
||||||
use proj::{Proj, ProjError};
|
use proj::ProjError;
|
||||||
use std::borrow::Borrow;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
glib::wrapper! {
|
glib::wrapper! {
|
||||||
@ -22,32 +22,50 @@ impl Monitor {
|
|||||||
let pointer_location_detecture = gtk::EventControllerMotion::new();
|
let pointer_location_detecture = gtk::EventControllerMotion::new();
|
||||||
pointer_location_detecture.connect_motion(
|
pointer_location_detecture.connect_motion(
|
||||||
clone!(@weak this as s => move |_context, x, y| {
|
clone!(@weak this as s => move |_context, x, y| {
|
||||||
s.imp().renderer.borrow().change_cfg(
|
s.imp().renderer.borrow_mut().change_pointer(x as f32, y as f32);
|
||||||
|cfg| cfg.pointer_location = (x as f32, y as f32)
|
}
|
||||||
);
|
),
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let scale_detecture = gtk::EventControllerScroll::new(EventControllerScrollFlags::VERTICAL);
|
let scale_detecture = gtk::EventControllerScroll::new(EventControllerScrollFlags::VERTICAL);
|
||||||
|
|
||||||
scale_detecture.connect_scroll(clone!(
|
scale_detecture.connect_scroll(clone!(
|
||||||
@weak this as s => @default-panic,move |_context, _x, y| {
|
@weak this as s, @weak render as r => @default-panic,move |_context, _x, y| {
|
||||||
let renderer = s.imp().borrow().renderer.borrow();
|
let renderer = s.imp().renderer.borrow();
|
||||||
renderer.change_cfg(|cfg| {
|
renderer.change_cfg(|cfg| {
|
||||||
let current_scale = cfg.scale;
|
let current_scale = cfg.scale;
|
||||||
cfg.scale = (current_scale + y as f32 / 100.0).max(1.0).min(5.0);
|
let scale = (current_scale - y as f32 / 10.0).max(1.0).min(5.0);
|
||||||
|
cfg.scale = scale;
|
||||||
|
r.imp().mapper.borrow_mut().set_scale(scale);
|
||||||
});
|
});
|
||||||
|
r.calc_translate();
|
||||||
Inhibit(false)
|
Inhibit(false)
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let drag_detecture = gtk::GestureDrag::new();
|
||||||
|
drag_detecture.connect_drag_update(clone!(
|
||||||
|
@weak render as r => move |this, _, _| {
|
||||||
|
let (ox, oy) = this.offset().unwrap_or((0.0,0.0));
|
||||||
|
r.change_cfg(|cfg|{
|
||||||
|
cfg.updated_translate = ( - ox as f32, -oy as f32);
|
||||||
|
} );
|
||||||
|
}));
|
||||||
|
drag_detecture.connect_drag_end(clone!(
|
||||||
|
@weak render as r => move |this,_,_|{
|
||||||
|
let t = r.imp().translate();
|
||||||
|
r.change_cfg(|cfg| {
|
||||||
|
cfg.translate = t ;
|
||||||
|
cfg.updated_translate = (0.0,0.0);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
render.add_controller(pointer_location_detecture);
|
render.add_controller(pointer_location_detecture);
|
||||||
render.add_controller(scale_detecture);
|
render.add_controller(scale_detecture);
|
||||||
|
render.add_controller(drag_detecture);
|
||||||
render.set_hexpand(true);
|
render.set_hexpand(true);
|
||||||
render.set_vexpand(true);
|
render.set_vexpand(true);
|
||||||
render.set_parent(&this);
|
render.set_parent(&this);
|
||||||
this.imp().renderer.replace(render);
|
this.imp().renderer.replace(render);
|
||||||
|
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::render::{imp, WindowCoord};
|
use crate::render::{imp, WindowCoord};
|
||||||
use femtovg::Paint;
|
use femtovg::Paint;
|
||||||
use geo_macros::Prj;
|
use geo_macros::Prj;
|
||||||
|
use geo_types::MultiPolygon;
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -23,6 +24,7 @@ impl BackgroundConfig {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct BackgroundWidget {
|
pub struct BackgroundWidget {
|
||||||
pub(super) config: RefCell<BackgroundConfig>,
|
pub(super) config: RefCell<BackgroundConfig>,
|
||||||
|
pub(super) shp: RefCell<Option<Vec<MultiPolygon>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::coords::{Mapper, Range};
|
|||||||
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
|
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
|
||||||
use geo_types::{line_string, LineString, Point};
|
use geo_types::{line_string, LineString, Point};
|
||||||
use glib::subclass::types::ObjectSubclassIsExt;
|
use glib::subclass::types::ObjectSubclassIsExt;
|
||||||
|
use shapefile;
|
||||||
use std::cell::Ref;
|
use std::cell::Ref;
|
||||||
|
|
||||||
pub use self::imp::BackgroundConfig;
|
pub use self::imp::BackgroundConfig;
|
||||||
@ -21,6 +22,17 @@ impl BackgroundWidget {
|
|||||||
pub fn new(config: BackgroundConfig) -> Self {
|
pub fn new(config: BackgroundConfig) -> Self {
|
||||||
let this: Self = glib::Object::new();
|
let this: Self = glib::Object::new();
|
||||||
let imp = this.imp();
|
let imp = this.imp();
|
||||||
|
let polygons = shapefile::read_as::<_, shapefile::Polygon, shapefile::dbase::Record>(
|
||||||
|
"/Users/tsuki/Downloads/ne_110m_admin_0_countries/ne_110m_admin_0_countries.shp",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let polys: Vec<geo_types::MultiPolygon<f64>> = polygons
|
||||||
|
.into_iter()
|
||||||
|
.map(|(polygon, _)| polygon.into())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
imp.shp.replace(Some(polys));
|
||||||
imp.config.replace(config);
|
imp.config.replace(config);
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
@ -45,9 +57,11 @@ impl BackgroundWidget {
|
|||||||
fn mesh_lines(
|
fn mesh_lines(
|
||||||
&self,
|
&self,
|
||||||
canvas: &mut Canvas<OpenGl>,
|
canvas: &mut Canvas<OpenGl>,
|
||||||
|
scale: f32,
|
||||||
|
translate: (f32, f32),
|
||||||
canvas_width: f32,
|
canvas_width: f32,
|
||||||
canvas_height: f32,
|
canvas_height: f32,
|
||||||
mapper: Ref<'_, Mapper>,
|
mapper: &Ref<'_, Mapper>,
|
||||||
bound: (Range, Range),
|
bound: (Range, Range),
|
||||||
) {
|
) {
|
||||||
let imp = self.imp();
|
let imp = self.imp();
|
||||||
@ -63,7 +77,13 @@ impl BackgroundWidget {
|
|||||||
LineString::new(
|
LineString::new(
|
||||||
result
|
result
|
||||||
.points()
|
.points()
|
||||||
.map(|p| (p.x() as f32 * canvas_width, p.y() as f32 * canvas_height).into())
|
.map(|p| {
|
||||||
|
(
|
||||||
|
p.x() as f32 * canvas_width - translate.0,
|
||||||
|
(1.0 - p.y() as f32) * canvas_height - translate.1,
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@ -76,14 +96,16 @@ impl BackgroundWidget {
|
|||||||
let mut paint = Paint::color(Color::white());
|
let mut paint = Paint::color(Color::white());
|
||||||
paint.set_font_size(25.0);
|
paint.set_font_size(25.0);
|
||||||
paint.set_line_width(1.0);
|
paint.set_line_width(1.0);
|
||||||
let text_location = mapper.map((left, *lat)).unwrap();
|
let (x, y) = self.map_to_screen(
|
||||||
|
mapper,
|
||||||
let _ = canvas.stroke_text(
|
scale,
|
||||||
text_location.0 as f32 * canvas_width,
|
translate,
|
||||||
text_location.1 as f32 * canvas_height,
|
canvas_height,
|
||||||
format!("{:.2} N", lat),
|
canvas_width,
|
||||||
&paint,
|
(left, *lat),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let _ = canvas.stroke_text(x, y, format!("{:.2} N", lat), &paint);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,14 +114,15 @@ impl BackgroundWidget {
|
|||||||
let mut paint = Paint::color(Color::white());
|
let mut paint = Paint::color(Color::white());
|
||||||
paint.set_font_size(25.0);
|
paint.set_font_size(25.0);
|
||||||
paint.set_line_width(1.0);
|
paint.set_line_width(1.0);
|
||||||
let text_location = mapper.map((*lon, top + 0.1)).unwrap();
|
let (x, y) = self.map_to_screen(
|
||||||
|
mapper,
|
||||||
let _ = canvas.stroke_text(
|
scale,
|
||||||
text_location.0 as f32 * canvas_width,
|
translate,
|
||||||
text_location.1 as f32 * canvas_height,
|
canvas_height,
|
||||||
format!("{:.2}", lon),
|
canvas_width,
|
||||||
&paint,
|
(*lon + 0.5, bottom + 0.1),
|
||||||
);
|
);
|
||||||
|
let _ = canvas.stroke_text(x, y, format!("{:.2}", lon), &paint);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +133,13 @@ impl BackgroundWidget {
|
|||||||
LineString::new(
|
LineString::new(
|
||||||
result
|
result
|
||||||
.points()
|
.points()
|
||||||
.map(|p| (p.x() as f32 * canvas_width, p.y() as f32 * canvas_height).into())
|
.map(|p| {
|
||||||
|
(
|
||||||
|
p.x() as f32 * canvas_width - translate.0,
|
||||||
|
(1.0 - p.y()) as f32 * canvas_height - translate.1,
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@ -124,25 +153,100 @@ impl BackgroundWidget {
|
|||||||
canvas: &mut Canvas<OpenGl>,
|
canvas: &mut Canvas<OpenGl>,
|
||||||
scale: f32,
|
scale: f32,
|
||||||
dpi: i32,
|
dpi: i32,
|
||||||
|
translate: (f32, f32),
|
||||||
mapper: Ref<'_, Mapper>,
|
mapper: Ref<'_, Mapper>,
|
||||||
bound: (Range, Range),
|
bound: (Range, Range),
|
||||||
) {
|
) {
|
||||||
let canvas_width = canvas.width();
|
let canvas_width = canvas.width();
|
||||||
let canvas_height = canvas.height();
|
let canvas_height = canvas.height();
|
||||||
|
|
||||||
let config = self.imp().config.borrow();
|
let config = self.imp().config.borrow();
|
||||||
|
self.mesh_lines(
|
||||||
|
canvas,
|
||||||
|
scale,
|
||||||
|
translate,
|
||||||
|
canvas_width,
|
||||||
|
canvas_height,
|
||||||
|
&mapper,
|
||||||
|
bound,
|
||||||
|
);
|
||||||
|
self.shp(
|
||||||
|
mapper,
|
||||||
|
canvas,
|
||||||
|
translate,
|
||||||
|
scale,
|
||||||
|
canvas_width,
|
||||||
|
canvas_height,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.mesh_lines(canvas, canvas_width, canvas_height, mapper, bound);
|
fn shp(
|
||||||
|
&self,
|
||||||
|
mapper: Ref<'_, Mapper>,
|
||||||
|
canvas: &mut Canvas<OpenGl>,
|
||||||
|
translate: (f32, f32),
|
||||||
|
scale: f32,
|
||||||
|
canvas_width: f32,
|
||||||
|
canvas_height: f32,
|
||||||
|
) {
|
||||||
|
if let Some(s) = self.imp().shp.borrow().as_ref() {
|
||||||
|
for p in s.iter() {
|
||||||
|
for poly in p.iter() {
|
||||||
|
let mut points = poly.exterior().points();
|
||||||
|
let first_point = points.next().unwrap();
|
||||||
|
let mut path = Path::new();
|
||||||
|
|
||||||
|
let first = self.map_to_screen(
|
||||||
|
&mapper,
|
||||||
|
scale,
|
||||||
|
translate,
|
||||||
|
canvas_height,
|
||||||
|
canvas_width,
|
||||||
|
(first_point.x(), first_point.y()),
|
||||||
|
);
|
||||||
|
|
||||||
|
path.move_to(first.0, first.1);
|
||||||
|
|
||||||
|
for p in points {
|
||||||
|
let (nx, ny) = self.map_to_screen(
|
||||||
|
&mapper,
|
||||||
|
scale,
|
||||||
|
translate,
|
||||||
|
canvas_height,
|
||||||
|
canvas_width,
|
||||||
|
(p.x(), p.y()),
|
||||||
|
);
|
||||||
|
path.line_to(nx, ny);
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.stroke_path(&path, &Paint::color(Color::white()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn map_to_screen(
|
||||||
|
&self,
|
||||||
|
mapper: &Ref<'_, Mapper>,
|
||||||
|
scale: f32,
|
||||||
|
translate: (f32, f32),
|
||||||
|
canvas_height: f32,
|
||||||
|
canvas_width: f32,
|
||||||
|
point: (f64, f64),
|
||||||
|
) -> (f32, f32) {
|
||||||
|
let (x, y) = mapper.map(point).unwrap();
|
||||||
|
(
|
||||||
|
x as f32 * canvas_width - translate.0,
|
||||||
|
(1.0 - y as f32) * canvas_height - translate.1,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_lat_lines(&self, lat_lines: Vec<f64>) {
|
pub fn set_lat_lines(&self, lat_lines: Vec<f64>) {
|
||||||
println!("set lat lines {:?}", lat_lines);
|
|
||||||
let imp = self.imp();
|
let imp = self.imp();
|
||||||
imp.config.borrow_mut().lat_lines = lat_lines;
|
imp.config.borrow_mut().lat_lines = lat_lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_lon_lines(&self, lon_lines: Vec<f64>) {
|
pub fn set_lon_lines(&self, lon_lines: Vec<f64>) {
|
||||||
println!("set lon lines {:?}", lon_lines);
|
|
||||||
let imp = self.imp();
|
let imp = self.imp();
|
||||||
imp.config.borrow_mut().lon_lines = lon_lines;
|
imp.config.borrow_mut().lon_lines = lon_lines;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,9 @@ use super::foreground::ForegroundWidget;
|
|||||||
use super::WindowCoord;
|
use super::WindowCoord;
|
||||||
use crate::coords::proj::Mercator;
|
use crate::coords::proj::Mercator;
|
||||||
use crate::coords::Mapper;
|
use crate::coords::Mapper;
|
||||||
use femtovg::{Color, Paint, Path, FontId};
|
use femtovg::{Color, FontId, Paint, Path};
|
||||||
use gtk::glib;
|
use gtk::glib;
|
||||||
|
use gtk::prelude::WidgetExtManual;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use gtk::traits::{GLAreaExt, WidgetExt};
|
use gtk::traits::{GLAreaExt, WidgetExt};
|
||||||
use ndarray::Array2;
|
use ndarray::Array2;
|
||||||
@ -17,7 +18,9 @@ pub struct RenderConfig {
|
|||||||
pub dim2: Option<Array2<f64>>,
|
pub dim2: Option<Array2<f64>>,
|
||||||
pub scale: f32,
|
pub scale: f32,
|
||||||
pub pointer_location: WindowCoord,
|
pub pointer_location: WindowCoord,
|
||||||
pub transform: WindowCoord,
|
pub pointer_lon_lat: (f64, f64),
|
||||||
|
pub translate: WindowCoord,
|
||||||
|
pub updated_translate: WindowCoord,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Fonts {
|
struct Fonts {
|
||||||
@ -31,9 +34,7 @@ pub struct Render {
|
|||||||
pub(super) foreground: RefCell<ForegroundWidget>,
|
pub(super) foreground: RefCell<ForegroundWidget>,
|
||||||
pub config: RefCell<RenderConfig>,
|
pub config: RefCell<RenderConfig>,
|
||||||
pub mapper: RefCell<Mapper>,
|
pub mapper: RefCell<Mapper>,
|
||||||
canvas: RefCell<Option<femtovg::Canvas<femtovg::renderer::OpenGl>>>,
|
pub(super) canvas: RefCell<Option<femtovg::Canvas<femtovg::renderer::OpenGl>>>,
|
||||||
canvas_width: RefCell<f32>,
|
|
||||||
canvas_height: RefCell<f32>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Render {
|
impl Default for Render {
|
||||||
@ -44,8 +45,6 @@ impl Default for Render {
|
|||||||
config: RefCell::new(RenderConfig::default()),
|
config: RefCell::new(RenderConfig::default()),
|
||||||
mapper: RefCell::new(Mercator::new().into()),
|
mapper: RefCell::new(Mercator::new().into()),
|
||||||
canvas: RefCell::new(None),
|
canvas: RefCell::new(None),
|
||||||
canvas_height: RefCell::new(0.0),
|
|
||||||
canvas_width: RefCell::new(0.0),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,6 +62,11 @@ impl ObjectImpl for Render {
|
|||||||
self.parent_constructed();
|
self.parent_constructed();
|
||||||
let area = self.obj();
|
let area = self.obj();
|
||||||
area.set_has_stencil_buffer(true);
|
area.set_has_stencil_buffer(true);
|
||||||
|
|
||||||
|
area.add_tick_callback(|area, _| {
|
||||||
|
area.queue_render();
|
||||||
|
glib::Continue(true)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +94,6 @@ impl GLAreaImpl for Render {
|
|||||||
let w = canvas.width();
|
let w = canvas.width();
|
||||||
let h = canvas.height();
|
let h = canvas.height();
|
||||||
let configs = self.config.borrow();
|
let configs = self.config.borrow();
|
||||||
|
|
||||||
canvas.clear_rect(
|
canvas.clear_rect(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -101,7 +104,6 @@ impl GLAreaImpl for Render {
|
|||||||
|
|
||||||
let mapper = self.mapper.borrow();
|
let mapper = self.mapper.borrow();
|
||||||
let (lon_range, lat_range) = mapper.range.clone();
|
let (lon_range, lat_range) = mapper.range.clone();
|
||||||
|
|
||||||
{
|
{
|
||||||
let background_widget = self.background.borrow_mut();
|
let background_widget = self.background.borrow_mut();
|
||||||
background_widget.set_lat_lines(lat_range.key_points(9));
|
background_widget.set_lat_lines(lat_range.key_points(9));
|
||||||
@ -110,7 +112,7 @@ impl GLAreaImpl for Render {
|
|||||||
let background_widget = self.background.borrow_mut();
|
let background_widget = self.background.borrow_mut();
|
||||||
background_widget.set_lon_lines(lon_range.key_points(20));
|
background_widget.set_lon_lines(lon_range.key_points(20));
|
||||||
}
|
}
|
||||||
|
let translate = self.translate();
|
||||||
self.foreground
|
self.foreground
|
||||||
.borrow()
|
.borrow()
|
||||||
.draw(canvas, configs.scale, dpi, self.mapper.borrow());
|
.draw(canvas, configs.scale, dpi, self.mapper.borrow());
|
||||||
@ -119,12 +121,11 @@ impl GLAreaImpl for Render {
|
|||||||
canvas,
|
canvas,
|
||||||
configs.scale,
|
configs.scale,
|
||||||
dpi,
|
dpi,
|
||||||
|
translate,
|
||||||
self.mapper.borrow(),
|
self.mapper.borrow(),
|
||||||
(lon_range, lat_range),
|
(lon_range, lat_range),
|
||||||
);
|
);
|
||||||
|
|
||||||
canvas.flush();
|
canvas.flush();
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,7 +158,17 @@ impl Render {
|
|||||||
};
|
};
|
||||||
renderer.set_screen_target(Some(fbo));
|
renderer.set_screen_target(Some(fbo));
|
||||||
let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
|
let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
|
||||||
canvas.add_font_dir("/Users/tsuki/projects/radar-g/src/assets").unwrap();
|
canvas
|
||||||
|
.add_font_dir("/Users/tsuki/projects/radar-g/src/assets")
|
||||||
|
.unwrap();
|
||||||
self.canvas.replace(Some(canvas));
|
self.canvas.replace(Some(canvas));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn translate(&self) -> WindowCoord {
|
||||||
|
let cfg = self.config.borrow();
|
||||||
|
let (rx, ry) = cfg.translate;
|
||||||
|
let (ux, uy) = cfg.updated_translate;
|
||||||
|
|
||||||
|
return (rx + ux, ry + uy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ pub use self::background::{BackgroundConfig, BackgroundWidget};
|
|||||||
pub use self::foreground::{ForegroundConfig, ForegroundWidget};
|
pub use self::foreground::{ForegroundConfig, ForegroundWidget};
|
||||||
use self::imp::RenderConfig;
|
use self::imp::RenderConfig;
|
||||||
use crate::data::DownSampleMeth;
|
use crate::data::DownSampleMeth;
|
||||||
|
use adw::prelude::WidgetExt;
|
||||||
use femtovg::Color;
|
use femtovg::Color;
|
||||||
pub use glib::subclass::prelude::*;
|
pub use glib::subclass::prelude::*;
|
||||||
use image::RgbImage;
|
use image::RgbImage;
|
||||||
@ -27,12 +28,20 @@ glib::wrapper! {
|
|||||||
|
|
||||||
impl Default for Render {
|
impl Default for Render {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(BackgroundWidget::default(), ForegroundWidget::default(),None)
|
Self::new(
|
||||||
|
BackgroundWidget::default(),
|
||||||
|
ForegroundWidget::default(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render {
|
impl Render {
|
||||||
pub fn new(background: BackgroundWidget, foreground: ForegroundWidget,mapper: Option<Mapper>) -> Self {
|
pub fn new(
|
||||||
|
background: BackgroundWidget,
|
||||||
|
foreground: ForegroundWidget,
|
||||||
|
mapper: Option<Mapper>,
|
||||||
|
) -> Self {
|
||||||
let this: Self = glib::Object::new();
|
let this: Self = glib::Object::new();
|
||||||
this.imp().background.replace(background);
|
this.imp().background.replace(background);
|
||||||
this.imp().foreground.replace(foreground);
|
this.imp().foreground.replace(foreground);
|
||||||
@ -54,6 +63,41 @@ impl Render {
|
|||||||
f(&mut cfg);
|
f(&mut cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn change_pointer(&mut self, x: f32, y: f32) {
|
||||||
|
if let Some(canvas) = self.imp().canvas.borrow().as_ref() {
|
||||||
|
let dpi = self.scale_factor();
|
||||||
|
let cw = canvas.width();
|
||||||
|
let ch = canvas.height();
|
||||||
|
let (tx, ty) = self.imp().translate();
|
||||||
|
println!("tx,ty: {:?}", (tx, ty));
|
||||||
|
println!("x :{} , y: {}, x + tx :{}", x, y, x + tx);
|
||||||
|
let (lon, lat) = self
|
||||||
|
.imp()
|
||||||
|
.mapper
|
||||||
|
.borrow()
|
||||||
|
.fore_map((
|
||||||
|
(x * dpi as f32+ tx) / cw,
|
||||||
|
(1.0 - (y * dpi as f32+ ty) / ch ),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
println!("lon,lat : {:?}", (lon, lat));
|
||||||
|
let mut cfg = self.imp().config.borrow_mut();
|
||||||
|
cfg.pointer_lon_lat = (lon, lat);
|
||||||
|
cfg.pointer_location = (x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calc_translate(&self) {
|
||||||
|
let ll = self.imp().config.borrow().pointer_lon_lat;
|
||||||
|
let scale = self.imp().config.borrow().scale;
|
||||||
|
let (rx, ry) = self.imp().mapper.borrow().map((ll.0, ll.1)).unwrap();
|
||||||
|
|
||||||
|
self.imp()
|
||||||
|
.mapper
|
||||||
|
.borrow_mut()
|
||||||
|
.set_translate((rx as f32 * (scale - 1.0), ry as f32 * (scale - 1.0)));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_mapper(&self, mapper: Mapper) {
|
pub fn set_mapper(&self, mapper: Mapper) {
|
||||||
self.imp().mapper.replace(mapper);
|
self.imp().mapper.replace(mapper);
|
||||||
}
|
}
|
||||||
@ -104,8 +148,8 @@ impl Render {
|
|||||||
|
|
||||||
let rainbow = pjp.run(&data).unwrap();
|
let rainbow = pjp.run(&data).unwrap();
|
||||||
self.imp().foreground.borrow_mut().set_data(rainbow);
|
self.imp().foreground.borrow_mut().set_data(rainbow);
|
||||||
let pbow:Array2<Option<Color>> = rrp.run(&data).unwrap();
|
let pbow: Array2<Option<Color>> = rrp.run(&data).unwrap();
|
||||||
self.imp().foreground.borrow_mut().set_colors(pbow);
|
self.imp().foreground.borrow_mut().set_colors(pbow);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user