Skip to content

Commit

Permalink
Added new feature relative_eq
Browse files Browse the repository at this point in the history
  • Loading branch information
martinfrances107 committed Dec 20, 2020
1 parent cbe1266 commit 5c9f43b
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 28 deletions.
3 changes: 3 additions & 0 deletions geo-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
11 changes: 7 additions & 4 deletions geo-types/src/coordinate.rs
Original file line number Diff line number Diff line change
@@ -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.
///
Expand Down Expand Up @@ -240,7 +243,7 @@ impl<T: CoordinateType> Zero for Coordinate<T> {
}
}

#[cfg(test)]
#[cfg(any(test, feature = "relative_eq"))]
impl<T: CoordinateType + AbsDiffEq> AbsDiffEq for Coordinate<T>
where
T::Epsilon: Copy,
Expand All @@ -258,7 +261,7 @@ where
}
}

#[cfg(test)]
#[cfg(any(test, feature = "relative_eq"))]
impl<T: CoordinateType + RelativeEq> RelativeEq for Coordinate<T>
where
T::Epsilon: Copy,
Expand Down
35 changes: 28 additions & 7 deletions geo-types/src/line.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -168,8 +168,7 @@ impl<T: CoordinateType> From<[(T, T); 2]> for Line<T> {
Line::new(coord[0], coord[1])
}
}

#[cfg(test)]
#[cfg(feature = "relative_eq")]
impl<T> RelativeEq for Line<T>
where
T: AbsDiffEq<Epsilon = T> + CoordinateType + RelativeEq,
Expand All @@ -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,
Expand All @@ -191,7 +202,7 @@ where
}
}

#[cfg(test)]
#[cfg(feature = "relative_eq")]
impl<T: AbsDiffEq<Epsilon = T> + CoordinateType> AbsDiffEq for Line<T> {
type Epsilon = T;

Expand All @@ -200,6 +211,18 @@ impl<T: AbsDiffEq<Epsilon = T> + CoordinateType> AbsDiffEq for Line<T> {
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)
Expand Down Expand Up @@ -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;
Expand Down
42 changes: 36 additions & 6 deletions geo-types/src/line_string.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -286,7 +286,7 @@ impl<T: CoordinateType> IndexMut<usize> for LineString<T> {
}
}

#[cfg(test)]
#[cfg(feature = "relative_eq")]
impl<T> RelativeEq for LineString<T>
where
T: AbsDiffEq<Epsilon = T> + CoordinateType + RelativeEq,
Expand All @@ -296,6 +296,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<f32> = coords_a.into_iter().collect();
///
/// let mut coords_b = vec![(0., 0.), (5., 0.), (7.001, 9.)];
/// let b: LineString<f32> = coords_b.into_iter().collect();
///
/// approx::assert_relative_eq!(a, b, max_relative=0.1)
/// ```
///
fn relative_eq(
&self,
other: &Self,
Expand All @@ -317,7 +333,7 @@ where
}
}

#[cfg(test)]
#[cfg(feature = "relative_eq")]
impl<T: AbsDiffEq<Epsilon = T> + CoordinateType> AbsDiffEq for LineString<T> {
type Epsilon = T;

Expand All @@ -326,6 +342,21 @@ impl<T: AbsDiffEq<Epsilon = T> + CoordinateType> AbsDiffEq for LineString<T> {
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<f32> = coords_a.into_iter().collect();
///
/// let mut coords_b = vec![(0., 0.), (5., 0.), (7.001, 9.)];
/// let b: LineString<f32> = 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;
Expand Down Expand Up @@ -373,12 +404,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() {
Expand Down
34 changes: 30 additions & 4 deletions geo-types/src/multi_point.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -113,7 +113,7 @@ impl<T: CoordinateType> MultiPoint<T> {
}
}

#[cfg(test)]
#[cfg(feature = "relative_eq")]
impl<T> RelativeEq for MultiPoint<T>
where
T: AbsDiffEq<Epsilon = T> + CoordinateType + RelativeEq,
Expand All @@ -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,
Expand All @@ -139,7 +152,7 @@ where
}
}

#[cfg(test)]
#[cfg(feature = "relative_eq")]
impl<T> AbsDiffEq for MultiPoint<T>
where
T: AbsDiffEq<Epsilon = T> + CoordinateType,
Expand All @@ -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() {
Expand Down
33 changes: 28 additions & 5 deletions geo-types/src/point.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -414,7 +414,7 @@ where
}
}

#[cfg(test)]
#[cfg(feature = "relative_eq")]
impl<T> RelativeEq for Point<T>
where
T: AbsDiffEq<Epsilon = T> + CoordinateType + RelativeEq,
Expand All @@ -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,
Expand All @@ -434,8 +446,7 @@ where
self.0.relative_eq(&other.0, epsilon, max_relative)
}
}

#[cfg(test)]
#[cfg(feature = "relative_eq")]
impl<T> AbsDiffEq for Point<T>
where
T: AbsDiffEq<Epsilon = T> + CoordinateType,
Expand All @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions geo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ 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]
default = []
use-proj = ["proj"]
proj-network = ["use-proj", "proj/network"]
use-serde = ["serde", "geo-types/serde"]
relative_eq = ["approx"]

[dev-dependencies]
approx = "0.3.0"
Expand Down

0 comments on commit 5c9f43b

Please sign in to comment.