From 946397df58f40dae5d5b285c87a6e56ec6ed80a7 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 11 Dec 2020 15:58:17 +0000 Subject: [PATCH 01/18] Added num_coords() method to MultiPoint. To Point, Line, LineString and MultiPoint test helpers and associated tests were added to assert that two structs were relatively equal. That is identical within the limits of numerical rounding accuracy. --- geo-types/src/line.rs | 131 ++++++++++++++++++++++++++++++++++- geo-types/src/line_string.rs | 116 +++++++++++++++++++++++++++++++ geo-types/src/multi_point.rs | 106 ++++++++++++++++++++++++++++ geo-types/src/point.rs | 127 +++++++++++++++++++++++++++++++++ 4 files changed, 479 insertions(+), 1 deletion(-) diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index a5815db84..4dfa20836 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -1,5 +1,10 @@ use crate::{Coordinate, CoordinateType, Point}; - +#[cfg(test)] +use approx::AbsDiffEq; +#[cfg(test)] +use approx::RelativeEq; +#[cfg(test)] +use num_traits::Float; /// A line segment made up of exactly two /// [`Coordinate`s](struct.Coordinate.html). /// @@ -165,6 +170,49 @@ impl From<[(T, T); 2]> for Line { } } +#[cfg(test)] +impl RelativeEq for Line +where + T: CoordinateType + Float + AbsDiffEq, +{ + + #[inline] + fn default_max_relative() -> Self::Epsilon { + T::epsilon() + } + + #[inline] + fn relative_eq( + &self, + other: &Line, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon, + ) -> bool { + self.start_point() + .relative_eq(&other.start_point(), epsilon, max_relative) + && self + .end_point() + .relative_eq(&other.end_point(), epsilon, max_relative) + } +} + +#[cfg(test)] +impl AbsDiffEq for Line { + type Epsilon = T; + + #[inline] + fn default_epsilon() -> Self::Epsilon { + T::epsilon() + } + + #[inline] + fn abs_diff_eq(&self, other: &Line, epsilon: Self::Epsilon) -> bool { + self.start_point() + .abs_diff_eq(&other.start_point(), epsilon) + && self.end_point().abs_diff_eq(&other.end_point(), epsilon) + } +} + #[cfg(feature = "rstar")] impl ::rstar::RTreeObject for Line where @@ -188,3 +236,84 @@ where d.powi(2) } } + +#[cfg(test)] +mod test { + use super::*; + + use super::{Coordinate, Line, Point}; + use approx::AbsDiffEq; + #[test] + fn test_abs_diff_eq() { + let delta = 1e-6; + let line = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1., y: 1. }); + let line_start_x = Line::new( + Point(Coordinate { + x: 0. + delta, + y: 0., + }), + Point(Coordinate { x: 1., y: 1. }), + ); + assert!(line.abs_diff_eq(&line_start_x, 1e-2)); + assert!(line.abs_diff_ne(&line_start_x, 1e-12)); + + let line_start_y = Line::new( + Coordinate { + x: 0., + y: 0. + delta, + }, + Coordinate { x: 1., y: 1. }, + ); + assert!(line.abs_diff_eq(&line_start_y, 1e-2)); + assert!(line.abs_diff_ne(&line_start_y, 1e-12)); + + let line_end_x = Line::new( + Coordinate { x: 0., y: 0. }, + Coordinate { + x: 1. + delta, + y: 1., + }, + ); + + assert!(line.abs_diff_eq(&line_end_x, 1e-2)); + assert!(line.abs_diff_ne(&line_end_x, 1e-12)); + + let line_end_y = Line::new( + Coordinate { x: 0., y: 0. }, + Coordinate { + x: 1., + y: 1. + delta, + }, + ); + + assert!(line.abs_diff_eq(&line_end_y, 1e-2)); + assert!(line.abs_diff_ne(&line_end_y, 1e-12)); + } + + #[test] + fn test_relative_eq() { + let delta = 1e-6; + + let line = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1., y: 1. }); + let line_start_x = Line::new( + Point(Coordinate { + x: 0. + delta, + y: 0., + }), + Point(Coordinate { x: 1., y: 1. }), + ); + let line_start_y = Line::new( + Coordinate { + x: 0., + y: 0. + delta, + }, + Coordinate { x: 1., y: 1. }, + ); + + assert!(line.relative_eq(&line_start_x, 1e-2, 1e-2)); + assert!(line.relative_ne(&line_start_x, 1e-12, 1e-12)); + + assert!(line.relative_eq(&line_start_y, 1e-2, 1e-2)); + assert!(line.relative_ne(&line_start_y, 1e-12, 1e-12)); + } +} diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index 73a435657..909529b88 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -1,3 +1,10 @@ +#[cfg(test)] +use approx::AbsDiffEq; +#[cfg(test)] +use approx::RelativeEq; +#[cfg(test)] +use num_traits::Float; + use crate::{Coordinate, CoordinateType, Line, Point, Triangle}; use std::iter::FromIterator; use std::ops::{Index, IndexMut}; @@ -282,6 +289,61 @@ impl IndexMut for LineString { } } +#[cfg(test)] +impl RelativeEq for LineString +where + T: CoordinateType + Float + AbsDiffEq, +{ + // type Epsilon = T; + + #[inline] + fn default_max_relative() -> Self::Epsilon { + T::epsilon() + } + + #[inline] + fn relative_eq( + &self, + other: &LineString, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon, + ) -> bool { + if self.num_coords() != other.num_coords() { + return false; + } + + let points_zipper = self.points_iter().zip(other.points_iter()); + for (lhs, rhs) in points_zipper { + if lhs.relative_ne(&rhs, epsilon, max_relative) { + return false; + } + } + + true + } +} + +#[cfg(test)] +impl AbsDiffEq for LineString { + type Epsilon = T; + + #[inline] + fn default_epsilon() -> Self::Epsilon { + T::epsilon() + } + + #[inline] + fn abs_diff_eq(&self, other: &LineString, epsilon: Self::Epsilon) -> bool { + let points_zipper = self.points_iter().zip(other.points_iter()); + for (lhs, rhs) in points_zipper { + if lhs.abs_diff_ne(&rhs, epsilon) { + return false; + } + } + true + } +} + #[cfg(feature = "rstar")] impl ::rstar::RTreeObject for LineString where @@ -319,3 +381,57 @@ where } } } + +#[cfg(test)] +mod test { + use super::*; + + use approx::AbsDiffEq; + // use geo_types::LineString; + + #[test] + fn test_abs_diff_eq() { + let delta = 1e-6; + + let coords = vec![(0., 0.), (5., 0.), (10., 10.)]; + let ls: LineString = coords.into_iter().collect(); + + let coords_x = vec![(0., 0.), (5. + delta, 0.), (10., 10.)]; + let ls_x: LineString = coords_x.into_iter().collect(); + assert!(ls.abs_diff_eq(&ls_x, 1e-2)); + assert!(ls.abs_diff_ne(&ls_x, 1e-12)); + + let coords_y = vec![(0., 0.), (5., 0. + delta), (10., 10.)]; + let ls_y: LineString = coords_y.into_iter().collect(); + assert!(ls.abs_diff_eq(&ls_y, 1e-2)); + assert!(ls.abs_diff_ne(&ls_y, 1e-12)); + } + + #[test] + fn test_relative_eq() { + let delta = 1e-6; + + let coords = vec![(0., 0.), (5., 0.), (10., 10.)]; + let ls: LineString = coords.into_iter().collect(); + + let coords_x = vec![(0., 0.), (5. + delta, 0.), (10., 10.)]; + let ls_x: LineString = coords_x.into_iter().collect(); + assert!(ls.relative_eq(&ls_x, 1e-2, 1e-2)); + assert!(ls.relative_ne(&ls_x, 1e-12, 1e-12)); + + let coords_y = vec![(0., 0.), (5., 0. + delta), (10., 10.)]; + let ls_y: LineString = coords_y.into_iter().collect(); + assert!(ls.relative_eq(&ls_y, 1e-2, 1e-2)); + assert!(ls.relative_ne(&ls_y, 1e-12, 1e-12)); + + // Undersized, but otherwise equal. + let coords_x = vec![(0., 0.), (5., 0.)]; + let ls_under: LineString = coords_x.into_iter().collect(); + assert!(ls.relative_ne(&ls_under, 1., 1.)); + + // Oversized, but otherwise equal. + let coords_x = vec![(0., 0.), (5., 0.), (10., 10.), (10., 100.)]; + let ls_oversized: LineString = coords_x.into_iter().collect(); + assert!(ls.relative_ne(&ls_oversized, 1., 1.)); + } +} diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index 83d9ddf3a..c3998afcd 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -1,4 +1,11 @@ use crate::{CoordinateType, Point}; +#[cfg(test)] +use approx::AbsDiffEq; +#[cfg(test)] +use approx::RelativeEq; +#[cfg(test)] +use num_traits::float::Float; + use std::iter::FromIterator; /// A collection of [`Point`s](struct.Point.html). Can @@ -91,6 +98,78 @@ impl MultiPoint { } } +impl MultiPoint { + /// Return the number of coordinates in the `MultiPoint`. + /// + /// # Examples + /// + /// ``` + /// use geo_types::MultiPoint; + /// + /// let mut coords = vec![(0., 0.), (5., 0.), (7., 9.)]; + /// let multi_point: MultiPoint = coords.into_iter().collect(); + /// assert_eq!(3, multi_point.num_coords()); + /// ``` + pub fn num_coords(&self) -> usize { + self.0.len() + } +} + +#[cfg(test)] +impl RelativeEq for MultiPoint +where + T: CoordinateType + Float + AbsDiffEq, +{ + #[inline] + fn default_max_relative() -> Self::Epsilon { + T::epsilon() + } + + #[inline] + fn relative_eq( + &self, + other: &MultiPoint, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon, + ) -> bool { + if self.num_coords() != other.num_coords() { + return false; + } + + let mp_zipper = self.iter().zip(other.iter()); + for (lhs, rhs) in mp_zipper { + if lhs.relative_ne(&rhs, epsilon, max_relative) { + return false; + } + } + true + } +} + +#[cfg(test)] +impl AbsDiffEq for MultiPoint +where + T: CoordinateType + Float, +{ + type Epsilon = T; + + #[inline] + fn default_epsilon() -> Self::Epsilon { + T::epsilon() + } + + #[inline] + fn abs_diff_eq(&self, other: &MultiPoint, epsilon: Self::Epsilon) -> bool { + let mp_zipper = self.into_iter().zip(other.into_iter()); + for (lhs, rhs) in mp_zipper { + if lhs.abs_diff_ne(&rhs, epsilon) { + return false; + } + } + true + } +} + #[cfg(test)] mod test { use super::*; @@ -146,4 +225,31 @@ mod test { } } } + + #[test] + fn test_relative_eq() { + let delta = 1e-6; + + let multi = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10., y: 10.]]); + + let multi_x = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10.+delta, y: 10.]]); + assert!(multi.relative_eq(&multi_x, 1e-2, 1e-2)); + assert!(multi.relative_ne(&multi_x, 1e-12, 1e-12)); + + let multi_y = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10., y: 10.+delta]]); + assert!(multi.relative_eq(&multi_y, 1e-2, 1e-2)); + assert!(multi.relative_ne(&multi_y, 1e-12, 1e-12)); + + // Under-sized but otherwise equal. + let multi_undersized = MultiPoint(vec![point![x: 0., y: 0.]]); + assert!(multi.relative_ne(&multi_undersized, 1., 1.)); + + // Over-sized but otherwise equal. + let multi_oversized = MultiPoint(vec![ + point![x: 0., y: 0.], + point![x: 10., y: 10.], + point![x: 10., y:100.], + ]); + assert!(multi.relative_ne(&multi_oversized, 1., 1.)); + } } diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index 2f5010e62..85ad1ce9f 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -1,4 +1,9 @@ use crate::{Coordinate, CoordinateType}; +#[cfg(test)] +use approx::AbsDiffEq; +#[cfg(test)] +use approx::RelativeEq; + use num_traits::Float; use std::ops::{Add, Div, Mul, Neg, Sub}; @@ -409,6 +414,79 @@ where } } +#[cfg(test)] +impl RelativeEq for Point +where + T: CoordinateType + Float, +{ + // type Epsilon = T; + + #[inline] + fn default_max_relative() -> Self::Epsilon { + T::epsilon() + } + + #[inline] + fn relative_eq( + &self, + other: &Point, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon, + ) -> bool { + // Handle same infinities. + if self == other { + return true; + } + + if self.x().is_infinite() + || self.y().is_infinite() + || other.x().is_infinite() + || other.y().is_infinite() + { + return false; + } + + let diff_x = self.x() - other.x(); + let diff_y = self.y() - other.y(); + let abs_diff = (diff_x * diff_x + diff_y * diff_y).sqrt(); + println!("compute largest"); + // For when the numbers are really close together. + if abs_diff <= epsilon { + return true; + } + + let abs_self = (self.x() * self.x() + self.y() + self.y()).sqrt(); + let abs_other = (other.x() * other.x() + other.y() * other.y()).sqrt(); + + let largest = if abs_other > abs_self { + abs_other + } else { + abs_self + }; + + // Use a relative difference comparison. + abs_diff <= largest * max_relative + } +} + +#[cfg(test)] +impl AbsDiffEq for Point +where + T: CoordinateType + Float, +{ + type Epsilon = T; + + #[inline] + fn default_epsilon() -> Self::Epsilon { + T::epsilon() + } + + #[inline] + fn abs_diff_eq(&self, other: &Point, epsilon: Self::Epsilon) -> bool { + (self.x() - other.x()).abs() < epsilon && (self.y() - other.y()).abs() < epsilon + } +} + #[cfg(feature = "rstar")] // These are required for rstar RTree impl ::rstar::Point for Point @@ -438,3 +516,52 @@ where } } } + +#[cfg(test)] +mod test { + use super::*; + + use approx::AbsDiffEq; + + #[test] + fn test_abs_diff_eq() { + let delta = 1e-6; + let p = Point::new(1.0, 1.0); + + let p_x = Point::new(1.0 - delta, 1.0); + assert!(p.abs_diff_eq(&p_x, 1e-2)); + assert!(p.abs_diff_ne(&p_x, 1e-12)); + + let p_y = Point::new(1.0, 1.0 + delta); + assert!(p.abs_diff_eq(&p_y, 1e-2)); + assert!(p.abs_diff_ne(&p_y, 1e-12)); + + let p_xy = Point::new(1.0 + delta, 1.0 - delta); + assert!(p.abs_diff_eq(&p_xy, 1e-2)); + assert!(p.abs_diff_ne(&p_xy, 1e-12)); + + let p_inf = Point::new(f64::INFINITY, 1.); + assert!(p.abs_diff_ne(&p_inf, 1e-2)); + } + + #[test] + fn test_relative_eq() { + let delta = 1e-6; + let p = Point::new(1.0, 1.0); + + let p_x = Point::new(1.0 - delta, 1.0); + assert!(p.relative_eq(&p_x, 1e-2, 1e-2)); + assert!(p.relative_ne(&p_x, 1e-12, 1e-12)); + + let p_y = Point::new(1.0, 1.0 + delta); + assert!(p.relative_eq(&p_y, 1e-2, 1e-2)); + assert!(p.relative_ne(&p_y, 1e-12, 1e-12)); + + let p_xy = Point::new(1.0 + delta, 1.0 - delta); + assert!(p.relative_eq(&p_xy, 1e-2, 1e-2)); + assert!(p.relative_ne(&p_xy, 1e-12, 1e-12)); + + let p_inf = Point::new(f64::INFINITY, 1.); + assert!(p.relative_ne(&p_inf, 1e-2, 1e-2)); + } +} From 65f6100421bae9d86066b8485413dabe20e44336 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 11 Dec 2020 18:48:20 +0000 Subject: [PATCH 02/18] Removed debug. --- geo-types/src/point.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index 85ad1ce9f..a532df70f 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -449,7 +449,7 @@ where let diff_x = self.x() - other.x(); let diff_y = self.y() - other.y(); let abs_diff = (diff_x * diff_x + diff_y * diff_y).sqrt(); - println!("compute largest"); + // For when the numbers are really close together. if abs_diff <= epsilon { return true; From 4ab3599eb4ca4dfb309b6ff003d5303115835ca3 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 16 Dec 2020 08:30:40 +0000 Subject: [PATCH 03/18] Removed commented out code. --- geo-types/src/line_string.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index 909529b88..9dc80e865 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -294,8 +294,6 @@ impl RelativeEq for LineString where T: CoordinateType + Float + AbsDiffEq, { - // type Epsilon = T; - #[inline] fn default_max_relative() -> Self::Epsilon { T::epsilon() From daf5570a9ae3b0bc24c073cf7aba9d77be6d0c30 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 16 Dec 2020 08:45:07 +0000 Subject: [PATCH 04/18] Removed commented out code. --- geo-types/src/point.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index a532df70f..d74acc738 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -419,8 +419,6 @@ impl RelativeEq for Point where T: CoordinateType + Float, { - // type Epsilon = T; - #[inline] fn default_max_relative() -> Self::Epsilon { T::epsilon() From 719c32c8562a91f9b35fc8efc118e74ef4b16f4c Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 16 Dec 2020 09:15:43 +0000 Subject: [PATCH 05/18] line_string.rs abs_diff_eq: simplify by using .all() --- geo-types/src/line_string.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index 9dc80e865..b9a6cd817 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -332,13 +332,8 @@ impl AbsDiffEq for LineString { #[inline] fn abs_diff_eq(&self, other: &LineString, epsilon: Self::Epsilon) -> bool { - let points_zipper = self.points_iter().zip(other.points_iter()); - for (lhs, rhs) in points_zipper { - if lhs.abs_diff_ne(&rhs, epsilon) { - return false; - } - } - true + let mut points_zipper = self.points_iter().zip(other.points_iter()); + points_zipper.all(|(lhs, rhs)| lhs.abs_diff_eq(&rhs, epsilon)) } } From 6c23693cebc519b2ef502ec793bf8ffd03850abf Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 16 Dec 2020 09:34:35 +0000 Subject: [PATCH 06/18] multi_point.rs: Simplify using .all() --- geo-types/src/multi_point.rs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index c3998afcd..68f3d2181 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -136,13 +136,8 @@ where return false; } - let mp_zipper = self.iter().zip(other.iter()); - for (lhs, rhs) in mp_zipper { - if lhs.relative_ne(&rhs, epsilon, max_relative) { - return false; - } - } - true + let mut mp_zipper = self.iter().zip(other.iter()); + mp_zipper.all(|(lhs, rhs)| lhs.relative_eq(&rhs, epsilon, max_relative)) } } @@ -160,13 +155,8 @@ where #[inline] fn abs_diff_eq(&self, other: &MultiPoint, epsilon: Self::Epsilon) -> bool { - let mp_zipper = self.into_iter().zip(other.into_iter()); - for (lhs, rhs) in mp_zipper { - if lhs.abs_diff_ne(&rhs, epsilon) { - return false; - } - } - true + let mut mp_zipper = self.into_iter().zip(other.into_iter()); + mp_zipper.all(|(lhs, rhs)| lhs.abs_diff_eq(&rhs, epsilon)) } } From 3eaec497e76653e6836d4174210f48a86bdfa7d4 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 16 Dec 2020 09:58:54 +0000 Subject: [PATCH 07/18] multi_point.rs abs_diff_eq() now handles unequal sizes --- geo-types/src/multi_point.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index 68f3d2181..133eb0be4 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -155,6 +155,10 @@ where #[inline] fn abs_diff_eq(&self, other: &MultiPoint, epsilon: Self::Epsilon) -> bool { + if self.num_coords() != other.num_coords() { + return false; + } + let mut mp_zipper = self.into_iter().zip(other.into_iter()); mp_zipper.all(|(lhs, rhs)| lhs.abs_diff_eq(&rhs, epsilon)) } @@ -242,4 +246,32 @@ mod test { ]); assert!(multi.relative_ne(&multi_oversized, 1., 1.)); } + + #[test] + fn test_abs_diff_eq() { + let delta = 1e-6; + + let multi = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10., y: 10.]]); + + let multi_x = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10.+delta, y: 10.]]); + assert!(multi.abs_diff_eq(&multi_x, 1e-2)); + assert!(multi.abs_diff_ne(&multi_x, 1e-12)); + + let multi_y = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10., y: 10.+delta]]); + assert!(multi.abs_diff_eq(&multi_y, 1e-2)); + assert!(multi.abs_diff_ne(&multi_y, 1e-12)); + + // Under-sized but otherwise equal. + let multi_undersized = MultiPoint(vec![point![x: 0., y: 0.]]); + assert!(multi.abs_diff_ne(&multi_undersized, 1.)); + + // Over-sized but otherwise equal. + let multi_oversized = MultiPoint(vec![ + point![x: 0., y: 0.], + point![x: 10., y: 10.], + point![x: 10., y:100.], + ]); + assert!(multi.abs_diff_ne(&multi_oversized, 1.)); + } + } From 1dca7196297c122c827c1835204ae68522efad7c Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 16 Dec 2020 20:26:21 +0000 Subject: [PATCH 08/18] point.rs Simplify RelativeEq for Point --- geo-types/src/coordinate.rs | 4 ++++ geo-types/src/line.rs | 10 +++++----- geo-types/src/line_string.rs | 2 +- geo-types/src/multi_point.rs | 2 +- geo-types/src/point.rs | 36 ++---------------------------------- 5 files changed, 13 insertions(+), 41 deletions(-) diff --git a/geo-types/src/coordinate.rs b/geo-types/src/coordinate.rs index 9e1de8b99..7fabb1ecd 100644 --- a/geo-types/src/coordinate.rs +++ b/geo-types/src/coordinate.rs @@ -247,10 +247,12 @@ where { type Epsilon = T::Epsilon; + #[inline] fn default_epsilon() -> T::Epsilon { T::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool { T::abs_diff_eq(&self.x, &other.x, epsilon) && T::abs_diff_eq(&self.y, &other.y, epsilon) } @@ -261,10 +263,12 @@ impl RelativeEq for Coordinate where T::Epsilon: Copy, { + #[inline] fn default_max_relative() -> T::Epsilon { T::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool { T::relative_eq(&self.x, &other.x, epsilon, max_relative) && T::relative_eq(&self.y, &other.y, epsilon, max_relative) diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index 4dfa20836..85b53b44e 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -173,7 +173,7 @@ impl From<[(T, T); 2]> for Line { #[cfg(test)] impl RelativeEq for Line where - T: CoordinateType + Float + AbsDiffEq, + T: AbsDiffEq + CoordinateType + Float + RelativeEq { #[inline] @@ -188,11 +188,11 @@ where epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { - self.start_point() - .relative_eq(&other.start_point(), epsilon, max_relative) + self.start + .relative_eq(&other.start, epsilon, max_relative) && self - .end_point() - .relative_eq(&other.end_point(), epsilon, max_relative) + .end + .relative_eq(&other.end, epsilon, max_relative) } } diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index b9a6cd817..8c89f920d 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -292,7 +292,7 @@ impl IndexMut for LineString { #[cfg(test)] impl RelativeEq for LineString where - T: CoordinateType + Float + AbsDiffEq, + T: AbsDiffEq + CoordinateType + Float + RelativeEq { #[inline] fn default_max_relative() -> Self::Epsilon { diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index 133eb0be4..0401d86a8 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -118,7 +118,7 @@ impl MultiPoint { #[cfg(test)] impl RelativeEq for MultiPoint where - T: CoordinateType + Float + AbsDiffEq, + T: AbsDiffEq + CoordinateType + Float + RelativeEq { #[inline] fn default_max_relative() -> Self::Epsilon { diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index d74acc738..6a8a75630 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -417,7 +417,7 @@ where #[cfg(test)] impl RelativeEq for Point where - T: CoordinateType + Float, + T: AbsDiffEq + CoordinateType + Float + RelativeEq { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -431,39 +431,7 @@ where epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { - // Handle same infinities. - if self == other { - return true; - } - - if self.x().is_infinite() - || self.y().is_infinite() - || other.x().is_infinite() - || other.y().is_infinite() - { - return false; - } - - let diff_x = self.x() - other.x(); - let diff_y = self.y() - other.y(); - let abs_diff = (diff_x * diff_x + diff_y * diff_y).sqrt(); - - // For when the numbers are really close together. - if abs_diff <= epsilon { - return true; - } - - let abs_self = (self.x() * self.x() + self.y() + self.y()).sqrt(); - let abs_other = (other.x() * other.x() + other.y() * other.y()).sqrt(); - - let largest = if abs_other > abs_self { - abs_other - } else { - abs_self - }; - - // Use a relative difference comparison. - abs_diff <= largest * max_relative + self.0.relative_eq(&other.0, epsilon, max_relative) } } From edb4ff1a308bfa565c1bd6af57db639eda65ba4c Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 16 Dec 2020 20:33:42 +0000 Subject: [PATCH 09/18] lines.rs Simplify "AbsDiffEq for Line" to operate of coords not points. --- geo-types/src/line.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index 85b53b44e..1f1eb8e00 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -197,7 +197,7 @@ where } #[cfg(test)] -impl AbsDiffEq for Line { +impl + CoordinateType + Float> AbsDiffEq for Line { type Epsilon = T; #[inline] @@ -207,9 +207,9 @@ impl AbsDiffEq for Line { #[inline] fn abs_diff_eq(&self, other: &Line, epsilon: Self::Epsilon) -> bool { - self.start_point() - .abs_diff_eq(&other.start_point(), epsilon) - && self.end_point().abs_diff_eq(&other.end_point(), epsilon) + self.start + .abs_diff_eq(&other.start, epsilon) + && self.end.abs_diff_eq(&other.end, epsilon) } } From 5aa011c648e67cc8cafef37f9ce78a1fad0dd30c Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 16 Dec 2020 20:52:29 +0000 Subject: [PATCH 10/18] line_string.rs - abs_diff_eq() Now rejects line_strings with unequal lengths. (with tests) --- geo-types/src/line_string.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index 8c89f920d..edfa71d4d 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -299,7 +299,6 @@ where T::epsilon() } - #[inline] fn relative_eq( &self, other: &LineString, @@ -330,8 +329,10 @@ impl AbsDiffEq for LineString { T::epsilon() } - #[inline] fn abs_diff_eq(&self, other: &LineString, epsilon: Self::Epsilon) -> bool { + if self.num_coords() != other.num_coords() { + return false; + } let mut points_zipper = self.points_iter().zip(other.points_iter()); points_zipper.all(|(lhs, rhs)| lhs.abs_diff_eq(&rhs, epsilon)) } @@ -398,6 +399,16 @@ mod test { let ls_y: LineString = coords_y.into_iter().collect(); assert!(ls.abs_diff_eq(&ls_y, 1e-2)); assert!(ls.abs_diff_ne(&ls_y, 1e-12)); + + // Undersized, but otherwise equal. + let coords_x = vec![(0., 0.), (5., 0.)]; + let ls_under: LineString = coords_x.into_iter().collect(); + assert!(ls.abs_diff_ne(&ls_under, 1.)); + + // Oversized, but otherwise equal. + let coords_x = vec![(0., 0.), (5., 0.), (10., 10.), (10., 100.)]; + let ls_oversized: LineString = coords_x.into_iter().collect(); + assert!(ls.abs_diff_ne(&ls_oversized, 1.)); } #[test] From efb112a657f2959d0b7c017ed9b2a78ef17f02a0 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 17 Dec 2020 10:59:12 +0000 Subject: [PATCH 11/18] Removed type constraint on RelativeEq and AbsDiffEq that the type must be Float. Also AbsDiffEq for Point now uses AbsDiffEq in Coords. --- geo-types/src/line.rs | 15 +++++++-------- geo-types/src/line_string.rs | 14 ++++++-------- geo-types/src/multi_point.rs | 15 +++++++-------- geo-types/src/point.rs | 17 +++++++++-------- 4 files changed, 29 insertions(+), 32 deletions(-) diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index 1f1eb8e00..370b9acc0 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -3,8 +3,7 @@ use crate::{Coordinate, CoordinateType, Point}; use approx::AbsDiffEq; #[cfg(test)] use approx::RelativeEq; -#[cfg(test)] -use num_traits::Float; + /// A line segment made up of exactly two /// [`Coordinate`s](struct.Coordinate.html). /// @@ -173,18 +172,18 @@ impl From<[(T, T); 2]> for Line { #[cfg(test)] impl RelativeEq for Line where - T: AbsDiffEq + CoordinateType + Float + RelativeEq + T: AbsDiffEq + CoordinateType + RelativeEq { #[inline] fn default_max_relative() -> Self::Epsilon { - T::epsilon() + T::default_max_relative() } #[inline] fn relative_eq( &self, - other: &Line, + other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { @@ -197,16 +196,16 @@ where } #[cfg(test)] -impl + CoordinateType + Float> AbsDiffEq for Line { +impl + CoordinateType> AbsDiffEq for Line { type Epsilon = T; #[inline] fn default_epsilon() -> Self::Epsilon { - T::epsilon() + T::default_epsilon() } #[inline] - fn abs_diff_eq(&self, other: &Line, epsilon: Self::Epsilon) -> bool { + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { self.start .abs_diff_eq(&other.start, epsilon) && self.end.abs_diff_eq(&other.end, epsilon) diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index edfa71d4d..009064495 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -2,8 +2,6 @@ use approx::AbsDiffEq; #[cfg(test)] use approx::RelativeEq; -#[cfg(test)] -use num_traits::Float; use crate::{Coordinate, CoordinateType, Line, Point, Triangle}; use std::iter::FromIterator; @@ -292,16 +290,16 @@ impl IndexMut for LineString { #[cfg(test)] impl RelativeEq for LineString where - T: AbsDiffEq + CoordinateType + Float + RelativeEq + T: AbsDiffEq + CoordinateType + RelativeEq { #[inline] fn default_max_relative() -> Self::Epsilon { - T::epsilon() + T::default_max_relative() } fn relative_eq( &self, - other: &LineString, + other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { @@ -321,15 +319,15 @@ where } #[cfg(test)] -impl AbsDiffEq for LineString { +impl + CoordinateType > AbsDiffEq for LineString { type Epsilon = T; #[inline] fn default_epsilon() -> Self::Epsilon { - T::epsilon() + T::default_epsilon() } - fn abs_diff_eq(&self, other: &LineString, epsilon: Self::Epsilon) -> bool { + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { if self.num_coords() != other.num_coords() { return false; } diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index 0401d86a8..dd10c3747 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -3,8 +3,6 @@ use crate::{CoordinateType, Point}; use approx::AbsDiffEq; #[cfg(test)] use approx::RelativeEq; -#[cfg(test)] -use num_traits::float::Float; use std::iter::FromIterator; @@ -118,17 +116,17 @@ impl MultiPoint { #[cfg(test)] impl RelativeEq for MultiPoint where - T: AbsDiffEq + CoordinateType + Float + RelativeEq + T: AbsDiffEq + CoordinateType + RelativeEq { #[inline] fn default_max_relative() -> Self::Epsilon { - T::epsilon() + T::default_max_relative() } #[inline] fn relative_eq( &self, - other: &MultiPoint, + other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { @@ -144,17 +142,18 @@ where #[cfg(test)] impl AbsDiffEq for MultiPoint where - T: CoordinateType + Float, + T: AbsDiffEq + CoordinateType, + T::Epsilon: Copy, { type Epsilon = T; #[inline] fn default_epsilon() -> Self::Epsilon { - T::epsilon() + T::default_epsilon() } #[inline] - fn abs_diff_eq(&self, other: &MultiPoint, epsilon: Self::Epsilon) -> bool { + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { if self.num_coords() != other.num_coords() { return false; } diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index 6a8a75630..ca559c5b1 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -417,17 +417,17 @@ where #[cfg(test)] impl RelativeEq for Point where - T: AbsDiffEq + CoordinateType + Float + RelativeEq + T: AbsDiffEq + CoordinateType + RelativeEq { #[inline] fn default_max_relative() -> Self::Epsilon { - T::epsilon() + T::default_max_relative() } #[inline] fn relative_eq( &self, - other: &Point, + other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { @@ -438,18 +438,19 @@ where #[cfg(test)] impl AbsDiffEq for Point where - T: CoordinateType + Float, + T: AbsDiffEq + CoordinateType, + T::Epsilon: Copy { - type Epsilon = T; + type Epsilon = T::Epsilon; #[inline] fn default_epsilon() -> Self::Epsilon { - T::epsilon() + T::default_epsilon() } #[inline] - fn abs_diff_eq(&self, other: &Point, epsilon: Self::Epsilon) -> bool { - (self.x() - other.x()).abs() < epsilon && (self.y() - other.y()).abs() < epsilon + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.0.abs_diff_eq(&other.0, epsilon) } } From 8ba2b0b858b0885dd8d82595717391d3cf8cb846 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 17 Dec 2020 12:12:13 +0000 Subject: [PATCH 12/18] ran cargo fmt --- geo-types/src/line.rs | 14 ++++---------- geo-types/src/line_string.rs | 4 ++-- geo-types/src/multi_point.rs | 3 +-- geo-types/src/point.rs | 4 ++-- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index 370b9acc0..378259692 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -172,9 +172,8 @@ impl From<[(T, T); 2]> for Line { #[cfg(test)] impl RelativeEq for Line where - T: AbsDiffEq + CoordinateType + RelativeEq + T: AbsDiffEq + CoordinateType + RelativeEq, { - #[inline] fn default_max_relative() -> Self::Epsilon { T::default_max_relative() @@ -187,11 +186,8 @@ where epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { - self.start - .relative_eq(&other.start, epsilon, max_relative) - && self - .end - .relative_eq(&other.end, epsilon, max_relative) + self.start.relative_eq(&other.start, epsilon, max_relative) + && self.end.relative_eq(&other.end, epsilon, max_relative) } } @@ -206,9 +202,7 @@ impl + CoordinateType> AbsDiffEq for Line { #[inline] fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { - self.start - .abs_diff_eq(&other.start, epsilon) - && self.end.abs_diff_eq(&other.end, epsilon) + self.start.abs_diff_eq(&other.start, epsilon) && self.end.abs_diff_eq(&other.end, epsilon) } } diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index 009064495..86b11477e 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -290,7 +290,7 @@ impl IndexMut for LineString { #[cfg(test)] impl RelativeEq for LineString where - T: AbsDiffEq + CoordinateType + RelativeEq + T: AbsDiffEq + CoordinateType + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -319,7 +319,7 @@ where } #[cfg(test)] -impl + CoordinateType > AbsDiffEq for LineString { +impl + CoordinateType> AbsDiffEq for LineString { type Epsilon = T; #[inline] diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index dd10c3747..e87693da8 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -116,7 +116,7 @@ impl MultiPoint { #[cfg(test)] impl RelativeEq for MultiPoint where - T: AbsDiffEq + CoordinateType + RelativeEq + T: AbsDiffEq + CoordinateType + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -272,5 +272,4 @@ mod test { ]); assert!(multi.abs_diff_ne(&multi_oversized, 1.)); } - } diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index ca559c5b1..8a32e05ae 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -417,7 +417,7 @@ where #[cfg(test)] impl RelativeEq for Point where - T: AbsDiffEq + CoordinateType + RelativeEq + T: AbsDiffEq + CoordinateType + RelativeEq, { #[inline] fn default_max_relative() -> Self::Epsilon { @@ -439,7 +439,7 @@ where impl AbsDiffEq for Point where T: AbsDiffEq + CoordinateType, - T::Epsilon: Copy + T::Epsilon: Copy, { type Epsilon = T::Epsilon; From 26a6a2dddda0816a095d80d78aacf6be1cffa4a0 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 20 Dec 2020 11:03:14 +0000 Subject: [PATCH 13/18] Added new feature relative_eq --- geo-types/Cargo.toml | 3 +++ geo-types/src/coordinate.rs | 11 ++++++---- geo-types/src/line.rs | 35 ++++++++++++++++++++++++------ geo-types/src/line_string.rs | 42 ++++++++++++++++++++++++++++++------ geo-types/src/multi_point.rs | 34 +++++++++++++++++++++++++---- geo-types/src/point.rs | 33 +++++++++++++++++++++++----- geo/Cargo.toml | 5 +++-- 7 files changed, 135 insertions(+), 28 deletions(-) diff --git a/geo-types/Cargo.toml b/geo-types/Cargo.toml index a03e9271b..325c02894 100644 --- a/geo-types/Cargo.toml +++ b/geo-types/Cargo.toml @@ -10,6 +10,9 @@ keywords = ["gis", "geo", "geography", "geospatial"] description = "Geospatial primitive data types" edition = "2018" +[features] +relative_eq = [] + [dependencies] approx = "0.4.0" num-traits = "0.2" diff --git a/geo-types/src/coordinate.rs b/geo-types/src/coordinate.rs index 7fabb1ecd..aa20cc656 100644 --- a/geo-types/src/coordinate.rs +++ b/geo-types/src/coordinate.rs @@ -1,7 +1,10 @@ use crate::{CoordinateType, Point}; -#[cfg(test)] -use approx::{AbsDiffEq, RelativeEq, UlpsEq}; +#[cfg(any(test, feature = "relative_eq"))] +use approx::{AbsDiffEq, RelativeEq}; + +#[cfg(test)] +use approx::UlpsEq; /// A lightweight struct used to store coordinates on the 2-dimensional /// Cartesian plane. /// @@ -240,7 +243,7 @@ impl Zero for Coordinate { } } -#[cfg(test)] +#[cfg(any(test, feature = "relative_eq"))] impl AbsDiffEq for Coordinate where T::Epsilon: Copy, @@ -258,7 +261,7 @@ where } } -#[cfg(test)] +#[cfg(any(test, feature = "relative_eq"))] impl RelativeEq for Coordinate where T::Epsilon: Copy, diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index 378259692..90a49a02c 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -1,7 +1,7 @@ use crate::{Coordinate, CoordinateType, Point}; -#[cfg(test)] +#[cfg(any(feature = "relative_eq", test))] use approx::AbsDiffEq; -#[cfg(test)] +#[cfg(any(feature = "relative_eq", test))] use approx::RelativeEq; /// A line segment made up of exactly two @@ -168,8 +168,7 @@ impl From<[(T, T); 2]> for Line { Line::new(coord[0], coord[1]) } } - -#[cfg(test)] +#[cfg(feature = "relative_eq")] impl RelativeEq for Line where T: AbsDiffEq + CoordinateType + RelativeEq, @@ -179,6 +178,18 @@ where T::default_max_relative() } + /// Equality assertion within a relative limit. + /// + /// # Examples + /// + /// ``` + /// use geo_types::{Coordinate, Line}; + /// + /// let a = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1., y: 1. }); + /// let b = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1.001, y: 1. }); + /// + /// approx::assert_relative_eq!(a, b, max_relative=0.1) + /// ``` #[inline] fn relative_eq( &self, @@ -191,7 +202,7 @@ where } } -#[cfg(test)] +#[cfg(feature = "relative_eq")] impl + CoordinateType> AbsDiffEq for Line { type Epsilon = T; @@ -200,6 +211,18 @@ impl + CoordinateType> AbsDiffEq for Line { T::default_epsilon() } + /// Equality assertion within a relative limit. + /// + /// # Examples + /// + /// ``` + /// use geo_types::{Coordinate, Line}; + /// + /// let a = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1., y: 1. }); + /// let b = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1.001, y: 1. }); + /// + /// approx::assert_relative_eq!(a, b, epsilon=0.1) + /// ``` #[inline] fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { self.start.abs_diff_eq(&other.start, epsilon) && self.end.abs_diff_eq(&other.end, epsilon) @@ -234,8 +257,6 @@ where mod test { use super::*; - use super::{Coordinate, Line, Point}; - use approx::AbsDiffEq; #[test] fn test_abs_diff_eq() { let delta = 1e-6; diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index 86b11477e..ca166a14b 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -1,6 +1,6 @@ -#[cfg(test)] +#[cfg(feature = "relative_eq")] use approx::AbsDiffEq; -#[cfg(test)] +#[cfg(feature = "relative_eq")] use approx::RelativeEq; use crate::{Coordinate, CoordinateType, Line, Point, Triangle}; @@ -287,7 +287,7 @@ impl IndexMut for LineString { } } -#[cfg(test)] +#[cfg(feature = "relative_eq")] impl RelativeEq for LineString where T: AbsDiffEq + CoordinateType + RelativeEq, @@ -297,6 +297,22 @@ where T::default_max_relative() } + /// Equality assertion within a relative limit. + /// + /// # Examples + /// + /// ``` + /// use geo_types::LineString; + /// + /// let mut coords_a = vec![(0., 0.), (5., 0.), (7., 9.)]; + /// let a: LineString = coords_a.into_iter().collect(); + /// + /// let mut coords_b = vec![(0., 0.), (5., 0.), (7.001, 9.)]; + /// let b: LineString = coords_b.into_iter().collect(); + /// + /// approx::assert_relative_eq!(a, b, max_relative=0.1) + /// ``` + /// fn relative_eq( &self, other: &Self, @@ -318,7 +334,7 @@ where } } -#[cfg(test)] +#[cfg(feature = "relative_eq")] impl + CoordinateType> AbsDiffEq for LineString { type Epsilon = T; @@ -327,6 +343,21 @@ impl + CoordinateType> AbsDiffEq for LineString { T::default_epsilon() } + /// Equality assertion within a relative limit. + /// + /// # Examples + /// + /// ``` + /// use geo_types::LineString; + /// + /// let mut coords_a = vec![(0., 0.), (5., 0.), (7., 9.)]; + /// let a: LineString = coords_a.into_iter().collect(); + /// + /// let mut coords_b = vec![(0., 0.), (5., 0.), (7.001, 9.)]; + /// let b: LineString = coords_b.into_iter().collect(); + /// + /// approx::assert_relative_eq!(a, b, epsilon=0.1) + /// ``` fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { if self.num_coords() != other.num_coords() { return false; @@ -374,12 +405,11 @@ where } } -#[cfg(test)] +#[cfg(all(test, feature = "relative_eq"))] mod test { use super::*; use approx::AbsDiffEq; - // use geo_types::LineString; #[test] fn test_abs_diff_eq() { diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index e87693da8..ca2df25b3 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -1,7 +1,7 @@ use crate::{CoordinateType, Point}; -#[cfg(test)] +#[cfg(any(feature = "relative_eq"))] use approx::AbsDiffEq; -#[cfg(test)] +#[cfg(feature = "relative_eq")] use approx::RelativeEq; use std::iter::FromIterator; @@ -113,7 +113,7 @@ impl MultiPoint { } } -#[cfg(test)] +#[cfg(feature = "relative_eq")] impl RelativeEq for MultiPoint where T: AbsDiffEq + CoordinateType + RelativeEq, @@ -123,6 +123,19 @@ where T::default_max_relative() } + /// Equality assertion within a relative limit. + /// + /// # Examples + /// + /// ``` + /// use geo_types::MultiPoint; + /// use geo_types::point; + /// + /// let a = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10., y: 10.]]); + /// let b = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10.001, y: 10.]]); + /// + /// approx::assert_relative_eq!(a, b, max_relative=0.1) + /// ``` #[inline] fn relative_eq( &self, @@ -139,7 +152,7 @@ where } } -#[cfg(test)] +#[cfg(feature = "relative_eq")] impl AbsDiffEq for MultiPoint where T: AbsDiffEq + CoordinateType, @@ -152,6 +165,19 @@ where T::default_epsilon() } + /// Equality assertion within a absolute limit. + /// + /// # Examples + /// + /// ``` + /// use geo_types::MultiPoint; + /// use geo_types::point; + /// + /// let a = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10., y: 10.]]); + /// let b = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10.001, y: 10.]]); + /// + /// approx::assert_relative_eq!(a, b, epsilon=0.1) + /// ``` #[inline] fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { if self.num_coords() != other.num_coords() { diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index 8a32e05ae..bb6df066f 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -1,7 +1,7 @@ use crate::{Coordinate, CoordinateType}; -#[cfg(test)] + use approx::AbsDiffEq; -#[cfg(test)] +#[cfg(feature = "relative_eq")] use approx::RelativeEq; use num_traits::Float; @@ -414,7 +414,7 @@ where } } -#[cfg(test)] +#[cfg(feature = "relative_eq")] impl RelativeEq for Point where T: AbsDiffEq + CoordinateType + RelativeEq, @@ -424,6 +424,18 @@ where T::default_max_relative() } + /// Equality assertion within a relative limit. + /// + /// # Examples + /// + /// ``` + /// use geo_types::Point; + /// + /// let a = Point::new(2.0, 3.0); + /// let b = Point::new(2.0, 3.01); + /// + /// approx::assert_relative_eq!(a, b, max_relative=0.1) + /// ``` #[inline] fn relative_eq( &self, @@ -434,8 +446,7 @@ where self.0.relative_eq(&other.0, epsilon, max_relative) } } - -#[cfg(test)] +#[cfg(feature = "relative_eq")] impl AbsDiffEq for Point where T: AbsDiffEq + CoordinateType, @@ -448,6 +459,18 @@ where T::default_epsilon() } + /// Equality assertion within a absolute limit. + /// + /// # Examples + /// + /// ```relative_eq + /// use geo_types::Point; + /// + /// let a = Point::new(2.0, 3.0); + /// let b = Point::new(2.0, 3.0000001); + /// + /// approx::assert_relative_eq!(a, b, epsilon=0.1) + /// ``` #[inline] fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, epsilon) diff --git a/geo/Cargo.toml b/geo/Cargo.toml index f35dd810f..96a5c5862 100644 --- a/geo/Cargo.toml +++ b/geo/Cargo.toml @@ -22,8 +22,8 @@ geographiclib-rs = { version = "0.2" } proj = { version = "0.20.3", optional = true } -geo-types = { version = "0.6.2", path = "../geo-types", features = ["rstar"] } - +geo-types = { version = "0.6.2", path = "../geo-types", features = ["relative_eq", "rstar"] } +approx= { version = "0.4.0", optional = true } robust = { version = "0.2.2" } [features] @@ -31,6 +31,7 @@ default = [] use-proj = ["proj"] proj-network = ["use-proj", "proj/network"] use-serde = ["serde", "geo-types/serde"] +relative_eq = ["approx"] [dev-dependencies] approx = "0.4.0" From c21a5521e23856205b968d0fee3d2bff5e49c1d6 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 22 Dec 2020 13:04:02 +0000 Subject: [PATCH 14/18] After rebase, drop the use of the deprecated num_coords() method. --- geo-types/src/line_string.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index ca166a14b..38f6647e7 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -319,7 +319,7 @@ where epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { - if self.num_coords() != other.num_coords() { + if self.0.len() != other.0.len() { return false; } @@ -359,7 +359,7 @@ impl + CoordinateType> AbsDiffEq for LineString { /// approx::assert_relative_eq!(a, b, epsilon=0.1) /// ``` fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { - if self.num_coords() != other.num_coords() { + if self.0.len() != other.0.len() { return false; } let mut points_zipper = self.points_iter().zip(other.points_iter()); From bfb2746ac63b843c27a33f045868b244a50ce1b7 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 24 Dec 2020 11:36:29 +0000 Subject: [PATCH 15/18] Fixed dev-dependency issue. --- geo-types/src/coordinate.rs | 6 +++--- geo-types/src/line.rs | 4 ++-- geo-types/src/line_string.rs | 2 +- geo-types/src/multi_point.rs | 2 +- geo/Cargo.toml | 8 ++++---- geo/src/algorithm/rotate.rs | 12 +++++------- 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/geo-types/src/coordinate.rs b/geo-types/src/coordinate.rs index aa20cc656..450e3961c 100644 --- a/geo-types/src/coordinate.rs +++ b/geo-types/src/coordinate.rs @@ -1,6 +1,6 @@ use crate::{CoordinateType, Point}; -#[cfg(any(test, feature = "relative_eq"))] +#[cfg(any(feature = "relative_eq", test))] use approx::{AbsDiffEq, RelativeEq}; #[cfg(test)] @@ -243,7 +243,7 @@ impl Zero for Coordinate { } } -#[cfg(any(test, feature = "relative_eq"))] +#[cfg(feature = "relative_eq")] impl AbsDiffEq for Coordinate where T::Epsilon: Copy, @@ -261,7 +261,7 @@ where } } -#[cfg(any(test, feature = "relative_eq"))] +#[cfg(feature = "relative_eq")] impl RelativeEq for Coordinate where T::Epsilon: Copy, diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index 90a49a02c..a0a6f3a59 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -1,7 +1,7 @@ use crate::{Coordinate, CoordinateType, Point}; -#[cfg(any(feature = "relative_eq", test))] +#[cfg(feature = "relative_eq")] use approx::AbsDiffEq; -#[cfg(any(feature = "relative_eq", test))] +#[cfg(feature = "relative_eq")] use approx::RelativeEq; /// A line segment made up of exactly two diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index 38f6647e7..f24541cdb 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -405,7 +405,7 @@ where } } -#[cfg(all(test, feature = "relative_eq"))] +#[cfg(test)] mod test { use super::*; diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index ca2df25b3..1a3a978fe 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -1,5 +1,5 @@ use crate::{CoordinateType, Point}; -#[cfg(any(feature = "relative_eq"))] +#[cfg(feature = "relative_eq")] use approx::AbsDiffEq; #[cfg(feature = "relative_eq")] use approx::RelativeEq; diff --git a/geo/Cargo.toml b/geo/Cargo.toml index 96a5c5862..12097a746 100644 --- a/geo/Cargo.toml +++ b/geo/Cargo.toml @@ -22,20 +22,20 @@ geographiclib-rs = { version = "0.2" } proj = { version = "0.20.3", optional = true } -geo-types = { version = "0.6.2", path = "../geo-types", features = ["relative_eq", "rstar"] } -approx= { version = "0.4.0", optional = true } +geo-types = { version = "0.6.2", optional = true, path = "../geo-types", features = ["rstar"] } + robust = { version = "0.2.2" } [features] -default = [] +default = ["geo-types"] use-proj = ["proj"] proj-network = ["use-proj", "proj/network"] use-serde = ["serde", "geo-types/serde"] -relative_eq = ["approx"] [dev-dependencies] approx = "0.4.0" criterion = { version = "0.3" } +geo-types = { version = "0.6.2", path = "../geo-types", features = ["relative_eq", "rstar"] } rand = "0.8.0" [[bench]] diff --git a/geo/src/algorithm/rotate.rs b/geo/src/algorithm/rotate.rs index 9fccef44c..97013234a 100644 --- a/geo/src/algorithm/rotate.rs +++ b/geo/src/algorithm/rotate.rs @@ -221,6 +221,7 @@ where mod test { use super::*; use crate::{line_string, point, polygon, Coordinate, Point}; + use approx::assert_relative_eq; #[test] fn test_rotate_around_point() { @@ -334,16 +335,13 @@ mod test { #[test] fn test_rotate_line() { let line0 = Line::from([(0., 0.), (0., 2.)]); - let line1 = Line::from([(1., 0.9999999999999999), (-1., 1.)]); - assert_eq!(line0.rotate(90.), line1); + let line1 = Line::from([(1., 1.), (-1., 1.)]); + assert_relative_eq!(line0.rotate(90.0), line1); } #[test] fn test_rotate_line_around_point() { let line0 = Line::new(Point::new(0., 0.), Point::new(0., 2.)); - let line1 = Line::new( - Point::new(0., 0.), - Point::new(-2., 0.00000000000000012246467991473532), - ); - assert_eq!(line0.rotate_around_point(90., Point::new(0., 0.)), line1); + let line1 = Line::new(Point::new(0., 0.), Point::new(-2., 0.)); + assert_relative_eq!(line0.rotate_around_point(90., Point::new(0., 0.)), line1); } } From d347afdf431b33714c43a398b607be6388cd8889 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 30 Dec 2020 11:31:52 +0000 Subject: [PATCH 16/18] Minor Tidy: Removed multipoint.rs num_coords(). Fixed doctest code and comments. --- geo-types/src/line.rs | 6 +++--- geo-types/src/line_string.rs | 2 +- geo-types/src/multi_point.rs | 25 ++++--------------------- geo-types/src/point.rs | 4 ++-- 4 files changed, 10 insertions(+), 27 deletions(-) diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index a0a6f3a59..f69a29e93 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -188,7 +188,7 @@ where /// let a = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1., y: 1. }); /// let b = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1.001, y: 1. }); /// - /// approx::assert_relative_eq!(a, b, max_relative=0.1) + /// approx::assert_relative_eq!(a, b, max_relative=0.1); /// ``` #[inline] fn relative_eq( @@ -211,7 +211,7 @@ impl + CoordinateType> AbsDiffEq for Line { T::default_epsilon() } - /// Equality assertion within a relative limit. + /// Equality assertion with a absolute limit. /// /// # Examples /// @@ -221,7 +221,7 @@ impl + CoordinateType> AbsDiffEq for Line { /// let a = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1., y: 1. }); /// let b = Line::new(Coordinate { x: 0., y: 0. }, Coordinate { x: 1.001, y: 1. }); /// - /// approx::assert_relative_eq!(a, b, epsilon=0.1) + /// approx::assert_abs_diff_eq!(a, b, epsilon=0.1); /// ``` #[inline] fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index f24541cdb..c9754e579 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -343,7 +343,7 @@ impl + CoordinateType> AbsDiffEq for LineString { T::default_epsilon() } - /// Equality assertion within a relative limit. + /// Equality assertion with a absolute limit. /// /// # Examples /// diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index 1a3a978fe..be97a09b8 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -96,23 +96,6 @@ impl MultiPoint { } } -impl MultiPoint { - /// Return the number of coordinates in the `MultiPoint`. - /// - /// # Examples - /// - /// ``` - /// use geo_types::MultiPoint; - /// - /// let mut coords = vec![(0., 0.), (5., 0.), (7., 9.)]; - /// let multi_point: MultiPoint = coords.into_iter().collect(); - /// assert_eq!(3, multi_point.num_coords()); - /// ``` - pub fn num_coords(&self) -> usize { - self.0.len() - } -} - #[cfg(feature = "relative_eq")] impl RelativeEq for MultiPoint where @@ -143,7 +126,7 @@ where epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool { - if self.num_coords() != other.num_coords() { + if self.0.len() != other.0.len() { return false; } @@ -165,7 +148,7 @@ where T::default_epsilon() } - /// Equality assertion within a absolute limit. + /// Equality assertion with a absolute limit. /// /// # Examples /// @@ -176,11 +159,11 @@ where /// let a = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10., y: 10.]]); /// let b = MultiPoint(vec![point![x: 0., y: 0.], point![x: 10.001, y: 10.]]); /// - /// approx::assert_relative_eq!(a, b, epsilon=0.1) + /// approx::abs_diff_eq!(a, b, epsilon=0.1); /// ``` #[inline] fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { - if self.num_coords() != other.num_coords() { + if self.0.len() != other.0.len() { return false; } diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index bb6df066f..e1cbe9d01 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -459,11 +459,11 @@ where T::default_epsilon() } - /// Equality assertion within a absolute limit. + /// Equality assertion with a absolute limit. /// /// # Examples /// - /// ```relative_eq + /// ``` /// use geo_types::Point; /// /// let a = Point::new(2.0, 3.0); From 89d474264d6bb61593a9daef095c261a23fd837f Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 30 Dec 2020 06:46:53 -0800 Subject: [PATCH 17/18] Rename `relative_eq` feature to `approx` and make optional --- geo-types/Cargo.toml | 14 ++++++++++++-- geo-types/src/coordinate.rs | 12 +++++------- geo-types/src/lib.rs | 2 ++ geo-types/src/line.rs | 10 ++++------ geo-types/src/line_string.rs | 10 ++++------ geo-types/src/multi_point.rs | 11 +++++------ geo-types/src/point.rs | 10 +++++----- geo-types/src/private_utils.rs | 2 +- geo/Cargo.toml | 4 +--- 9 files changed, 39 insertions(+), 36 deletions(-) diff --git a/geo-types/Cargo.toml b/geo-types/Cargo.toml index 325c02894..be6c37332 100644 --- a/geo-types/Cargo.toml +++ b/geo-types/Cargo.toml @@ -11,13 +11,23 @@ description = "Geospatial primitive data types" edition = "2018" [features] -relative_eq = [] +use-rstar = ["rstar", "approx"] [dependencies] -approx = "0.4.0" +approx = { version = "0.4.0", optional = true } num-traits = "0.2" serde = { version = "1", optional = true, features = ["derive"] } +# Prefer `use-rstar` feature rather than enabling rstar directly. +# rstar integration relies on the optional approx crate, but implicit features cannot yet enable other features. +# See: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#namespaced-features rstar = { version = "0.8", optional = true } [dev-dependencies] approx = "0.4.0" + +[package.metadata.cargo-all-features] + +skip_feature_sets = [ + # must be enabled via use-rstar + ["rstar"], +] \ No newline at end of file diff --git a/geo-types/src/coordinate.rs b/geo-types/src/coordinate.rs index 450e3961c..c51c94a14 100644 --- a/geo-types/src/coordinate.rs +++ b/geo-types/src/coordinate.rs @@ -1,10 +1,8 @@ use crate::{CoordinateType, Point}; -#[cfg(any(feature = "relative_eq", test))] -use approx::{AbsDiffEq, RelativeEq}; +#[cfg(any(feature = "approx", test))] +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; -#[cfg(test)] -use approx::UlpsEq; /// A lightweight struct used to store coordinates on the 2-dimensional /// Cartesian plane. /// @@ -243,7 +241,7 @@ impl Zero for Coordinate { } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl AbsDiffEq for Coordinate where T::Epsilon: Copy, @@ -261,7 +259,7 @@ where } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl RelativeEq for Coordinate where T::Epsilon: Copy, @@ -278,7 +276,7 @@ where } } -#[cfg(test)] +#[cfg(any(feature = "approx", test))] impl UlpsEq for Coordinate where T::Epsilon: Copy, diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index 74499fb0a..56b947ec5 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -28,6 +28,7 @@ extern crate serde; #[cfg(feature = "rstar")] extern crate rstar; +#[cfg(test)] #[macro_use] extern crate approx; @@ -79,6 +80,7 @@ pub use crate::rect::{InvalidRectCoordinatesError, Rect}; #[macro_use] mod macros; +#[cfg(feature = "rstar")] #[doc(hidden)] pub mod private_utils; diff --git a/geo-types/src/line.rs b/geo-types/src/line.rs index f69a29e93..95b5a2839 100644 --- a/geo-types/src/line.rs +++ b/geo-types/src/line.rs @@ -1,8 +1,6 @@ use crate::{Coordinate, CoordinateType, Point}; -#[cfg(feature = "relative_eq")] -use approx::AbsDiffEq; -#[cfg(feature = "relative_eq")] -use approx::RelativeEq; +#[cfg(any(feature = "approx", test))] +use approx::{AbsDiffEq, RelativeEq}; /// A line segment made up of exactly two /// [`Coordinate`s](struct.Coordinate.html). @@ -168,7 +166,7 @@ impl From<[(T, T); 2]> for Line { Line::new(coord[0], coord[1]) } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl RelativeEq for Line where T: AbsDiffEq + CoordinateType + RelativeEq, @@ -202,7 +200,7 @@ where } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl + CoordinateType> AbsDiffEq for Line { type Epsilon = T; diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index c9754e579..31f5aacfb 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -1,7 +1,5 @@ -#[cfg(feature = "relative_eq")] -use approx::AbsDiffEq; -#[cfg(feature = "relative_eq")] -use approx::RelativeEq; +#[cfg(any(feature = "approx", test))] +use approx::{AbsDiffEq, RelativeEq}; use crate::{Coordinate, CoordinateType, Line, Point, Triangle}; use std::iter::FromIterator; @@ -287,7 +285,7 @@ impl IndexMut for LineString { } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl RelativeEq for LineString where T: AbsDiffEq + CoordinateType + RelativeEq, @@ -334,7 +332,7 @@ where } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl + CoordinateType> AbsDiffEq for LineString { type Epsilon = T; diff --git a/geo-types/src/multi_point.rs b/geo-types/src/multi_point.rs index be97a09b8..83facc604 100644 --- a/geo-types/src/multi_point.rs +++ b/geo-types/src/multi_point.rs @@ -1,8 +1,7 @@ use crate::{CoordinateType, Point}; -#[cfg(feature = "relative_eq")] -use approx::AbsDiffEq; -#[cfg(feature = "relative_eq")] -use approx::RelativeEq; + +#[cfg(any(feature = "approx", test))] +use approx::{AbsDiffEq, RelativeEq}; use std::iter::FromIterator; @@ -96,7 +95,7 @@ impl MultiPoint { } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl RelativeEq for MultiPoint where T: AbsDiffEq + CoordinateType + RelativeEq, @@ -135,7 +134,7 @@ where } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl AbsDiffEq for MultiPoint where T: AbsDiffEq + CoordinateType, diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index e1cbe9d01..02a2a2de9 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -1,8 +1,7 @@ use crate::{Coordinate, CoordinateType}; -use approx::AbsDiffEq; -#[cfg(feature = "relative_eq")] -use approx::RelativeEq; +#[cfg(any(feature = "approx", test))] +use approx::{AbsDiffEq, RelativeEq}; use num_traits::Float; use std::ops::{Add, Div, Mul, Neg, Sub}; @@ -414,7 +413,7 @@ where } } -#[cfg(feature = "relative_eq")] +#[cfg(any(feature = "approx", test))] impl RelativeEq for Point where T: AbsDiffEq + CoordinateType + RelativeEq, @@ -446,7 +445,8 @@ where self.0.relative_eq(&other.0, epsilon, max_relative) } } -#[cfg(feature = "relative_eq")] + +#[cfg(any(feature = "approx", test))] impl AbsDiffEq for Point where T: AbsDiffEq + CoordinateType, diff --git a/geo-types/src/private_utils.rs b/geo-types/src/private_utils.rs index efdda6f71..b84f258be 100644 --- a/geo-types/src/private_utils.rs +++ b/geo-types/src/private_utils.rs @@ -127,7 +127,7 @@ where T: Float, { let distance = line_euclidean_length(Line::new(p1, p2)).to_f32().unwrap(); - relative_eq!(distance, 0.0) + approx::relative_eq!(distance, 0.0) } pub fn line_string_contains_point(line_string: &LineString, point: Point) -> bool diff --git a/geo/Cargo.toml b/geo/Cargo.toml index 12097a746..52da54c36 100644 --- a/geo/Cargo.toml +++ b/geo/Cargo.toml @@ -22,12 +22,11 @@ geographiclib-rs = { version = "0.2" } proj = { version = "0.20.3", optional = true } -geo-types = { version = "0.6.2", optional = true, path = "../geo-types", features = ["rstar"] } +geo-types = { version = "0.6.2", path = "../geo-types", features = ["approx", "use-rstar"] } robust = { version = "0.2.2" } [features] -default = ["geo-types"] use-proj = ["proj"] proj-network = ["use-proj", "proj/network"] use-serde = ["serde", "geo-types/serde"] @@ -35,7 +34,6 @@ use-serde = ["serde", "geo-types/serde"] [dev-dependencies] approx = "0.4.0" criterion = { version = "0.3" } -geo-types = { version = "0.6.2", path = "../geo-types", features = ["relative_eq", "rstar"] } rand = "0.8.0" [[bench]] From fde739552976dbf2b51f85c1025e52d3f323a644 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 1 Jan 2021 13:18:17 -0800 Subject: [PATCH 18/18] changelog --- geo-types/CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/geo-types/CHANGES.md b/geo-types/CHANGES.md index 61caf57f3..6fb77e72a 100644 --- a/geo-types/CHANGES.md +++ b/geo-types/CHANGES.md @@ -4,6 +4,8 @@ * `geo_types::LineString::num_coords` has been deprecated in favor of `geo::algorithm::coords_iter::CoordsIter::coords_count` * +* Introduce `use-rstar` feature rather than `rstar` so that `approx` dependency can be optional + * ## 0.6.2