Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

relative_eq() #567

Merged
merged 19 commits into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
946397d
Added num_coords() method to MultiPoint. To Point, Line, LineString a…
martinfrances107 Dec 11, 2020
65f6100
Removed debug.
martinfrances107 Dec 11, 2020
4ab3599
Removed commented out code.
martinfrances107 Dec 16, 2020
daf5570
Removed commented out code.
martinfrances107 Dec 16, 2020
719c32c
line_string.rs abs_diff_eq: simplify by using .all()
martinfrances107 Dec 16, 2020
6c23693
multi_point.rs: Simplify using .all()
martinfrances107 Dec 16, 2020
3eaec49
multi_point.rs abs_diff_eq() now handles unequal sizes
martinfrances107 Dec 16, 2020
1dca719
point.rs Simplify RelativeEq for Point
martinfrances107 Dec 16, 2020
edb4ff1
lines.rs Simplify "AbsDiffEq for Line<T>" to operate of coords not po…
martinfrances107 Dec 16, 2020
5aa011c
line_string.rs - abs_diff_eq() Now rejects line_strings with unequal…
martinfrances107 Dec 16, 2020
efb112a
Removed type constraint on RelativeEq and AbsDiffEq that the type mus…
martinfrances107 Dec 17, 2020
8ba2b0b
ran cargo fmt
martinfrances107 Dec 17, 2020
26a6a2d
Added new feature relative_eq
martinfrances107 Dec 20, 2020
c21a552
After rebase, drop the use of the deprecated num_coords() method.
martinfrances107 Dec 22, 2020
bfb2746
Fixed dev-dependency issue.
martinfrances107 Dec 24, 2020
d347afd
Minor Tidy: Removed multipoint.rs num_coords(). Fixed doctest code an…
martinfrances107 Dec 30, 2020
89d4742
Rename `relative_eq` feature to `approx` and make optional
michaelkirk Dec 30, 2020
fde7395
changelog
michaelkirk Jan 1, 2021
e90ee64
Merge pull request #1 from georust/mkirk/approx-feature-juggling
martinfrances107 Jan 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions geo-types/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

* `geo_types::LineString::num_coords` has been deprecated in favor of `geo::algorithm::coords_iter::CoordsIter::coords_count`
* <https://github.com/georust/geo/pull/563>
* Introduce `use-rstar` feature rather than `rstar` so that `approx` dependency can be optional
* <https://github.com/georust/geo/pull/567>

## 0.6.2

Expand Down
15 changes: 14 additions & 1 deletion geo-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,24 @@ keywords = ["gis", "geo", "geography", "geospatial"]
description = "Geospatial primitive data types"
edition = "2018"

[features]
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"],
]
13 changes: 9 additions & 4 deletions geo-types/src/coordinate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{CoordinateType, Point};
#[cfg(test)]

#[cfg(any(feature = "approx", test))]
use approx::{AbsDiffEq, RelativeEq, UlpsEq};

/// A lightweight struct used to store coordinates on the 2-dimensional
Expand Down Expand Up @@ -240,38 +241,42 @@ impl<T: CoordinateType> Zero for Coordinate<T> {
}
}

#[cfg(test)]
#[cfg(any(feature = "approx", test))]
impl<T: CoordinateType + AbsDiffEq> AbsDiffEq for Coordinate<T>
where
T::Epsilon: Copy,
{
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)
}
}

#[cfg(test)]
#[cfg(any(feature = "approx", test))]
impl<T: CoordinateType + RelativeEq> RelativeEq for Coordinate<T>
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)
}
}

#[cfg(test)]
#[cfg(any(feature = "approx", test))]
impl<T: CoordinateType + UlpsEq> UlpsEq for Coordinate<T>
where
T::Epsilon: Copy,
Expand Down
2 changes: 2 additions & 0 deletions geo-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ extern crate serde;
#[cfg(feature = "rstar")]
extern crate rstar;

#[cfg(test)]
#[macro_use]
extern crate approx;

Expand Down Expand Up @@ -79,6 +80,7 @@ pub use crate::rect::{InvalidRectCoordinatesError, Rect};
#[macro_use]
mod macros;

#[cfg(feature = "rstar")]
#[doc(hidden)]
pub mod private_utils;

Expand Down
141 changes: 141 additions & 0 deletions geo-types/src/line.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::{Coordinate, CoordinateType, Point};
#[cfg(any(feature = "approx", test))]
use approx::{AbsDiffEq, RelativeEq};

/// A line segment made up of exactly two
/// [`Coordinate`s](struct.Coordinate.html).
Expand Down Expand Up @@ -164,6 +166,66 @@ impl<T: CoordinateType> From<[(T, T); 2]> for Line<T> {
Line::new(coord[0], coord[1])
}
}
#[cfg(any(feature = "approx", test))]
impl<T> RelativeEq for Line<T>
where
T: AbsDiffEq<Epsilon = T> + CoordinateType + RelativeEq,
{
#[inline]
fn default_max_relative() -> Self::Epsilon {
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,
other: &Self,
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)
}
}

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

#[inline]
fn default_epsilon() -> Self::Epsilon {
T::default_epsilon()
}

/// Equality assertion with a absolute 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_abs_diff_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)
}
}

#[cfg(feature = "rstar")]
impl<T> ::rstar::RTreeObject for Line<T>
Expand All @@ -188,3 +250,82 @@ where
d.powi(2)
}
}

#[cfg(test)]
mod test {
use super::*;

#[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));
}
}
Loading