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