Skip to main content

egml_core/model/geometry/aggregates/
multi_point.rs

1use crate::model::geometry::Envelope;
2use crate::model::geometry::aggregates::{
3    AbstractGeometricAggregate, AsAbstractGeometricAggregate, AsAbstractGeometricAggregateMut,
4};
5use crate::model::geometry::primitives::{PointArrayProperty, PointProperty};
6use crate::{Error, impl_abstract_geometric_aggregate_traits};
7use nalgebra::Isometry3;
8use rayon::iter::IntoParallelRefMutIterator;
9use rayon::iter::ParallelIterator;
10
11#[derive(Debug, Clone, PartialEq)]
12pub struct MultiPoint {
13    pub(crate) abstract_geometric_aggregate: AbstractGeometricAggregate,
14    point_members: Option<PointArrayProperty>,
15    point_member: Vec<PointProperty>,
16}
17
18impl MultiPoint {
19    pub fn new(point_members: Option<PointArrayProperty>) -> Result<Self, Error> {
20        Ok(Self {
21            abstract_geometric_aggregate: AbstractGeometricAggregate::default(),
22            point_members,
23            point_member: Vec::new(),
24        })
25    }
26
27    pub fn point_members(&self) -> Option<&PointArrayProperty> {
28        self.point_members.as_ref()
29    }
30
31    pub fn set_point_members(&mut self, val: Option<PointArrayProperty>) {
32        self.point_members = val;
33    }
34
35    pub fn point_member(&self) -> &[PointProperty] {
36        &self.point_member
37    }
38
39    pub fn set_point_member(&mut self, val: Vec<PointProperty>) {
40        self.point_member = val;
41    }
42
43    pub fn push_point_member(&mut self, member: PointProperty) {
44        self.point_member.push(member);
45    }
46
47    pub fn extend_point_members(&mut self, members: impl IntoIterator<Item = PointProperty>) {
48        self.point_member.extend(members);
49    }
50}
51
52impl MultiPoint {
53    pub fn apply_transform(&mut self, m: &Isometry3<f64>) {
54        if let Some(members) = &mut self.point_members {
55            members
56                .objects
57                .par_iter_mut()
58                .for_each(|p| p.apply_transform(m));
59        }
60        self.point_member.par_iter_mut().for_each(|p| {
61            if let Some(object) = &mut p.object {
62                object.apply_transform(m);
63            }
64        });
65    }
66
67    pub fn compute_envelope(&self) -> Option<Envelope> {
68        let points: Vec<_> = self
69            .point_members
70            .iter()
71            .flat_map(|members| members.objects.iter())
72            .chain(self.point_member.iter().flat_map(|x| x.object.as_ref()))
73            .map(|p| *p.pos())
74            .collect();
75        Envelope::from_points(&points).ok()
76    }
77}
78
79impl AsAbstractGeometricAggregate for MultiPoint {
80    fn abstract_geometric_aggregate(&self) -> &AbstractGeometricAggregate {
81        &self.abstract_geometric_aggregate
82    }
83}
84
85impl AsAbstractGeometricAggregateMut for MultiPoint {
86    fn abstract_geometric_aggregate_mut(&mut self) -> &mut AbstractGeometricAggregate {
87        &mut self.abstract_geometric_aggregate
88    }
89}
90
91impl_abstract_geometric_aggregate_traits!(MultiPoint);