rustial_engine/visualization/
instanced_column_layer.rs1use std::any::Any;
4
5use crate::layer::{Layer, LayerId, LayerKind};
6use super::{ColorRamp, ColumnInstanceSet};
7
8#[derive(Debug, Clone)]
15pub struct InstancedColumnLayer {
16 id: LayerId,
17 name: String,
18 visible: bool,
19 opacity: f32,
20 z_index: i32,
21 pub columns: ColumnInstanceSet,
23 pub ramp: ColorRamp,
25}
26
27impl InstancedColumnLayer {
28 pub fn new(
30 name: impl Into<String>,
31 columns: ColumnInstanceSet,
32 ramp: ColorRamp,
33 ) -> Self {
34 Self {
35 id: LayerId::next(),
36 name: name.into(),
37 visible: true,
38 opacity: 1.0,
39 z_index: 0,
40 columns,
41 ramp,
42 }
43 }
44
45 pub fn set_columns(&mut self, columns: ColumnInstanceSet) {
47 self.columns = columns;
48 }
49}
50
51impl Layer for InstancedColumnLayer {
52 fn id(&self) -> LayerId {
53 self.id
54 }
55
56 fn name(&self) -> &str {
57 &self.name
58 }
59
60 fn kind(&self) -> LayerKind {
61 LayerKind::Visualization
62 }
63
64 fn visible(&self) -> bool {
65 self.visible
66 }
67
68 fn set_visible(&mut self, visible: bool) {
69 self.visible = visible;
70 }
71
72 fn opacity(&self) -> f32 {
73 self.opacity
74 }
75
76 fn set_opacity(&mut self, opacity: f32) {
77 self.opacity = opacity.clamp(0.0, 1.0);
78 }
79
80 fn z_index(&self) -> i32 {
81 self.z_index
82 }
83
84 fn as_any(&self) -> &dyn Any {
85 self
86 }
87
88 fn as_any_mut(&mut self) -> &mut dyn Any {
89 self
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 use crate::visualization::{ColorStop, ColumnInstance};
97 use rustial_math::GeoCoord;
98
99 fn test_ramp() -> ColorRamp {
100 ColorRamp::new(vec![
101 ColorStop { value: 0.0, color: [0.0, 0.0, 1.0, 1.0] },
102 ColorStop { value: 1.0, color: [1.0, 0.0, 0.0, 1.0] },
103 ])
104 }
105
106 #[test]
107 fn instanced_column_layer_basics() {
108 let columns = ColumnInstanceSet::new(vec![
109 ColumnInstance::new(GeoCoord::from_lat_lon(0.0, 0.0), 100.0, 10.0)
110 .with_pick_id(1),
111 ]);
112 let layer = InstancedColumnLayer::new("histogram", columns, test_ramp());
113 assert_eq!(layer.name(), "histogram");
114 assert_eq!(layer.columns.len(), 1);
115 assert_eq!(layer.columns.columns[0].pick_id, 1);
116 }
117
118 #[test]
119 fn instanced_column_layer_downcast() {
120 let columns = ColumnInstanceSet::default();
121 let layer: Box<dyn Layer> = Box::new(
122 InstancedColumnLayer::new("test", columns, test_ramp()),
123 );
124 assert!(layer.as_any().downcast_ref::<InstancedColumnLayer>().is_some());
125 }
126
127 #[test]
128 fn set_columns_replaces() {
129 let mut layer = InstancedColumnLayer::new(
130 "test",
131 ColumnInstanceSet::default(),
132 test_ramp(),
133 );
134 assert!(layer.columns.is_empty());
135 layer.set_columns(ColumnInstanceSet::new(vec![
136 ColumnInstance::new(GeoCoord::from_lat_lon(0.0, 0.0), 50.0, 5.0),
137 ]));
138 assert_eq!(layer.columns.len(), 1);
139 }
140}