From b7a01f5a79eca2de7b581aa192b023778b122787 Mon Sep 17 00:00:00 2001 From: Rory McCann Date: Sat, 5 Aug 2017 12:13:10 +0200 Subject: [PATCH] more --- src/algorithm/coord_change.rs | 70 +++++++++++++++++++++++++++++++++++ src/algorithm/mod.rs | 2 + 2 files changed, 72 insertions(+) create mode 100644 src/algorithm/coord_change.rs diff --git a/src/algorithm/coord_change.rs b/src/algorithm/coord_change.rs new file mode 100644 index 0000000000..8c58e15f1f --- /dev/null +++ b/src/algorithm/coord_change.rs @@ -0,0 +1,70 @@ +use num_traits::{Float}; +use types::{Point, Polygon, LineString, Line, MultiPoint, MultiPolygon, MultiLineString}; + +pub trait CoordChange { + fn coord_change(&self, func: &Fn(&(T, T)) -> (T, T)) -> Self where T: Float; + +} + +impl CoordChange for Point { + fn coord_change(&self, func: &Fn(&(T, T)) -> (T, T)) -> Point + { + let new_point = func(&(self.0.x, self.0.y)); + Point::new(new_point.0, new_point.1) + } +} + +impl CoordChange for LineString { + fn coord_change(&self, func: &Fn(&(T, T)) -> (T, T)) -> Self + { + LineString(self.0.iter().map(|p| p.coord_change(func)).collect()) + } +} + +impl CoordChange for Polygon { + fn coord_change(&self, func: &Fn(&(T, T)) -> (T, T)) -> Self + { + Polygon::new(self.exterior.coord_change(func), self.interiors.iter().map(|l| l.coord_change(func)).collect()) + } +} + + +mod test { + use super::*; + + #[test] + fn point() { + let p = Point::new(10., 10.); + let new_p = p.coord_change(&|&(x, y)| (x+10., y+100.)); + assert_eq!(new_p.x(), 20.); + assert_eq!(new_p.y(), 110.); + } + + #[test] + fn linestring() { + let line1: LineString = LineString(vec![Point::new(0., 0.), Point::new(1., 2.).into()]); + let line2 = line1.coord_change(&|&(x, y)| (x+10., y-100.)); + assert_eq!(line2.0[0], Point::new(10., -100.)); + assert_eq!(line2.0[1], Point::new(11., -98.)); + + } + + #[test] + fn polygon() { + let exterior = LineString(vec![Point::new(0., 0.), Point::new(1., 1.), + Point::new(1., 0.), Point::new(0., 0.)]); + let interiors = vec![LineString(vec![Point::new(0.1, 0.1), Point::new(0.9, 0.9), + Point::new(0.9, 0.1), Point::new(0.1, 0.1)])]; + let p = Polygon::new(exterior, interiors); + + let p2 = p.coord_change(&|&(x, y)| (x+10., y-100.)); + + let exterior2 = LineString(vec![Point::new(10., -100.), Point::new(11., -99.), + Point::new(11., -100.), Point::new(10., -100.)]); + let interiors2 = vec![LineString(vec![Point::new(10.1, -99.9), Point::new(10.9, -99.1), + Point::new(10.9, -99.9), Point::new(10.1, -99.)])]; + let expected_p2 = Polygon::new(exterior2, interiors2); + + assert_eq!(p2, expected_p2); + } +} diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs index 24e0abd592..242d8f0f3c 100644 --- a/src/algorithm/mod.rs +++ b/src/algorithm/mod.rs @@ -30,3 +30,5 @@ pub mod extremes; pub mod rotate; /// Translates a geometry along the given offsets. pub mod translate; +/// Apply a function to all coordinates +pub mod coord_change;