egml_core/model/geometry/aggregates/
multi_point.rs1use 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);