1use geometry_model::{Linestring, Polygon, Ring};
12use geometry_trait::Point as PointTrait;
13
14pub fn append<G, P>(g: &mut G, point: P)
19where
20 G: Append<P>,
21{
22 g.append(point);
23}
24
25pub fn append_to_ring<P, const CW: bool, const CL: bool>(
38 polygon: &mut Polygon<P, CW, CL>,
39 point: P,
40 ring_index: Option<usize>,
41) where
42 P: PointTrait,
43{
44 match ring_index {
45 None => polygon.outer.0.push(point),
46 Some(i) if i < polygon.inners.len() => polygon.inners[i].0.push(point),
47 Some(_) => {}
49 }
50}
51
52#[doc(hidden)]
56pub trait Append<P> {
57 fn append(&mut self, point: P);
58}
59
60impl<P: PointTrait> Append<P> for Linestring<P> {
61 fn append(&mut self, point: P) {
62 self.0.push(point);
63 }
64}
65
66impl<P: PointTrait, const CW: bool, const CL: bool> Append<P> for Ring<P, CW, CL> {
67 fn append(&mut self, point: P) {
68 self.0.push(point);
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::{append, append_to_ring};
79 use geometry_cs::Cartesian;
80 use geometry_model::{Linestring, Point2D, Polygon, linestring, polygon};
81 use geometry_trait::{Linestring as _, Polygon as _, Ring as _};
82
83 type Pt = Point2D<f64, Cartesian>;
84
85 #[test]
86 fn append_to_linestring() {
87 let mut ls: Linestring<Pt> = linestring![(0., 0.), (1., 1.)];
88 append(&mut ls, Pt::new(2., 2.));
89 assert_eq!(ls.points().count(), 3);
90 }
91
92 #[test]
93 fn append_to_ring_grows_by_one() {
94 let mut r: geometry_model::Ring<Pt> =
95 geometry_model::Ring::from_vec(vec![Pt::new(0., 0.), Pt::new(4., 0.)]);
96 append(&mut r, Pt::new(4., 3.));
97 assert_eq!(r.points().count(), 3);
98 }
99
100 #[test]
101 fn append_to_polygon_outer() {
102 let mut pg: Polygon<Pt> = polygon![[(0., 0.), (4., 0.), (4., 3.)]];
103 append_to_ring(&mut pg, Pt::new(0., 3.), None);
104 assert_eq!(pg.exterior().points().count(), 4);
105 }
106
107 #[test]
108 fn append_to_polygon_interior_ring_by_index() {
109 let mut pg: Polygon<Pt> = polygon![
110 [(0., 0.), (10., 0.), (10., 10.), (0., 10.), (0., 0.)],
111 [(1., 1.), (2., 1.), (2., 2.)],
112 ];
113 append_to_ring(&mut pg, Pt::new(1., 2.), Some(0));
114 assert_eq!(pg.interiors().next().unwrap().points().count(), 4);
115 }
116
117 #[test]
118 fn append_to_out_of_range_interior_is_a_noop() {
119 let mut pg: Polygon<Pt> = polygon![[(0., 0.), (10., 0.), (10., 10.), (0., 10.), (0., 0.)]];
123 append_to_ring(&mut pg, Pt::new(1., 1.), Some(0));
125 assert_eq!(pg.interiors().count(), 0, "no ring created, no panic");
126 assert_eq!(pg.exterior().points().count(), 5);
128 }
129}