rustial_engine/visualization/
grid_extrusion_layer.rs1use std::any::Any;
4
5use super::overlay::ExtrusionParams;
6use super::{ColorRamp, GeoGrid, ScalarField2D};
7use crate::layer::{Layer, LayerId, LayerKind};
8
9#[derive(Debug, Clone)]
15pub struct GridExtrusionLayer {
16 id: LayerId,
17 name: String,
18 visible: bool,
19 opacity: f32,
20 z_index: i32,
21 pub grid: GeoGrid,
23 pub field: ScalarField2D,
25 pub ramp: ColorRamp,
27 pub params: ExtrusionParams,
29}
30
31impl GridExtrusionLayer {
32 pub fn new(
34 name: impl Into<String>,
35 grid: GeoGrid,
36 field: ScalarField2D,
37 ramp: ColorRamp,
38 ) -> Self {
39 Self {
40 id: LayerId::next(),
41 name: name.into(),
42 visible: true,
43 opacity: 1.0,
44 z_index: 0,
45 grid,
46 field,
47 ramp,
48 params: ExtrusionParams::default(),
49 }
50 }
51
52 pub fn with_params(mut self, params: ExtrusionParams) -> Self {
54 self.params = params;
55 self
56 }
57
58 pub fn update_field(&mut self, data: Vec<f32>) {
60 self.field.update_values(data);
61 }
62}
63
64impl Layer for GridExtrusionLayer {
65 fn id(&self) -> LayerId {
66 self.id
67 }
68
69 fn name(&self) -> &str {
70 &self.name
71 }
72
73 fn kind(&self) -> LayerKind {
74 LayerKind::Visualization
75 }
76
77 fn visible(&self) -> bool {
78 self.visible
79 }
80
81 fn set_visible(&mut self, visible: bool) {
82 self.visible = visible;
83 }
84
85 fn opacity(&self) -> f32 {
86 self.opacity
87 }
88
89 fn set_opacity(&mut self, opacity: f32) {
90 self.opacity = opacity.clamp(0.0, 1.0);
91 }
92
93 fn z_index(&self) -> i32 {
94 self.z_index
95 }
96
97 fn as_any(&self) -> &dyn Any {
98 self
99 }
100
101 fn as_any_mut(&mut self) -> &mut dyn Any {
102 self
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109 use crate::visualization::ColorStop;
110 use rustial_math::GeoCoord;
111
112 fn test_ramp() -> ColorRamp {
113 ColorRamp::new(vec![
114 ColorStop {
115 value: 0.0,
116 color: [0.0, 0.0, 1.0, 1.0],
117 },
118 ColorStop {
119 value: 1.0,
120 color: [1.0, 0.0, 0.0, 1.0],
121 },
122 ])
123 }
124
125 #[test]
126 fn grid_extrusion_layer_basics() {
127 let grid = GeoGrid::new(GeoCoord::from_lat_lon(0.0, 0.0), 4, 4, 100.0, 100.0);
128 let field = ScalarField2D::from_data(4, 4, vec![0.0; 16]);
129 let layer = GridExtrusionLayer::new("extrusion", grid, field, test_ramp());
130 assert_eq!(layer.name(), "extrusion");
131 assert!((layer.params.height_scale - 1.0).abs() < 1e-9);
132 assert!((layer.params.base_meters - 0.0).abs() < 1e-9);
133 }
134
135 #[test]
136 fn grid_extrusion_with_params() {
137 let grid = GeoGrid::new(GeoCoord::from_lat_lon(0.0, 0.0), 2, 2, 50.0, 50.0);
138 let field = ScalarField2D::from_data(2, 2, vec![1.0; 4]);
139 let layer =
140 GridExtrusionLayer::new("ext", grid, field, test_ramp()).with_params(ExtrusionParams {
141 height_scale: 10.0,
142 base_meters: 5.0,
143 });
144 assert!((layer.params.height_scale - 10.0).abs() < 1e-9);
145 assert!((layer.params.base_meters - 5.0).abs() < 1e-9);
146 }
147}