Skip to main content

geometry_algorithm/
linestring_segmentize.rs

1//! Split a linestring into equal-length pieces.
2//!
3//! The default is Cartesian. The explicit-strategy entry also supports
4//! spherical Haversine measurement and great-circle interpolation.
5
6use geometry_strategy::{CartesianSegmentize, SegmentizeStrategy};
7
8/// Split a linestring into equal Cartesian arc-length pieces.
9#[inline]
10#[must_use]
11pub fn linestring_segmentize<L>(
12    line: &L,
13    count: usize,
14) -> <CartesianSegmentize as SegmentizeStrategy<L>>::Output
15where
16    CartesianSegmentize: SegmentizeStrategy<L>,
17{
18    CartesianSegmentize.segmentize(line, count)
19}
20
21/// Split a linestring using an explicitly supplied measurement and
22/// interpolation strategy.
23#[inline]
24#[must_use]
25#[allow(
26    clippy::needless_pass_by_value,
27    reason = "segmentization strategies are zero-sized or small Copy values, matching other _with entries"
28)]
29pub fn linestring_segmentize_with<L, S>(line: &L, count: usize, strategy: S) -> S::Output
30where
31    S: SegmentizeStrategy<L>,
32{
33    strategy.segmentize(line, count)
34}
35
36#[cfg(test)]
37mod tests {
38    use super::linestring_segmentize;
39    use geometry_cs::Cartesian;
40    use geometry_model::{Linestring, Point2D};
41
42    type P = Point2D<f64, Cartesian>;
43
44    #[test]
45    fn equal_pieces_keep_original_corner_vertices() {
46        let line = Linestring::from_vec(vec![P::new(0.0, 0.0), P::new(2.0, 0.0), P::new(2.0, 2.0)]);
47        let pieces = linestring_segmentize(&line, 2);
48        assert_eq!(pieces.0.len(), 2);
49        assert_eq!(pieces.0[0].0.last(), Some(&P::new(2.0, 0.0)));
50        assert_eq!(pieces.0[1].0.first(), Some(&P::new(2.0, 0.0)));
51        assert!(linestring_segmentize(&line, 0).0.is_empty());
52    }
53}