This commit is contained in:
tsuki 2024-03-12 00:16:01 +08:00
parent b21529c2b9
commit b6537055ba
5 changed files with 100 additions and 24 deletions

View File

@ -15,12 +15,14 @@ pub enum MonitorInputMsg {
UpdateMetaItem(HashMap<String, String>),
RefreshLayerList,
SetRenderRange(f64, f64, f64, f64),
ChangeZoom(u8),
None,
}
impl Debug for MonitorInputMsg {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MonitorInputMsg::ChangeZoom(_) => write!(f, "MonitorInputMsg::ChangeZoom"),
MonitorInputMsg::SetRenderRange(_, _, _, _) => write!(f, "MonitorInputMsg::SetRenderRange"),
MonitorInputMsg::RefreshLayerList => write!(f, "MonitorInputMsg::RefreshLayerList"),
MonitorInputMsg::NewElement(_) => write!(f, "MonitorInputMsg::NewElement"),

View File

@ -1,3 +1,4 @@
use tracing::*;
use super::messages::{MonitorInputMsg, MonitorOutputMsg};
use crate::coords::cms::CMS;
use crate::pipeline::offscreen_renderer::OffscreenRenderer;
@ -18,16 +19,17 @@ use std::collections::HashMap;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use tokio::task;
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 adw::prelude::*;
use femtovg::ImageId;
use relm4::{component::Component, *};
use slippy_map_tiles::Tile;
use tokio::task;
use tracing::instrument::WithSubscriber;
use crate::coords::Range;
use crate::pipeline::element::Target;
#[derive(Debug)]
pub enum MonitorCommand {
@ -40,10 +42,11 @@ pub struct MonitorModel {
render_range: (f64, f64, f64, f64),
sidebar_open: bool,
sidebar_width: i32,
zoom: u8,
#[do_not_track]
map_tile_getter: Arc<MapTile>,
#[do_not_track]
tiles: Rc<RefCell<HashMap<Tile, Target>>>,
tiles: Rc<RefCell<HashMap<Tile, Option<Target>>>>,
new_layer: i8,
#[no_eq]
widgets: Vec<WidgetFrame>,
@ -99,14 +102,13 @@ impl Component for MonitorModel {
},
set_tiles: model.tiles.clone(),
connect_range_changing_notify[sender] => move |r| {
let ((x1 , x2), (y1,y2))= r.render_range();
let w = r.width() as f32;
let h = r.height() as f32;
let map_tile_getter = map_tile_getter.clone();
let new_tiles = map_tile_getter.new_tiles(3 ,(y1 as f32,y2 as f32),(x1 as f32,x2 as f32));
let tiles = (*tiles).borrow();
let ((x1 , x2), (y1,y2))= r.render_range();
let new_tiles = map_tile_getter.new_tiles(model.zoom ,(y1 as f32, y2 as f32),(x1 as f32,x2 as f32));
let mut tiles = (*tiles).borrow_mut();
let new_tiles = new_tiles.filter(|x| !tiles.contains_key(x)).collect::<Vec<_>>();
tiles.extend(new_tiles.iter().map(|x| (*x, None)));
if new_tiles.len() > 0 {
let new_sender = sender.clone();
@ -115,6 +117,7 @@ impl Component for MonitorModel {
let map_tile_getter = map_tile_getter.clone();
let sender = new_sender.clone();
task::spawn(async move {
info!("Loading tile {:?}", tile);
let result = map_tile_getter.get_tile(&tile).await;
if let Ok(result) = result {
let origin = tile.nw_corner();
@ -122,12 +125,19 @@ impl Component for MonitorModel {
let bounds = ((origin.lon() as f64..rb.lon() as f64).into(), (origin.lat() as f64..rb.lat() as f64).into());
sender.command_sender().emit(MonitorCommand::LoadTile(tile, result,(origin.lon() as f64, origin.lat() as f64), bounds));
}
});
}).await;
}
MonitorCommand::None
});
}
},
connect_scale_notify[sender] => move |r| {
// let ((x1 , x2), (y1,y2))= r.render_range();
// let w = r.width() as f32;
// let h = r.height() as f32;
// let zoom = lat_lon_to_zoom((y1,y2), (x1,x2),w, h);
// sender.input(MonitorInputMsg::ChangeZoom(zoom));
},
set_interior_layers: model.layers.clone(),
},
add_overlay=&gtk::Button{
@ -158,7 +168,6 @@ impl Component for MonitorModel {
) {
self.reset();
match message {
MonitorInputMsg::RefreshLayerList => {
self.sidebar.sender().send(SideBarInputMsg::RefreshList);
widgets.renderer.queue_render();
@ -183,6 +192,19 @@ impl Component for MonitorModel {
WidgetType::OpenGl => {}
_ => {}
},
MonitorInputMsg::ChangeZoom(zoom) => {
if self.zoom != zoom {
self.zoom = zoom;
let mut ts = self.tiles.borrow_mut();
for (k,v) in ts.drain() {
if let Some(v) = v {
widgets.renderer.delete_img(v);
}
}
}
}
MonitorInputMsg::RemoveWidget => {}
MonitorInputMsg::None => {}
_ => {}
@ -211,7 +233,7 @@ impl Component for MonitorModel {
padding: [20.0, 40.0, 20.0, 40.0],
};
let model = MonitorModel {
let mut model = MonitorModel {
render_range: (4.0, 53.3, 73.3, 135.0),
new_layer: 0,
widgets: vec![],
@ -220,6 +242,7 @@ impl Component for MonitorModel {
sidebar_open: true,
sidebar_width: 400,
layers: init,
zoom: 4,
map_tile_getter: Arc::new(MapTile::default()),
sidebar,
tracker: 0,
@ -229,6 +252,11 @@ impl Component for MonitorModel {
let tiles = model.tiles.clone();
let widgets = view_output! {};
// let (h, w) = (widgets.renderer.height(), widgets.renderer.width());
// let zoom = lat_lon_to_zoom((4.0, 53.3), (73.3, 135.0), w as f32, h as f32);
// model.zoom = zoom;
ComponentParts { model, widgets }
}
@ -242,8 +270,13 @@ impl Component for MonitorModel {
self.reset();
match message {
MonitorCommand::LoadTile(key, ref tile, origin, bounds) => {
let target = widgets.renderer.load_img_mem(&tile,origin,(256f32,256f32), bounds).unwrap();
self.tiles.borrow_mut().insert(key, target);
let target = widgets
.renderer
.load_img_mem(&tile, origin, (256f32, 256f32), bounds)
.unwrap();
// self.tiles.borrow_mut().insert(key, target);
// *self.tiles.borrow_mut().get_mut(&key) = Some(target);
self.tiles.borrow_mut().entry(key).and_modify(|x| *x = Some(target));
widgets.render.queue_draw();
}
_ => {}

View File

@ -16,7 +16,7 @@ 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_terrain/".to_string(),
client: Client::new(),
}
}

View File

@ -3,8 +3,8 @@ use super::interior::InteriorWidget;
use super::{Layer, WindowCoord};
use crate::coords::proj::Mercator;
use crate::coords::Mapper;
use crate::pipeline::element::Target;
use femtovg::{Canvas, Color, FontId, Renderer};
use crate::pipeline::element::{Target, TargetType};
use femtovg::{Canvas, Color, FontId, Paint, Renderer};
use gtk::glib::{self, prelude::*, Properties};
use gtk::subclass::prelude::*;
use gtk::traits::{GLAreaExt, WidgetExt};
@ -53,11 +53,13 @@ pub struct Render {
render_status: Cell<i64>,
#[property(get, set)]
range_changing: Cell<f64>,
#[property(get, set)]
scale: Cell<f64>,
pub(super) exterior: RefCell<ExteriorWidget>,
pub(super) interior: RefCell<InteriorWidget>,
pub(super) canvas: RefCell<Option<femtovg::Canvas<femtovg::renderer::OpenGl>>>,
pub(super) glow_context: RefCell<Option<glow::Context>>,
pub(super) tiles: RefCell<Rc<RefCell<HashMap<Tile, Target>>>>,
pub(super) tiles: RefCell<Rc<RefCell<HashMap<Tile, Option<Target>>>>>,
pub config: RefCell<RenderConfig>,
pub status: RefCell<RenderStatus>,
pub mapper: RefCell<Mapper>,
@ -67,6 +69,7 @@ pub struct Render {
impl Default for Render {
fn default() -> Self {
Self {
scale: Cell::new(1.0),
range_changing: Cell::new(0.0),
render_status: Cell::new(0),
exterior: RefCell::new(ExteriorWidget::default()),
@ -160,10 +163,13 @@ impl GLAreaImpl for Render {
(w, h)
};
let tiles = self.tiles.borrow().borrow();
for tile in tiles.values() {
let mut binding = self.tiles.borrow();
let mut tiles = binding.borrow_mut();
for tile in tiles.values_mut(){
if let Some(tile) = tile.as_mut() {
self.draw_target(tile);
}
}
let render_range = self.status.borrow().view_range.clone();
@ -207,6 +213,7 @@ impl GLAreaImpl for Render {
let scaled = scale_rate + scale_flag * step;
status.scale_rate = Some(scaled);
self.obj().set_scale(scaled as f64);
let sx = scale_flag * step * px as f64;
let sy = scale_flag * step * py as f64;
status.translation = Some((tx - sx, ty - sy));
@ -345,4 +352,28 @@ impl Render {
.view_range
.replace(((lat1, lat2), (lon1, lon2)));
}
pub(super) fn draw_target(&self, target: &mut Target) {
let mut canvas = self.canvas.borrow_mut();
let canvas = canvas.as_mut().unwrap();
let obj = self.obj();
let (ox,oy) = target.origin(&obj);
let (x, y) = target.size(&obj);
let id = match target.target{
TargetType:: ImageId(id) => id,
TargetType::Mem(ref mem) => {
let converted = canvas.load_image_mem(mem, femtovg::ImageFlags::empty()).unwrap();
target.set_target(TargetType::ImageId(converted));
converted
}
};
let painter = Paint::image(id, ox, oy, x, y, 0.0, 1.0);
let mut path = femtovg::Path::new();
path.rect(ox, oy, x, y);
canvas.fill_path(&path, &painter);
}
}

View File

@ -217,7 +217,7 @@ impl Render {
self.queue_render();
}
pub fn set_tiles(&self, tiles: Rc<RefCell<HashMap<Tile, Target>>>) {
pub fn set_tiles(&self, tiles: Rc<RefCell<HashMap<Tile, Option<Target>>>>) {
self.imp().tiles.replace(tiles);
self.queue_render();
}
@ -229,4 +229,14 @@ impl Render {
let (width, height) = size;
Ok(Target::new(TargetType::ImageId(img_id), width, height, bounds, None, None))
}
pub fn delete_img(&self, img: Target) {
let mut canvas = self.get_canvas();
let cvs = canvas.as_mut().unwrap();
// cvs.delete_image()
if let TargetType::ImageId(id) = img.target {
cvs.delete_image(id);
}
}
}