use crate::model::geometry::primitives::{AbstractCurve, AsAbstractCurve, AsAbstractCurveMut};
use crate::model::geometry::{DirectPosition, Envelope};
use crate::{Error, impl_abstract_curve_traits};
use nalgebra::Isometry3;
#[derive(Debug, Clone, PartialEq, Default)]
pub struct LineString {
pub(crate) abstract_curve: AbstractCurve,
points: Vec<DirectPosition>,
}
impl LineString {
pub fn new(abstract_curve: AbstractCurve, points: Vec<DirectPosition>) -> Result<Self, Error> {
if let Some((index, window)) = points.windows(2).enumerate().find(|(_, w)| w[0] == w[1]) {
return Err(Error::AdjacentDuplicatePositions {
index,
position: window[0],
});
}
if points.len() < 2 {
return Err(Error::TooFewElements {
geometry: "gml:LineString",
minimum: 2,
spec: Some("OGC 07-036 §10.4.4"),
id: None,
detail: None,
});
}
Ok(Self {
abstract_curve,
points,
})
}
pub fn points(&self) -> &[DirectPosition] {
&self.points
}
pub fn apply_transform(&mut self, m: &Isometry3<f64>) {
self.points.iter_mut().for_each(|p| {
p.apply_transform(m);
});
}
pub fn compute_envelope(&self) -> Envelope {
Envelope::from_points(&self.points).expect("line string must have valid points")
}
}
impl AsAbstractCurve for LineString {
fn abstract_curve(&self) -> &AbstractCurve {
&self.abstract_curve
}
}
impl AsAbstractCurveMut for LineString {
fn abstract_curve_mut(&mut self) -> &mut AbstractCurve {
&mut self.abstract_curve
}
}
impl_abstract_curve_traits!(LineString);