From a36f696805cca853e644719f29be32da271e1c1d Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 5 May 2022 11:11:38 -0700 Subject: [PATCH] CONTROVERSIAL: make GeoFloat compat with RTreeNum If we want to rely on using an RTree for some of our operations (like the Relate trait) we have to ensure our numeric types are RTree compatible. == Alternative considered Since RTreeNum isn't necessarily a float, we could instead add these new bounds to GeoNum instead of GeoFloat. However, doing so would mean dropping support for unsigned ints from GeoNum. Note that using unsigned ints now, while supported, can easily lead to underflow if you're using one of the many operations that involve subtraction. It would also put one more barrier between ever getting BigDecimal support in geo - which is not Bounded. Also, apparently Float isn't necessarily Signed, but having never personally encountered unsigned floating point in the wild, I don't have strong feelings about retaining support for it. And since Relate doesn't current support non-floats, this would be a cost with no benefit. If that changes, we could reconsider this decision, or perhaps add the required behavior to some derivative type, like one of the HasKernel implementations. --- geo/src/algorithm/euclidean_distance.rs | 12 ++++++------ geo/src/lib.rs | 5 +++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/geo/src/algorithm/euclidean_distance.rs b/geo/src/algorithm/euclidean_distance.rs index cbe44f2be6..e3c7ed022b 100644 --- a/geo/src/algorithm/euclidean_distance.rs +++ b/geo/src/algorithm/euclidean_distance.rs @@ -142,7 +142,7 @@ where .0 .iter() .map(|p| self.euclidean_distance(p)) - .fold(T::max_value(), |accum, val| accum.min(val)) + .fold(::max_value(), |accum, val| accum.min(val)) } } @@ -175,7 +175,7 @@ where mls.0 .iter() .map(|ls| self.euclidean_distance(ls)) - .fold(T::max_value(), |accum, val| accum.min(val)) + .fold(::max_value(), |accum, val| accum.min(val)) } } @@ -195,7 +195,7 @@ where .interiors() .iter() .map(|ring| self.euclidean_distance(ring)) - .fold(T::max_value(), |accum, val| accum.min(val)) + .fold(::max_value(), |accum, val| accum.min(val)) .min( polygon .exterior() @@ -205,7 +205,7 @@ where self.0, line.start, line.end, ) }) - .fold(T::max_value(), |accum, val| accum.min(val)), + .fold(::max_value(), |accum, val| accum.min(val)), ) } } @@ -220,7 +220,7 @@ where .0 .iter() .map(|p| self.euclidean_distance(p)) - .fold(T::max_value(), |accum, val| accum.min(val)) + .fold(::max_value(), |accum, val| accum.min(val)) } } @@ -530,7 +530,7 @@ where [(self.0, self.1), (self.1, self.2), (self.2, self.0)] .iter() .map(|edge| ::geo_types::private_utils::line_segment_distance(point.0, edge.0, edge.1)) - .fold(T::max_value(), |accum, val| accum.min(val)) + .fold(::max_value(), |accum, val| accum.min(val)) } } diff --git a/geo/src/lib.rs b/geo/src/lib.rs index 4dde1731b0..ab4ee44ae9 100644 --- a/geo/src/lib.rs +++ b/geo/src/lib.rs @@ -293,8 +293,9 @@ pub mod prelude { /// }) /// } /// ``` -pub trait GeoFloat: num_traits::Float + GeoNum {} -impl GeoFloat for T where T: num_traits::Float + GeoNum {} +pub trait GeoFloat: num_traits::Float + num_traits::Signed + num_traits::Bounded + GeoNum {} +impl GeoFloat for T where T: num_traits::Float + num_traits::Signed + num_traits::Bounded + GeoNum +{} pub trait GeoNum: CoordNum + algorithm::kernels::HasKernel {} impl GeoNum for T where T: CoordNum + algorithm::kernels::HasKernel {}