geo_traits/
multi_point.rs

1use std::marker::PhantomData;
2
3use crate::iterator::MultiPointIterator;
4use crate::{GeometryTrait, PointTrait, UnimplementedPoint};
5#[cfg(feature = "geo-types")]
6use geo_types::{CoordNum, MultiPoint, Point};
7
8/// A trait for accessing data from a generic MultiPoint.
9///
10/// A MultiPoint is a collection of [`Point`s][PointTrait].
11///
12/// Refer to [geo_types::MultiPoint] for information about semantics and validity.
13pub trait MultiPointTrait: Sized + GeometryTrait {
14    /// The type of each underlying Point, which implements [PointTrait]
15    type InnerPointType<'a>: 'a + PointTrait<T = Self::T>
16    where
17        Self: 'a;
18
19    /// An iterator over the points in this MultiPoint
20    fn points(
21        &self,
22    ) -> impl DoubleEndedIterator + ExactSizeIterator<Item = Self::InnerPointType<'_>> {
23        MultiPointIterator::new(self, 0, self.num_points())
24    }
25
26    /// The number of points in this MultiPoint
27    fn num_points(&self) -> usize;
28
29    /// Access to a specified point in this MultiPoint
30    /// Will return None if the provided index is out of bounds
31    fn point(&self, i: usize) -> Option<Self::InnerPointType<'_>> {
32        if i >= self.num_points() {
33            None
34        } else {
35            unsafe { Some(self.point_unchecked(i)) }
36        }
37    }
38
39    /// Access to a specified point in this MultiPoint
40    ///
41    /// # Safety
42    ///
43    /// Accessing an index out of bounds is UB.
44    unsafe fn point_unchecked(&self, i: usize) -> Self::InnerPointType<'_>;
45}
46
47#[cfg(feature = "geo-types")]
48impl<T: CoordNum> MultiPointTrait for MultiPoint<T> {
49    type InnerPointType<'a>
50        = &'a Point<Self::T>
51    where
52        Self: 'a;
53
54    fn num_points(&self) -> usize {
55        self.0.len()
56    }
57
58    unsafe fn point_unchecked(&self, i: usize) -> Self::InnerPointType<'_> {
59        self.0.get_unchecked(i)
60    }
61}
62
63#[cfg(feature = "geo-types")]
64impl<'a, T: CoordNum> MultiPointTrait for &'a MultiPoint<T> {
65    type InnerPointType<'b>
66        = &'a Point<Self::T>
67    where
68        Self: 'b;
69
70    fn num_points(&self) -> usize {
71        self.0.len()
72    }
73
74    unsafe fn point_unchecked(&self, i: usize) -> Self::InnerPointType<'_> {
75        self.0.get_unchecked(i)
76    }
77}
78
79/// An empty struct that implements [MultiPointTrait].
80///
81/// This can be used as the `MultiPointType` of the `GeometryTrait` by implementations that don't
82/// have a MultiPoint concept
83pub struct UnimplementedMultiPoint<T>(PhantomData<T>);
84
85impl<T> MultiPointTrait for UnimplementedMultiPoint<T> {
86    type InnerPointType<'a>
87        = UnimplementedPoint<Self::T>
88    where
89        Self: 'a;
90
91    fn num_points(&self) -> usize {
92        unimplemented!()
93    }
94
95    unsafe fn point_unchecked(&self, _i: usize) -> Self::InnerPointType<'_> {
96        unimplemented!()
97    }
98}