Skip to main content

egml_core/model/geometry/primitives/
point.rs

1use crate::model::common::{ApplyTransform, ComputeEnvelope, IterGeometries};
2use crate::model::geometry::primitives::{
3    AbstractGeometricPrimitive, AsAbstractGeometricPrimitive, AsAbstractGeometricPrimitiveMut,
4};
5use crate::model::geometry::refs::AbstractGeometryKindRef;
6use crate::model::geometry::{DirectPosition, Envelope};
7use crate::{
8    impl_abstract_geometric_primitive_mut_traits, impl_abstract_geometric_primitive_traits,
9    impl_has_geometry_type,
10};
11use nalgebra::{Isometry3, Rotation3, Scale3, Transform3, Vector3};
12
13/// A 0-D geometry that wraps a single [`DirectPosition`].
14///
15/// Corresponds to `gml:Point` in [OGC 07-036 ยง10.3.1](https://docs.ogc.org/is/07-036/07-036.pdf).
16#[derive(Debug, Clone, PartialEq, Default)]
17pub struct Point {
18    pub abstract_geometric_primitive: AbstractGeometricPrimitive,
19    pos: DirectPosition,
20}
21
22impl Point {
23    /// Creates a new `Point` from a position.
24    ///
25    /// # Examples
26    ///
27    /// ```rust
28    /// use egml_core::model::geometry::DirectPosition;
29    /// use egml_core::model::geometry::primitives::Point;
30    ///
31    /// let pos = DirectPosition::new(1.0, 2.0, 3.0).unwrap();
32    /// let pt = Point::new(pos);
33    /// assert_eq!(pt.pos().x(), 1.0);
34    /// ```
35    pub fn new(direct_position: DirectPosition) -> Self {
36        Self {
37            abstract_geometric_primitive: AbstractGeometricPrimitive::default(),
38            pos: direct_position,
39        }
40    }
41
42    pub fn from_abstract_geometric_primitive(
43        abstract_geometric_primitive: AbstractGeometricPrimitive,
44        direct_position: DirectPosition,
45    ) -> Self {
46        Self {
47            abstract_geometric_primitive,
48            pos: direct_position,
49        }
50    }
51
52    /// Returns the coordinate of this point.
53    pub fn pos(&self) -> &DirectPosition {
54        &self.pos
55    }
56
57    pub fn set_pos(&mut self, pos: DirectPosition) {
58        self.pos = pos;
59    }
60}
61
62impl AsAbstractGeometricPrimitive for Point {
63    fn abstract_geometric_primitive(&self) -> &AbstractGeometricPrimitive {
64        &self.abstract_geometric_primitive
65    }
66}
67
68impl AsAbstractGeometricPrimitiveMut for Point {
69    fn abstract_geometric_primitive_mut(&mut self) -> &mut AbstractGeometricPrimitive {
70        &mut self.abstract_geometric_primitive
71    }
72}
73
74impl_abstract_geometric_primitive_traits!(Point);
75impl_abstract_geometric_primitive_mut_traits!(Point);
76impl_has_geometry_type!(Point, Point);
77
78impl ApplyTransform for Point {
79    fn apply_transform(&mut self, transform: Transform3<f64>) {
80        self.pos.apply_transform(transform);
81    }
82
83    fn apply_isometry(&mut self, isometry: Isometry3<f64>) {
84        self.pos.apply_isometry(isometry);
85    }
86
87    fn apply_translation(&mut self, vector: Vector3<f64>) {
88        self.pos.apply_translation(vector);
89    }
90
91    fn apply_rotation(&mut self, rotation: Rotation3<f64>) {
92        self.pos.apply_rotation(rotation);
93    }
94
95    fn apply_scale(&mut self, scale: Scale3<f64>) {
96        self.pos.apply_scale(scale);
97    }
98}
99
100impl ComputeEnvelope for Point {
101    /// Returns a degenerate (zero-volume) envelope at the point's position.
102    fn compute_envelope(&self) -> Option<Envelope> {
103        Some(Envelope::new_unchecked(self.pos, self.pos))
104    }
105}
106
107impl IterGeometries for Point {
108    fn iter_geometries(&self) -> Box<dyn Iterator<Item = AbstractGeometryKindRef<'_>> + '_> {
109        Box::new(std::iter::once(self.into()))
110    }
111}