egml_core/model/geometry/aggregates/
multi_point.rs1use crate::model::common::{ApplyTransform, ComputeEnvelope, IterGeometries};
2use crate::model::geometry::Envelope;
3use crate::model::geometry::aggregates::{
4 AbstractGeometricAggregate, AsAbstractGeometricAggregate, AsAbstractGeometricAggregateMut,
5};
6use crate::model::geometry::primitives::{PointArrayProperty, PointProperty};
7use crate::model::geometry::refs::AbstractGeometryKindRef;
8use crate::{
9 Error, impl_abstract_geometric_aggregate_mut_traits, impl_abstract_geometric_aggregate_traits,
10 impl_has_geometry_type,
11};
12use nalgebra::{Isometry3, Rotation3, Scale3, Transform3, Vector3};
13use rayon::iter::IntoParallelRefMutIterator;
14use rayon::iter::ParallelIterator;
15
16#[derive(Debug, Clone, PartialEq)]
17pub struct MultiPoint {
18 pub abstract_geometric_aggregate: AbstractGeometricAggregate,
19 point_members: Option<PointArrayProperty>,
20 point_member: Vec<PointProperty>,
21}
22
23impl MultiPoint {
24 pub fn new(point_members: Option<PointArrayProperty>) -> Result<Self, Error> {
25 Ok(Self {
26 abstract_geometric_aggregate: AbstractGeometricAggregate::default(),
27 point_members,
28 point_member: Vec::new(),
29 })
30 }
31
32 pub fn from_abstract_geometric_aggregate(
33 abstract_geometric_aggregate: AbstractGeometricAggregate,
34 point_members: Option<PointArrayProperty>,
35 ) -> Self {
36 Self {
37 abstract_geometric_aggregate,
38 point_members,
39 point_member: Vec::new(),
40 }
41 }
42
43 pub fn point_members(&self) -> Option<&PointArrayProperty> {
44 self.point_members.as_ref()
45 }
46
47 pub fn set_point_members(&mut self, val: PointArrayProperty) {
48 self.point_members = Some(val);
49 }
50
51 pub fn set_point_members_opt(&mut self, val: Option<PointArrayProperty>) {
52 self.point_members = val;
53 }
54
55 pub fn clear_point_members(&mut self) {
56 self.point_members = None;
57 }
58
59 pub fn point_member(&self) -> &[PointProperty] {
60 &self.point_member
61 }
62
63 pub fn set_point_member(&mut self, val: Vec<PointProperty>) {
64 self.point_member = val;
65 }
66
67 pub fn push_point_member(&mut self, member: PointProperty) {
68 self.point_member.push(member);
69 }
70
71 pub fn extend_point_members(&mut self, members: impl IntoIterator<Item = PointProperty>) {
72 self.point_member.extend(members);
73 }
74}
75
76impl ApplyTransform for MultiPoint {
77 fn apply_transform(&mut self, transform: Transform3<f64>) {
78 if let Some(members) = &mut self.point_members {
79 members
80 .objects_mut()
81 .par_iter_mut()
82 .for_each(|p| p.apply_transform(transform));
83 }
84 self.point_member.par_iter_mut().for_each(|p| {
85 if let Some(object) = p.object_mut() {
86 object.apply_transform(transform);
87 }
88 });
89 }
90
91 fn apply_isometry(&mut self, isometry: Isometry3<f64>) {
92 if let Some(members) = &mut self.point_members {
93 members
94 .objects_mut()
95 .par_iter_mut()
96 .for_each(|p| p.apply_isometry(isometry));
97 }
98 self.point_member.par_iter_mut().for_each(|p| {
99 if let Some(object) = p.object_mut() {
100 object.apply_isometry(isometry);
101 }
102 });
103 }
104
105 fn apply_translation(&mut self, vector: Vector3<f64>) {
106 if let Some(members) = &mut self.point_members {
107 members
108 .objects_mut()
109 .par_iter_mut()
110 .for_each(|p| p.apply_translation(vector));
111 }
112 self.point_member.par_iter_mut().for_each(|p| {
113 if let Some(object) = p.object_mut() {
114 object.apply_translation(vector);
115 }
116 });
117 }
118
119 fn apply_rotation(&mut self, rotation: Rotation3<f64>) {
120 if let Some(members) = &mut self.point_members {
121 members
122 .objects_mut()
123 .par_iter_mut()
124 .for_each(|p| p.apply_rotation(rotation));
125 }
126 self.point_member.par_iter_mut().for_each(|p| {
127 if let Some(object) = p.object_mut() {
128 object.apply_rotation(rotation);
129 }
130 });
131 }
132
133 fn apply_scale(&mut self, scale: Scale3<f64>) {
134 if let Some(members) = &mut self.point_members {
135 members
136 .objects_mut()
137 .par_iter_mut()
138 .for_each(|p| p.apply_scale(scale));
139 }
140 self.point_member.par_iter_mut().for_each(|p| {
141 if let Some(object) = p.object_mut() {
142 object.apply_scale(scale);
143 }
144 });
145 }
146}
147
148impl ComputeEnvelope for MultiPoint {
149 fn compute_envelope(&self) -> Option<Envelope> {
150 let points: Vec<_> = self
151 .point_members
152 .iter()
153 .flat_map(|members| members.objects().iter())
154 .chain(self.point_member.iter().flat_map(|x| x.object()))
155 .map(|p| *p.pos())
156 .collect();
157 Envelope::from_points(&points).ok()
158 }
159}
160
161impl AsAbstractGeometricAggregate for MultiPoint {
162 fn abstract_geometric_aggregate(&self) -> &AbstractGeometricAggregate {
163 &self.abstract_geometric_aggregate
164 }
165}
166
167impl AsAbstractGeometricAggregateMut for MultiPoint {
168 fn abstract_geometric_aggregate_mut(&mut self) -> &mut AbstractGeometricAggregate {
169 &mut self.abstract_geometric_aggregate
170 }
171}
172
173impl_abstract_geometric_aggregate_traits!(MultiPoint);
174impl_abstract_geometric_aggregate_mut_traits!(MultiPoint);
175impl_has_geometry_type!(MultiPoint, MultiPoint);
176
177impl IterGeometries for MultiPoint {
178 fn iter_geometries(&self) -> Box<dyn Iterator<Item = AbstractGeometryKindRef<'_>> + '_> {
179 Box::new(
180 std::iter::once(self.into())
181 .chain(
182 self.point_members
183 .iter()
184 .flat_map(|members| members.objects().iter())
185 .flat_map(|x| x.iter_geometries()),
186 )
187 .chain(
188 self.point_member
189 .iter()
190 .filter_map(|x| x.object())
191 .flat_map(|x| x.iter_geometries()),
192 ),
193 )
194 }
195}