use geometry_model::{Linestring, Polygon, Ring};
use geometry_trait::Point as PointTrait;
pub fn append<G, P>(g: &mut G, point: P)
where
G: Append<P>,
{
g.append(point);
}
pub fn append_to_ring<P, const CW: bool, const CL: bool>(
polygon: &mut Polygon<P, CW, CL>,
point: P,
ring_index: Option<usize>,
) where
P: PointTrait,
{
match ring_index {
None => polygon.outer.0.push(point),
Some(i) if i < polygon.inners.len() => polygon.inners[i].0.push(point),
Some(_) => {}
}
}
#[doc(hidden)]
pub trait Append<P> {
fn append(&mut self, point: P);
}
impl<P: PointTrait> Append<P> for Linestring<P> {
fn append(&mut self, point: P) {
self.0.push(point);
}
}
impl<P: PointTrait, const CW: bool, const CL: bool> Append<P> for Ring<P, CW, CL> {
fn append(&mut self, point: P) {
self.0.push(point);
}
}
#[cfg(test)]
mod tests {
use super::{append, append_to_ring};
use geometry_cs::Cartesian;
use geometry_model::{Linestring, Point2D, Polygon, linestring, polygon};
use geometry_trait::{Linestring as _, Polygon as _, Ring as _};
type Pt = Point2D<f64, Cartesian>;
#[test]
fn append_to_linestring() {
let mut ls: Linestring<Pt> = linestring![(0., 0.), (1., 1.)];
append(&mut ls, Pt::new(2., 2.));
assert_eq!(ls.points().count(), 3);
}
#[test]
fn append_to_polygon_outer() {
let mut pg: Polygon<Pt> = polygon![[(0., 0.), (4., 0.), (4., 3.)]];
append_to_ring(&mut pg, Pt::new(0., 3.), None);
assert_eq!(pg.exterior().points().count(), 4);
}
#[test]
fn append_to_polygon_interior_ring_by_index() {
let mut pg: Polygon<Pt> = polygon![
[(0., 0.), (10., 0.), (10., 10.), (0., 10.), (0., 0.)],
[(1., 1.), (2., 1.), (2., 2.)],
];
append_to_ring(&mut pg, Pt::new(1., 2.), Some(0));
assert_eq!(pg.interiors().next().unwrap().points().count(), 4);
}
#[test]
fn append_to_out_of_range_interior_is_a_noop() {
let mut pg: Polygon<Pt> = polygon![[(0., 0.), (10., 0.), (10., 10.), (0., 10.), (0., 0.)]];
append_to_ring(&mut pg, Pt::new(1., 1.), Some(0));
assert_eq!(pg.interiors().count(), 0, "no ring created, no panic");
assert_eq!(pg.exterior().points().count(), 5);
}
}