137 lines
No EOL
4.2 KiB
Rust
137 lines
No EOL
4.2 KiB
Rust
use std::cell::RefCell;
|
|
use crate::map::sources::baselayers::*;
|
|
use crate::map::sources::datalayers::*;
|
|
use crate::map::sources::{ActiveLayer, LayerSource, Tile};
|
|
use eframe::emath::{pos2, Rect};
|
|
use futures::channel::mpsc::TrySendError;
|
|
use image::{ColorType, DynamicImage};
|
|
use lru::LruCache;
|
|
use poll_promise::Promise;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::cmp::PartialEq;
|
|
use std::collections::HashMap;
|
|
use std::fmt::{Debug, Formatter};
|
|
use std::rc::Rc;
|
|
use std::sync::{Arc, Mutex};
|
|
use tracing::{debug, error, trace};
|
|
use walkers::sources::{Attribution, TileSource};
|
|
use walkers::{HttpTiles, Texture, TextureWithUv, TileId, Tiles};
|
|
|
|
// type aliases to make the tile map less hellish
|
|
pub type ZoomLevel = usize;
|
|
pub type XCoord = usize;
|
|
pub type YCoord = usize;
|
|
pub type SourceId = u64;
|
|
|
|
#[derive(Default, Serialize, Deserialize, Debug)]
|
|
#[serde(default)]
|
|
pub struct LayerManager {
|
|
#[serde(skip)]
|
|
pub ctx: Option<egui::Context>,
|
|
pub registered_sources: HashMap<SourceId, LayerSource>,
|
|
pub active_layers: Vec<ActiveLayer>,
|
|
#[serde(skip)]
|
|
pub individual_sources: HashMap<SourceId, WHttpTiles>,
|
|
}
|
|
|
|
pub struct WHttpTiles(pub Rc<RefCell<HttpTiles>>);
|
|
impl Debug for WHttpTiles {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "<WHttpTiles>")
|
|
}
|
|
}
|
|
|
|
impl LayerManager {
|
|
pub fn register_layer(&mut self, layer: &LayerSource) {
|
|
self.registered_sources
|
|
.insert(layer.source_id, layer.clone());
|
|
}
|
|
pub fn unregister_layer(&mut self, layer_id: &SourceId) {
|
|
self.registered_sources.remove(layer_id);
|
|
self.active_layers.retain(|u| u.source_id != *layer_id);
|
|
}
|
|
pub fn register_builtin_layers(&mut self) {
|
|
let layers = [
|
|
// -- Base layers --
|
|
&*BASELAYER_OSM, // OpenStreetMap
|
|
// -- NOAA MRMS - Merged Composite Reflectivity - QCd
|
|
&*NOAA_MRMS_MERGED_CREF_QC_CONUS, // Continental United States
|
|
&*NOAA_MRMS_MERGED_CREF_QC_HAWAII, // Hawaii
|
|
&*NOAA_MRMS_MERGED_CREF_QC_ALASKA, // Alaska FSS
|
|
&*NOAA_MRMS_MERGED_CREF_QC_CARIB, // Caribbean
|
|
&*NOAA_MRMS_MERGED_CREF_QC_GUAM, // Guam
|
|
// -- NOAA MRMS - Merged RhoHV (Differential Reflectivity) @ 3km
|
|
&*NOAA_MRMS_MERGED_RHOHV_3KM_CONUS,
|
|
];
|
|
|
|
for layer in layers {
|
|
self.register_layer(layer);
|
|
}
|
|
}
|
|
|
|
pub fn remove_unregistered_layers(&mut self) {
|
|
// remove any
|
|
self.active_layers
|
|
.retain(|u| self.registered_sources.contains_key(&u.source_id));
|
|
}
|
|
}
|
|
|
|
impl TileSource for LayerSource {
|
|
fn tile_url(&self, tile_id: TileId) -> String {
|
|
self.tile_url
|
|
.replace("{z}", &tile_id.zoom.to_string())
|
|
.replace("{x}", &tile_id.x.to_string())
|
|
.replace("{y}", &tile_id.y.to_string())
|
|
}
|
|
|
|
fn attribution(&self) -> Attribution {
|
|
Attribution {
|
|
text: self.source.clone().leak(),
|
|
url: self.source_link.clone().leak(),
|
|
logo_light: None,
|
|
logo_dark: None,
|
|
}
|
|
}
|
|
|
|
fn tile_size(&self) -> u32 {
|
|
self.tile_size
|
|
}
|
|
|
|
fn max_zoom(&self) -> u8 {
|
|
self.max_zoom
|
|
}
|
|
}
|
|
|
|
impl Tiles for LayerManager {
|
|
fn at(&mut self, tile_id: TileId) -> Vec<TextureWithUv> {
|
|
let mut layers = vec![];
|
|
for layer in self.active_layers.iter().rev().filter(|u| u.visible) {
|
|
let layer = self.individual_sources.entry(layer.source_id)
|
|
.or_insert_with(|| {
|
|
WHttpTiles(Rc::new(RefCell::new(HttpTiles::new(
|
|
self.registered_sources
|
|
.get(&layer.source_id)
|
|
.unwrap()
|
|
.clone(),
|
|
self.ctx.as_ref().unwrap().clone(),
|
|
))))
|
|
});
|
|
let tiles_here = layer.0.borrow_mut().at(tile_id);
|
|
layers.extend(tiles_here);
|
|
}
|
|
layers
|
|
}
|
|
|
|
fn attribution(&self) -> Attribution {
|
|
Attribution {
|
|
text: "our sources",
|
|
url: "https://weather.ax/credits",
|
|
logo_light: None,
|
|
logo_dark: None,
|
|
}
|
|
}
|
|
|
|
fn tile_size(&self) -> u32 {
|
|
256
|
|
}
|
|
} |