use std::any::Any;
use super::{ColorRamp, ColumnInstanceSet};
use crate::layer::{Layer, LayerId, LayerKind};
#[derive(Debug, Clone)]
pub struct InstancedColumnLayer {
id: LayerId,
name: String,
visible: bool,
opacity: f32,
z_index: i32,
pub columns: ColumnInstanceSet,
pub ramp: ColorRamp,
}
impl InstancedColumnLayer {
pub fn new(name: impl Into<String>, columns: ColumnInstanceSet, ramp: ColorRamp) -> Self {
Self {
id: LayerId::next(),
name: name.into(),
visible: true,
opacity: 1.0,
z_index: 0,
columns,
ramp,
}
}
pub fn set_columns(&mut self, columns: ColumnInstanceSet) {
self.columns = columns;
}
}
impl Layer for InstancedColumnLayer {
fn id(&self) -> LayerId {
self.id
}
fn name(&self) -> &str {
&self.name
}
fn kind(&self) -> LayerKind {
LayerKind::Visualization
}
fn visible(&self) -> bool {
self.visible
}
fn set_visible(&mut self, visible: bool) {
self.visible = visible;
}
fn opacity(&self) -> f32 {
self.opacity
}
fn set_opacity(&mut self, opacity: f32) {
self.opacity = opacity.clamp(0.0, 1.0);
}
fn z_index(&self) -> i32 {
self.z_index
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::visualization::{ColorStop, ColumnInstance};
use rustial_math::GeoCoord;
fn test_ramp() -> ColorRamp {
ColorRamp::new(vec![
ColorStop {
value: 0.0,
color: [0.0, 0.0, 1.0, 1.0],
},
ColorStop {
value: 1.0,
color: [1.0, 0.0, 0.0, 1.0],
},
])
}
#[test]
fn instanced_column_layer_basics() {
let columns = ColumnInstanceSet::new(vec![ColumnInstance::new(
GeoCoord::from_lat_lon(0.0, 0.0),
100.0,
10.0,
)
.with_pick_id(1)]);
let layer = InstancedColumnLayer::new("histogram", columns, test_ramp());
assert_eq!(layer.name(), "histogram");
assert_eq!(layer.columns.len(), 1);
assert_eq!(layer.columns.columns[0].pick_id, 1);
}
#[test]
fn instanced_column_layer_downcast() {
let columns = ColumnInstanceSet::default();
let layer: Box<dyn Layer> =
Box::new(InstancedColumnLayer::new("test", columns, test_ramp()));
assert!(layer
.as_any()
.downcast_ref::<InstancedColumnLayer>()
.is_some());
}
#[test]
fn set_columns_replaces() {
let mut layer =
InstancedColumnLayer::new("test", ColumnInstanceSet::default(), test_ramp());
assert!(layer.columns.is_empty());
layer.set_columns(ColumnInstanceSet::new(vec![ColumnInstance::new(
GeoCoord::from_lat_lon(0.0, 0.0),
50.0,
5.0,
)]));
assert_eq!(layer.columns.len(), 1);
}
}