egml_core/model/geometry/primitives/
line_string.rs1use crate::Error::{AdjacentDuplicatePositions, TooFewElements};
2use crate::model::geometry::primitives::{AbstractCurve, AsAbstractCurve, AsAbstractCurveMut};
3use crate::model::geometry::{DirectPosition, Envelope};
4use crate::{Error, impl_abstract_curve_traits};
5use nalgebra::Isometry3;
6
7#[derive(Debug, Clone, PartialEq, Default)]
11pub struct LineString {
12 pub(crate) abstract_curve: AbstractCurve,
13 points: Vec<DirectPosition>,
14}
15
16impl LineString {
17 pub fn new(abstract_curve: AbstractCurve, points: Vec<DirectPosition>) -> Result<Self, Error> {
24 let duplicates_count = points.windows(2).filter(|x| x[0] == x[1]).count();
25 if duplicates_count > 0 {
26 return Err(AdjacentDuplicatePositions);
27 }
28 if points.len() < 2 {
29 return Err(TooFewElements {
30 geometry: "gml:LineString",
31 minimum: 2,
32 spec: Some("ISO 19136 §10.4.4"),
33 id: None,
34 message: None,
35 });
36 }
37
38 Ok(Self {
39 abstract_curve,
40 points,
41 })
42 }
43
44 pub fn points(&self) -> &[DirectPosition] {
46 &self.points
47 }
48
49 pub fn apply_transform(&mut self, m: &Isometry3<f64>) {
51 self.points.iter_mut().for_each(|p| {
52 p.apply_transform(m);
53 });
54 }
55
56 pub fn compute_envelope(&self) -> Envelope {
57 Envelope::from_points(&self.points).expect("line string must have valid points")
58 }
59}
60
61impl AsAbstractCurve for LineString {
62 fn abstract_curve(&self) -> &AbstractCurve {
63 &self.abstract_curve
64 }
65}
66
67impl AsAbstractCurveMut for LineString {
68 fn abstract_curve_mut(&mut self) -> &mut AbstractCurve {
69 &mut self.abstract_curve
70 }
71}
72
73impl_abstract_curve_traits!(LineString);