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