rustial_engine/map_state/
heavy_layers.rs1use super::*;
2
3impl MapState {
4 pub(super) fn refresh_streamed_vector_layer_features(&mut self) -> HashMap<String, bool> {
5 let streamed_layers: Vec<StreamedVectorLayerRefreshSpec> = self
6 .layers
7 .iter()
8 .filter_map(|layer| {
9 let vector_layer = layer.as_any().downcast_ref::<crate::layers::VectorLayer>()?;
10 let source_id = vector_layer.query_source_id.as_ref()?;
11 let runtime = self.streamed_vector_sources.get(source_id)?;
12 let layer_key = vector_layer
13 .query_layer_id
14 .as_deref()
15 .unwrap_or(vector_layer.name())
16 .to_owned();
17 Some(StreamedVectorLayerRefreshSpec {
18 runtime_id: layer.id(),
19 layer_key,
20 source_id: source_id.clone(),
21 source_layer: vector_layer.query_source_layer.clone(),
22 visible_tiles: runtime.visible_tiles().tiles.clone(),
23 })
24 })
25 .collect();
26
27 let resolved = resolve_streamed_vector_layer_refresh(streamed_layers);
28
29 let mut changed = HashMap::new();
30 let active_keys: HashSet<String> = resolved.iter().map(|entry| entry.layer_key.clone()).collect();
31 self.streamed_vector_layer_fingerprints
32 .retain(|key, _| active_keys.contains(key));
33 self.streamed_vector_query_payloads
34 .retain(|key, _| active_keys.contains(key));
35
36 for resolved_layer in resolved {
37 let was_changed = self
38 .streamed_vector_layer_fingerprints
39 .get(&resolved_layer.layer_key)
40 .copied()
41 != Some(resolved_layer.fingerprint);
42 self.streamed_vector_layer_fingerprints
43 .insert(resolved_layer.layer_key.clone(), resolved_layer.fingerprint);
44 let (features, provenance) = resolved_layer.rebuild_feature_inputs();
45 self.streamed_vector_query_payloads
46 .insert(resolved_layer.layer_key.clone(), resolved_layer.tile_payloads);
47
48 if let Some(layer) = self
49 .layers
50 .iter_mut()
51 .find(|layer| layer.id() == resolved_layer.runtime_id)
52 {
53 if let Some(vector_layer) = layer.as_any_mut().downcast_mut::<crate::layers::VectorLayer>() {
54 vector_layer.set_features_with_provenance(
55 features,
56 provenance,
57 );
58 }
59 }
60
61 changed.insert(resolved_layer.layer_key, was_changed);
62 }
63
64 changed
65 }
66
67 pub(super) fn rebuild_symbol_query_payloads(&mut self) {
68 let view = VisiblePlacedSymbolView::new(&self.placed_symbols);
69 self.streamed_symbol_query_payloads = view.rebuild_query_payloads();
70 self.streamed_symbol_dependency_payloads = view.rebuild_dependency_payloads();
71 }
72
73 pub(super) fn streamed_payload_view_for(&self, layer_id: &str) -> StreamedPayloadView<'_> {
78 StreamedPayloadView::from_optional(
79 self.streamed_vector_query_payloads
80 .get(layer_id)
81 .map(Vec::as_slice),
82 )
83 }
84
85 pub(super) fn streamed_symbol_query_payloads_for(&self, layer_id: &str) -> &[SymbolQueryPayload] {
91 symbol_query_payloads_from_optional(
92 self.streamed_symbol_query_payloads
93 .get(layer_id)
94 .map(Vec::as_slice),
95 )
96 }
97
98 pub(super) fn invalidate_symbol_dependency_tiles(
99 &mut self,
100 matches: impl Fn(&crate::symbols::SymbolAssetDependencies) -> bool,
101 ) -> usize {
102 let affected: HashSet<StreamedSymbolPayloadKey> = collect_affected_symbol_payloads(
103 &self.streamed_symbol_dependency_payloads,
104 matches,
105 );
106
107 if affected.is_empty() {
108 return 0;
109 }
110
111 for (layer_id, tile) in &affected {
112 if let Some(tile) = tile {
113 self.dirty_streamed_symbol_tiles
114 .entry(layer_id.clone())
115 .or_default()
116 .insert(*tile);
117 } else {
118 self.dirty_streamed_symbol_layers.insert(layer_id.clone());
119 }
120 }
121 self.data_update_elapsed = self.data_update_interval;
122
123 self.placed_symbols = Arc::new(prune_affected_symbol_payloads(
124 &affected,
125 &self.placed_symbols,
126 &mut self.streamed_symbol_query_payloads,
127 &mut self.streamed_symbol_dependency_payloads,
128 ));
129 self.symbol_assets.rebuild_from_symbols(&self.placed_symbols);
130 affected.len()
131 }
132
133 pub(super) fn update_heavy_layers(&mut self, dt_seconds: f64) {
139 use crate::layer::LayerKind;
140 use crate::layers::{VectorLayer, VectorRenderMode};
141
142 if let Some(terrain_tiles) = self.desired_terrain_tiles() {
149 self.update_terrain_with_tiles(&terrain_tiles);
150 } else {
151 self.update_terrain();
152 }
153
154 let camera_projection = self.camera.projection();
158 let mut all_vectors: Vec<VectorMeshData> = Vec::new();
159 let mut symbol_candidates = Vec::new();
160 let mut had_symbol_layer = false;
161 let mut active_keys: HashSet<SyncVectorCacheKey> = HashSet::new();
162
163 self.refresh_streamed_vector_layer_features();
164
165 for layer in self.layers.iter() {
166 if !layer.visible() || layer.kind() != LayerKind::Vector {
167 continue;
168 }
169 if let Some(vector_layer) = layer.as_any().downcast_ref::<VectorLayer>() {
170 let layer_id = vector_layer
171 .query_layer_id
172 .as_deref()
173 .unwrap_or(vector_layer.name());
174 let is_streamed_layer = vector_layer
175 .query_source_id
176 .as_ref()
177 .is_some_and(|source_id| self.streamed_vector_sources.contains_key(source_id));
178 had_symbol_layer = had_symbol_layer
179 || vector_layer.style.render_mode == VectorRenderMode::Symbol;
180
181 let cache_key = SyncVectorCacheKey {
184 layer_id: vector_layer.id(),
185 style_fingerprint: vector_layer.style.tessellation_fingerprint(),
186 data_generation: vector_layer.data_generation(),
187 projection: camera_projection,
188 };
189 active_keys.insert(cache_key);
190
191 if let Some(entry) = self.sync_vector_cache.get(&cache_key) {
193 if !entry.mesh.is_empty() {
194 all_vectors.push(entry.mesh.clone());
195 }
196 } else {
197 let mesh = vector_layer.tessellate(camera_projection);
199 if !mesh.is_empty() {
200 all_vectors.push(mesh.clone());
201 }
202 self.sync_vector_cache.insert(
203 cache_key,
204 SyncVectorCacheEntry { mesh },
205 );
206 }
207
208 if is_streamed_layer {
209 let streamed_payloads = self.streamed_payload_view_for(layer_id);
210 let (features, provenance) = streamed_payloads.rebuild_feature_inputs();
211 symbol_candidates.extend(
212 vector_layer.symbol_candidates_for_features(&features, &provenance),
213 );
214 } else {
215 symbol_candidates.extend(vector_layer.symbol_candidates());
216 }
217 }
218 }
219
220 self.sync_vector_cache
223 .retain(|key, _| active_keys.contains(key));
224 self.vector_meshes = Arc::new(all_vectors);
225
226 if had_symbol_layer && !symbol_candidates.is_empty() {
228 let meters_per_pixel = self.camera.meters_per_pixel();
229 let placed = self.symbol_placement.place_candidates(
230 &symbol_candidates,
231 camera_projection,
232 meters_per_pixel,
233 dt_seconds,
234 Some(&self.scene_viewport_bounds),
235 );
236 self.symbol_assets.rebuild_from_symbols(&placed);
237 self.placed_symbols = Arc::new(placed);
238 self.rebuild_symbol_query_payloads();
239 } else if !had_symbol_layer {
240 self.placed_symbols = Arc::new(Vec::new());
241 self.streamed_symbol_query_payloads.clear();
242 self.streamed_symbol_dependency_payloads.clear();
243 self.dirty_streamed_symbol_tiles.clear();
244 }
245
246 let mut models = Vec::new();
248 for layer in self.layers.iter() {
249 if !layer.visible() || layer.kind() != LayerKind::Model {
250 continue;
251 }
252 if let Some(model_layer) = layer.as_any().downcast_ref::<crate::layers::ModelLayer>() {
253 models.extend(model_layer.instances.iter().cloned());
254 }
255 }
256 self.model_instances = Arc::new(models);
257
258 self.collect_visualization_overlays();
260
261 self.collect_image_overlays();
263
264 self.dirty_streamed_symbol_layers.clear();
265 self.dirty_streamed_symbol_tiles.clear();
266 }
267
268 pub(super) fn apply_pending_frame_overrides(&mut self) {
269 if let Some(meshes) = self.pending_terrain_meshes.take() {
270 self.terrain_meshes = meshes;
271 }
272
273 if let Some(meshes) = self.pending_vector_meshes.take() {
274 self.vector_meshes = meshes;
275 }
276
277 if let Some(instances) = self.pending_model_instances.take() {
278 self.model_instances = instances;
279 }
280 }
281
282 pub(super) fn collect_visualization_overlays(&mut self) {
284 use crate::visualization::{
285 GridExtrusionLayer, GridScalarLayer, InstancedColumnLayer, PointCloudLayer,
286 VisualizationOverlay,
287 };
288
289 let mut overlays = Vec::new();
290 for layer in self.layers.iter() {
291 if !layer.visible() {
292 continue;
293 }
294 if layer.kind() != crate::layer::LayerKind::Visualization {
295 continue;
296 }
297 if let Some(grid_layer) = layer.as_any().downcast_ref::<GridScalarLayer>() {
298 overlays.push(VisualizationOverlay::GridScalar {
299 layer_id: grid_layer.id(),
300 grid: grid_layer.grid.clone(),
301 field: grid_layer.field.clone(),
302 ramp: grid_layer.ramp.clone(),
303 });
304 } else if let Some(grid_layer) = layer.as_any().downcast_ref::<GridExtrusionLayer>() {
305 overlays.push(VisualizationOverlay::GridExtrusion {
306 layer_id: grid_layer.id(),
307 grid: grid_layer.grid.clone(),
308 field: grid_layer.field.clone(),
309 ramp: grid_layer.ramp.clone(),
310 params: grid_layer.params.clone(),
311 });
312 } else if let Some(col_layer) = layer.as_any().downcast_ref::<InstancedColumnLayer>() {
313 overlays.push(VisualizationOverlay::Columns {
314 layer_id: col_layer.id(),
315 columns: col_layer.columns.clone(),
316 ramp: col_layer.ramp.clone(),
317 });
318 } else if let Some(point_layer) = layer.as_any().downcast_ref::<PointCloudLayer>() {
319 overlays.push(VisualizationOverlay::Points {
320 layer_id: point_layer.id(),
321 points: point_layer.points.clone(),
322 ramp: point_layer.ramp.clone(),
323 });
324 }
325 }
326 self.visualization_overlays = Arc::new(overlays);
327 }
328
329 pub(super) fn collect_image_overlays(&mut self) {
331 use crate::layers::ImageOverlayLayer;
332 use crate::layers::DynamicImageOverlayLayer;
333
334 let projection = self.camera.projection();
335 let mut overlays = Vec::new();
336 for layer in self.layers.iter_mut() {
337 if !layer.visible() {
338 continue;
339 }
340 if let Some(img_layer) = layer.as_any().downcast_ref::<ImageOverlayLayer>() {
341 overlays.push(img_layer.to_overlay_data(projection));
342 } else if let Some(dyn_layer) = layer.as_any_mut().downcast_mut::<DynamicImageOverlayLayer>() {
343 dyn_layer.poll_frame();
344 if let Some(data) = dyn_layer.to_overlay_data(projection) {
345 overlays.push(data);
346 }
347 }
348 }
349 self.image_overlays = Arc::new(overlays);
350 }
351
352 pub(super) fn apply_style_document(&mut self, document: &StyleDocument) -> Result<(), StyleError> {
354 let layers = document.to_runtime_layers()?;
355 self.layers = LayerStack::new();
356 for layer in layers {
357 self.layers.push(layer);
358 }
359 self.streamed_vector_sources = build_streamed_vector_sources(document);
360 self.streamed_vector_layer_fingerprints.clear();
361 self.streamed_vector_query_payloads.clear();
362 self.streamed_symbol_query_payloads.clear();
363 self.streamed_symbol_dependency_payloads.clear();
364 self.dirty_streamed_symbol_layers.clear();
365 self.dirty_streamed_symbol_tiles.clear();
366 Ok(())
367 }
368
369}
370
371impl MapState {
372 pub fn style_source_is_used(&self, source_id: &str) -> bool {
374 match self.style_document() {
375 Some(document) => document.source_is_used(source_id),
376 None => false,
377 }
378 }
379
380 pub fn style_layer_ids_using_source(&self, source_id: &str) -> Vec<&str> {
382 match self.style_document() {
383 Some(document) => document.layer_ids_using_source(source_id),
384 None => Vec::new(),
385 }
386 }
387
388 pub fn reload_style_source(
390 &mut self,
391 source_id: impl Into<String>,
392 source: crate::style::StyleSource,
393 ) -> Result<bool, StyleError> {
394 let Some(mut style): Option<MapStyle> = self.style.take() else {
395 return Ok(false);
396 };
397 style.document_mut().set_source(source_id.into(), source);
398 self.apply_style_document(style.document())?;
399 self.style = Some(style);
400 Ok(true)
401 }
402
403 pub fn clear_style_source(&mut self, source_id: &str) -> Result<Option<crate::style::StyleSource>, StyleError> {
405 let Some(mut style): Option<MapStyle> = self.style.take() else {
406 return Ok(None);
407 };
408 let removed = style.document_mut().remove_source(source_id);
409 self.apply_style_document(style.document())?;
410 self.style = Some(style);
411 Ok(removed)
412 }
413
414}
415
416fn build_streamed_vector_sources(
417 document: &StyleDocument,
418) -> HashMap<String, crate::layers::TileLayer> {
419 document
420 .sources()
421 .filter_map(|(source_id, source)| match source {
422 crate::style::StyleSource::VectorTile(vector_source) => vector_source
423 .make_tile_source()
424 .map(|tile_source| {
425 (
426 source_id.to_owned(),
427 crate::layers::TileLayer::new_with_selection_config(
428 format!("__vector_source::{source_id}"),
429 tile_source,
430 vector_source.cache_capacity,
431 vector_source.selection.clone(),
432 ),
433 )
434 }),
435 _ => None,
436 })
437 .collect()
438}
439
440pub(super) fn wrapped_world_delta(delta: f64) -> f64 {
441 let half_world = WGS84_CIRCUMFERENCE * 0.5;
442 if delta > half_world {
443 delta - WGS84_CIRCUMFERENCE
444 } else if delta < -half_world {
445 delta + WGS84_CIRCUMFERENCE
446 } else {
447 delta
448 }
449}
450
451pub(super) fn translated_world_bounds(bounds: &WorldBounds, delta: glam::DVec2) -> WorldBounds {
452 WorldBounds::new(
453 WorldCoord::new(
454 bounds.min.position.x + delta.x,
455 bounds.min.position.y + delta.y,
456 bounds.min.position.z,
457 ),
458 WorldCoord::new(
459 bounds.max.position.x + delta.x,
460 bounds.max.position.y + delta.y,
461 bounds.max.position.z,
462 ),
463 )
464}
465