1use crate::layer::{Layer, LayerId};
4use crate::tile_manager::{
5 TileManager, TileManagerCounters, TileSelectionConfig, TileSelectionStats, VisibleTileSet,
6 ZoomPrefetchDirection,
7};
8use crate::tile_cache::TileCacheStats;
9use crate::tile_lifecycle::TileLifecycleDiagnostics;
10use crate::tile_source::TileSource;
11use crate::tile_source::TileSourceDiagnostics;
12use rustial_math::{FlatTileView, Frustum, GeoCoord, TileId, WorldBounds};
13use std::any::Any;
14use std::collections::HashSet;
15
16pub struct TileLayer {
18 id: LayerId,
19 name: String,
20 visible: bool,
21 opacity: f32,
22 manager: TileManager,
23 last_visible_set: VisibleTileSet,
24}
25
26impl TileLayer {
27 pub fn new(
29 name: impl Into<String>,
30 source: Box<dyn TileSource>,
31 cache_capacity: usize,
32 ) -> Self {
33 Self::new_with_selection_config(
34 name,
35 source,
36 cache_capacity,
37 TileSelectionConfig::default(),
38 )
39 }
40
41 pub fn new_with_selection_config(
43 name: impl Into<String>,
44 source: Box<dyn TileSource>,
45 cache_capacity: usize,
46 selection_config: TileSelectionConfig,
47 ) -> Self {
48 Self {
49 id: LayerId::next(),
50 name: name.into(),
51 visible: true,
52 opacity: 1.0,
53 manager: TileManager::new_with_config(source, cache_capacity, selection_config),
54 last_visible_set: VisibleTileSet::default(),
55 }
56 }
57
58 pub fn update(
60 &mut self,
61 viewport_bounds: &WorldBounds,
62 zoom: u8,
63 camera_world: (f64, f64),
64 camera_distance: f64,
65 ) {
66 self.update_with_view(
67 viewport_bounds,
68 zoom,
69 camera_world,
70 camera_distance,
71 None,
72 );
73 }
74
75 pub fn update_with_view(
78 &mut self,
79 viewport_bounds: &WorldBounds,
80 zoom: u8,
81 camera_world: (f64, f64),
82 camera_distance: f64,
83 flat_view: Option<&FlatTileView>,
84 ) {
85 if self.visible {
86 self.last_visible_set = self.manager.update_with_view(
87 viewport_bounds,
88 zoom,
89 camera_world,
90 camera_distance,
91 flat_view,
92 );
93 }
94 }
95
96 pub fn update_with_frustum(
99 &mut self,
100 frustum: &Frustum,
101 zoom: u8,
102 camera_world: (f64, f64),
103 ) {
104 if self.visible {
105 self.last_visible_set = self.manager.update_with_frustum(
106 frustum,
107 zoom,
108 camera_world,
109 );
110 }
111 }
112
113 pub fn update_with_covering(
119 &mut self,
120 frustum: &Frustum,
121 cam: &rustial_math::CoveringCamera,
122 opts: &rustial_math::CoveringTilesOptions,
123 camera_world: (f64, f64),
124 ) {
125 if self.visible {
126 self.last_visible_set = self.manager.update_with_covering(
127 frustum,
128 cam,
129 opts,
130 camera_world,
131 );
132 }
133 }
134
135 pub fn visible_tiles(&self) -> &VisibleTileSet {
137 &self.last_visible_set
138 }
139
140 pub fn desired_tiles(&self) -> &HashSet<TileId> {
142 self.manager.desired_tiles()
143 }
144
145 pub fn last_selection_stats(&self) -> &TileSelectionStats {
147 self.manager.last_selection_stats()
148 }
149
150 pub fn counters(&self) -> &TileManagerCounters {
152 self.manager.counters()
153 }
154
155 pub fn cache_stats(&self) -> TileCacheStats {
157 self.manager.cache_stats()
158 }
159
160 pub fn source_diagnostics(&self) -> Option<TileSourceDiagnostics> {
162 self.manager.source_diagnostics()
163 }
164
165 pub fn lifecycle_diagnostics(&self) -> TileLifecycleDiagnostics {
167 self.manager.lifecycle_diagnostics()
168 }
169
170 pub fn selection_config(&self) -> &TileSelectionConfig {
172 self.manager.selection_config()
173 }
174
175 pub fn set_selection_config(&mut self, config: TileSelectionConfig) {
177 self.manager.set_selection_config(config);
178 }
179
180 pub fn manager(&self) -> &TileManager {
182 &self.manager
183 }
184
185 pub fn promote_decoded(
189 &mut self,
190 decoded: Vec<(rustial_math::TileId, crate::tile_source::TileResponse)>,
191 ) {
192 self.manager.promote_decoded(decoded);
193 }
194
195 pub fn prefetch_with_view(
198 &mut self,
199 viewport_bounds: &WorldBounds,
200 zoom: u8,
201 camera_world: (f64, f64),
202 flat_view: Option<&FlatTileView>,
203 max_requests: usize,
204 ) -> usize {
205 self.manager.prefetch_with_view(
206 viewport_bounds,
207 zoom,
208 camera_world,
209 flat_view,
210 max_requests,
211 )
212 }
213
214 pub fn prefetch_zoom_direction(
217 &mut self,
218 camera_world: (f64, f64),
219 direction: ZoomPrefetchDirection,
220 max_requests: usize,
221 ) -> usize {
222 self.manager
223 .prefetch_zoom_direction(camera_world, direction, max_requests)
224 }
225
226 pub fn prefetch_route(
230 &mut self,
231 route: &[GeoCoord],
232 zoom: u8,
233 camera_world: (f64, f64),
234 max_requests: usize,
235 ) -> usize {
236 self.manager
237 .prefetch_route(route, zoom, camera_world, max_requests)
238 }
239}
240
241impl Layer for TileLayer {
242 fn id(&self) -> LayerId {
243 self.id
244 }
245
246 fn kind(&self) -> crate::layer::LayerKind {
247 crate::layer::LayerKind::Tile
248 }
249
250 fn name(&self) -> &str {
251 &self.name
252 }
253
254 fn visible(&self) -> bool {
255 self.visible
256 }
257
258 fn set_visible(&mut self, visible: bool) {
259 self.visible = visible;
260 }
261
262 fn opacity(&self) -> f32 {
263 self.opacity
264 }
265
266 fn set_opacity(&mut self, opacity: f32) {
267 self.opacity = opacity.clamp(0.0, 1.0);
268 }
269
270 fn as_any(&self) -> &dyn Any {
271 self
272 }
273
274 fn as_any_mut(&mut self) -> &mut dyn Any {
275 self
276 }
277}