From c3fc7c9b3c064df7f111d62a1a5e2dbeafff9017 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 7 Oct 2024 14:44:35 -0700 Subject: [PATCH] Deprecate legacy `length` usage --- geo/CHANGES.md | 11 +++- geo/src/algorithm/centroid.rs | 10 ++-- geo/src/algorithm/closest_point.rs | 4 +- geo/src/algorithm/concave_hull.rs | 6 +-- geo/src/algorithm/densify.rs | 17 ++++++- geo/src/algorithm/densify_haversine.rs | 13 ++++- geo/src/algorithm/euclidean_distance.rs | 5 +- geo/src/algorithm/euclidean_length.rs | 19 ++++--- geo/src/algorithm/geodesic_area.rs | 8 +-- geo/src/algorithm/geodesic_length.rs | 20 +++----- geo/src/algorithm/haversine_length.rs | 16 +++--- geo/src/algorithm/line_interpolate_point.rs | 5 ++ geo/src/algorithm/line_locate_point.rs | 5 ++ .../line_measures/metric_spaces/euclidean.rs | 7 +-- .../line_measures/metric_spaces/haversine.rs | 2 +- geo/src/algorithm/linestring_segment.rs | 50 +++++++++---------- geo/src/algorithm/mod.rs | 8 +-- geo/src/algorithm/rhumb/length.rs | 16 +++--- geo/src/algorithm/rhumb/mod.rs | 1 + 19 files changed, 133 insertions(+), 90 deletions(-) diff --git a/geo/CHANGES.md b/geo/CHANGES.md index 7c68c6708..62c48fa33 100644 --- a/geo/CHANGES.md +++ b/geo/CHANGES.md @@ -43,6 +43,16 @@ * `RhumbBearing`, `RhumbDistance`, `RhumbDestination`, `RhumbIntermediate` * `HaversineBearing`, `HaversineDistance`, `HaversineDestination`, `HaversineIntermediate` * +* Deprecated `HaversineLength`, `EuclideanLength`, `RhumbLength`, `GeodesicLength` in favor of new generic `Length` trait. + ``` + // Before + line_string.euclidean_length(); + line_string.haversine_length(); + // After + line_string.length::(); + line_string.length::(); + ``` + * * Change IntersectionMatrix::is_equal_topo to now consider empty geometries as equal. * * Fix `(LINESTRING EMPTY).contains(LINESTRING EMPTY)` and `(MULTIPOLYGON EMPTY).contains(MULTIPOINT EMPTY)` which previously @@ -53,7 +63,6 @@ * * Enable i128 geometry types * - ## 0.28.0 * BREAKING: The `HasKernel` trait was removed and it's functionality was merged diff --git a/geo/src/algorithm/centroid.rs b/geo/src/algorithm/centroid.rs index 8718295f5..0be576341 100644 --- a/geo/src/algorithm/centroid.rs +++ b/geo/src/algorithm/centroid.rs @@ -3,7 +3,7 @@ use std::cmp::Ordering; use crate::area::{get_linestring_area, Area}; use crate::dimensions::{Dimensions, Dimensions::*, HasDimensions}; use crate::geometry::*; -use crate::EuclideanLength; +use crate::line_measures::{Euclidean, Length}; use crate::GeoFloat; /// Calculation of the centroid. @@ -465,9 +465,11 @@ impl CentroidOperation { fn add_line(&mut self, line: &Line) { match line.dimensions() { ZeroDimensional => self.add_coord(line.start), - OneDimensional => { - self.add_centroid(OneDimensional, line.centroid().0, line.euclidean_length()) - } + OneDimensional => self.add_centroid( + OneDimensional, + line.centroid().0, + line.length::(), + ), _ => unreachable!("Line must be zero or one dimensional"), } } diff --git a/geo/src/algorithm/closest_point.rs b/geo/src/algorithm/closest_point.rs index 9af1e530d..516054538 100644 --- a/geo/src/algorithm/closest_point.rs +++ b/geo/src/algorithm/closest_point.rs @@ -1,4 +1,4 @@ -use crate::algorithm::{EuclideanLength, Intersects}; +use crate::algorithm::{Euclidean, Intersects, Length}; use crate::geometry::*; use crate::Closest; use crate::GeoFloat; @@ -52,7 +52,7 @@ impl ClosestPoint for Point { #[allow(clippy::many_single_char_names)] impl ClosestPoint for Line { fn closest_point(&self, p: &Point) -> Closest { - let line_length = self.euclidean_length(); + let line_length = self.length::(); if line_length == F::zero() { // if we've got a zero length line, technically the entire line // is the closest point... diff --git a/geo/src/algorithm/concave_hull.rs b/geo/src/algorithm/concave_hull.rs index c955ac1d0..e4a288adf 100644 --- a/geo/src/algorithm/concave_hull.rs +++ b/geo/src/algorithm/concave_hull.rs @@ -1,7 +1,7 @@ use crate::convex_hull::qhull; use crate::utils::partial_min; use crate::{ - coord, Centroid, Coord, CoordNum, EuclideanDistance, EuclideanLength, GeoFloat, Line, + coord, Centroid, Coord, CoordNum, Euclidean, EuclideanDistance, GeoFloat, Length, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, }; use rstar::{RTree, RTreeNum}; @@ -116,7 +116,7 @@ where T: GeoFloat + RTreeNum, { let h = max_dist + max_dist; - let w = line.euclidean_length() + h; + let w = line.length::() + h; let two = T::add(T::one(), T::one()); let search_dist = T::div(T::sqrt(T::powi(w, 2) + T::powi(h, 2)), two); let centroid = line.centroid(); @@ -217,7 +217,7 @@ where line_tree.insert(line); } while let Some(line) = line_queue.pop_front() { - let edge_length = line.euclidean_length(); + let edge_length = line.length::(); let dist = edge_length / concavity; let possible_closest_point = find_point_closest_to_line( &interior_points_tree, diff --git a/geo/src/algorithm/densify.rs b/geo/src/algorithm/densify.rs index 2c158f03b..3a930f904 100644 --- a/geo/src/algorithm/densify.rs +++ b/geo/src/algorithm/densify.rs @@ -1,8 +1,13 @@ use crate::{ - CoordFloat, EuclideanLength, Line, LineInterpolatePoint, LineString, MultiLineString, - MultiPolygon, Point, Polygon, Rect, Triangle, + CoordFloat, Line, LineInterpolatePoint, LineString, MultiLineString, MultiPolygon, Point, + Polygon, Rect, Triangle, }; +// This is still used in the trait constraints - but Densify too will soon be replaced with a +// generic version, at which point this implementation detail can be removed. +#[allow(deprecated)] +use crate::EuclideanLength; + /// Return a new linear geometry containing both existing and new interpolated coordinates with /// a maximum distance of `max_distance` between them. /// @@ -26,6 +31,7 @@ pub trait Densify { } // Helper for densification trait +#[allow(deprecated)] fn densify_line(line: Line, container: &mut Vec>, max_distance: T) { assert!(max_distance > T::zero()); container.push(line.start_point()); @@ -44,6 +50,7 @@ fn densify_line(line: Line, container: &mut Vec>, max } } +#[allow(deprecated)] impl Densify for MultiPolygon where T: CoordFloat, @@ -61,6 +68,7 @@ where } } +#[allow(deprecated)] impl Densify for Polygon where T: CoordFloat, @@ -80,6 +88,7 @@ where } } +#[allow(deprecated)] impl Densify for MultiLineString where T: CoordFloat, @@ -97,6 +106,7 @@ where } } +#[allow(deprecated)] impl Densify for LineString where T: CoordFloat, @@ -120,6 +130,7 @@ where } } +#[allow(deprecated)] impl Densify for Line where T: CoordFloat, @@ -137,6 +148,7 @@ where } } +#[allow(deprecated)] impl Densify for Triangle where T: CoordFloat, @@ -150,6 +162,7 @@ where } } +#[allow(deprecated)] impl Densify for Rect where T: CoordFloat, diff --git a/geo/src/algorithm/densify_haversine.rs b/geo/src/algorithm/densify_haversine.rs index 4f2465443..e8b2f0dbc 100644 --- a/geo/src/algorithm/densify_haversine.rs +++ b/geo/src/algorithm/densify_haversine.rs @@ -1,6 +1,8 @@ use num_traits::FromPrimitive; -use crate::line_measures::{Haversine, InterpolatePoint}; +use crate::line_measures::{Haversine, InterpolatePoint, Length}; +// Densify will soon be deprecated too, so let's just allow deprecated for now +#[allow(deprecated)] use crate::HaversineLength; use crate::{ CoordFloat, CoordsIter, Line, LineString, MultiLineString, MultiPolygon, Point, Polygon, Rect, @@ -42,7 +44,7 @@ fn densify_line( ) { assert!(max_distance > T::zero()); container.push(line.start_point()); - let num_segments = (line.haversine_length() / max_distance) + let num_segments = (line.length::() / max_distance) .ceil() .to_u64() .unwrap(); @@ -57,6 +59,7 @@ fn densify_line( } } +#[allow(deprecated)] impl DensifyHaversine for MultiPolygon where T: CoordFloat + FromPrimitive, @@ -74,6 +77,7 @@ where } } +#[allow(deprecated)] impl DensifyHaversine for Polygon where T: CoordFloat + FromPrimitive, @@ -93,6 +97,7 @@ where } } +#[allow(deprecated)] impl DensifyHaversine for MultiLineString where T: CoordFloat + FromPrimitive, @@ -110,6 +115,7 @@ where } } +#[allow(deprecated)] impl DensifyHaversine for LineString where T: CoordFloat + FromPrimitive, @@ -132,6 +138,7 @@ where } } +#[allow(deprecated)] impl DensifyHaversine for Line where T: CoordFloat + FromPrimitive, @@ -149,6 +156,7 @@ where } } +#[allow(deprecated)] impl DensifyHaversine for Triangle where T: CoordFloat + FromPrimitive, @@ -162,6 +170,7 @@ where } } +#[allow(deprecated)] impl DensifyHaversine for Rect where T: CoordFloat + FromPrimitive, diff --git a/geo/src/algorithm/euclidean_distance.rs b/geo/src/algorithm/euclidean_distance.rs index acde6ae07..b0ee3c5c8 100644 --- a/geo/src/algorithm/euclidean_distance.rs +++ b/geo/src/algorithm/euclidean_distance.rs @@ -1,10 +1,9 @@ use crate::utils::{coord_pos_relative_to_ring, CoordPos}; -use crate::EuclideanLength; -use crate::Intersects; use crate::{ Coord, GeoFloat, GeoNum, Geometry, GeometryCollection, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle, }; +use crate::{Distance, Euclidean, Intersects}; use num_traits::{float::FloatConst, Bounded, Float, Signed}; use rstar::primitives::CachedEnvelope; @@ -104,7 +103,7 @@ where { /// Minimum distance between two `Coord`s fn euclidean_distance(&self, c: &Coord) -> T { - Line::new(*self, *c).euclidean_length() + Euclidean::distance((*self).into(), (*c).into()) } } diff --git a/geo/src/algorithm/euclidean_length.rs b/geo/src/algorithm/euclidean_length.rs index 3b72ee820..077b48e91 100644 --- a/geo/src/algorithm/euclidean_length.rs +++ b/geo/src/algorithm/euclidean_length.rs @@ -1,6 +1,6 @@ use std::iter::Sum; -use crate::{CoordFloat, Line, LineString, MultiLineString}; +use crate::{CoordFloat, Euclidean, Length, Line, LineString, MultiLineString}; /// Calculation of the length @@ -30,51 +30,56 @@ pub trait EuclideanLength { fn euclidean_length(&self) -> T; } +#[allow(deprecated)] impl EuclideanLength for Line where T: CoordFloat, { fn euclidean_length(&self) -> T { - ::geo_types::private_utils::line_euclidean_length(*self) + self.length::() } } +#[allow(deprecated)] impl EuclideanLength for LineString where T: CoordFloat + Sum, { fn euclidean_length(&self) -> T { - self.lines().map(|line| line.euclidean_length()).sum() + self.length::() } } +#[allow(deprecated)] impl EuclideanLength for MultiLineString where T: CoordFloat + Sum, { fn euclidean_length(&self) -> T { - self.0 - .iter() - .fold(T::zero(), |total, line| total + line.euclidean_length()) + self.length::() } } #[cfg(test)] mod test { use crate::line_string; + #[allow(deprecated)] use crate::EuclideanLength; use crate::{coord, Line, MultiLineString}; + #[allow(deprecated)] #[test] fn empty_linestring_test() { let linestring = line_string![]; assert_relative_eq!(0.0_f64, linestring.euclidean_length()); } + #[allow(deprecated)] #[test] fn linestring_one_point_test() { let linestring = line_string![(x: 0., y: 0.)]; assert_relative_eq!(0.0_f64, linestring.euclidean_length()); } + #[allow(deprecated)] #[test] fn linestring_test() { let linestring = line_string![ @@ -87,6 +92,7 @@ mod test { ]; assert_relative_eq!(10.0_f64, linestring.euclidean_length()); } + #[allow(deprecated)] #[test] fn multilinestring_test() { let mline = MultiLineString::new(vec![ @@ -105,6 +111,7 @@ mod test { ]); assert_relative_eq!(15.0_f64, mline.euclidean_length()); } + #[allow(deprecated)] #[test] fn line_test() { let line0 = Line::new(coord! { x: 0., y: 0. }, coord! { x: 0., y: 1. }); diff --git a/geo/src/algorithm/geodesic_area.rs b/geo/src/algorithm/geodesic_area.rs index 66b44d186..20419e762 100644 --- a/geo/src/algorithm/geodesic_area.rs +++ b/geo/src/algorithm/geodesic_area.rs @@ -350,7 +350,7 @@ impl GeodesicArea for Geometry { #[cfg(test)] mod test { use super::*; - use crate::algorithm::geodesic_length::GeodesicLength; + use crate::algorithm::line_measures::{Geodesic, Length}; use crate::polygon; #[test] @@ -380,7 +380,7 @@ mod test { // Confirm that the exterior ring geodesic_length is the same as the perimeter assert_relative_eq!( - polygon.exterior().geodesic_length(), + polygon.exterior().length::(), polygon.geodesic_perimeter() ); } @@ -410,7 +410,7 @@ mod test { // Confirm that the exterior ring geodesic_length is the same as the perimeter assert_relative_eq!( - polygon.exterior().geodesic_length(), + polygon.exterior().length::(), polygon.geodesic_perimeter() ); } @@ -440,7 +440,7 @@ mod test { // Confirm that the exterior ring geodesic_length is the same as the perimeter assert_relative_eq!( - polygon.exterior().geodesic_length(), + polygon.exterior().length::(), polygon.geodesic_perimeter() ); } diff --git a/geo/src/algorithm/geodesic_length.rs b/geo/src/algorithm/geodesic_length.rs index 0b9abbe7f..d0efc1760 100644 --- a/geo/src/algorithm/geodesic_length.rs +++ b/geo/src/algorithm/geodesic_length.rs @@ -1,4 +1,4 @@ -use crate::{Distance, Geodesic, Line, LineString, MultiLineString}; +use crate::{Geodesic, Length, Line, LineString, MultiLineString}; #[deprecated( since = "0.29.0", @@ -48,30 +48,24 @@ pub trait GeodesicLength { fn geodesic_length(&self) -> T; } +#[allow(deprecated)] impl GeodesicLength for Line { /// The units of the returned value is meters. fn geodesic_length(&self) -> f64 { - let (start, end) = self.points(); - Geodesic::distance(start, end) + self.length::() } } +#[allow(deprecated)] impl GeodesicLength for LineString { fn geodesic_length(&self) -> f64 { - let mut length = 0.0; - for line in self.lines() { - length += line.geodesic_length(); - } - length + self.length::() } } +#[allow(deprecated)] impl GeodesicLength for MultiLineString { fn geodesic_length(&self) -> f64 { - let mut length = 0.0; - for line_string in &self.0 { - length += line_string.geodesic_length(); - } - length + self.length::() } } diff --git a/geo/src/algorithm/haversine_length.rs b/geo/src/algorithm/haversine_length.rs index b87806daf..a2730733b 100644 --- a/geo/src/algorithm/haversine_length.rs +++ b/geo/src/algorithm/haversine_length.rs @@ -1,7 +1,7 @@ use num_traits::FromPrimitive; use crate::{CoordFloat, Line, LineString, MultiLineString}; -use crate::{Distance, Haversine}; +use crate::{Haversine, Length}; #[deprecated( since = "0.29.0", @@ -45,34 +45,32 @@ pub trait HaversineLength { fn haversine_length(&self) -> T; } +#[allow(deprecated)] impl HaversineLength for Line where T: CoordFloat + FromPrimitive, { fn haversine_length(&self) -> T { - let (start, end) = self.points(); - Haversine::distance(start, end) + self.length::() } } +#[allow(deprecated)] impl HaversineLength for LineString where T: CoordFloat + FromPrimitive, { fn haversine_length(&self) -> T { - self.lines().fold(T::zero(), |total_length, line| { - total_length + line.haversine_length() - }) + self.length::() } } +#[allow(deprecated)] impl HaversineLength for MultiLineString where T: CoordFloat + FromPrimitive, { fn haversine_length(&self) -> T { - self.0 - .iter() - .fold(T::zero(), |total, line| total + line.haversine_length()) + self.length::() } } diff --git a/geo/src/algorithm/line_interpolate_point.rs b/geo/src/algorithm/line_interpolate_point.rs index 3af1dc0cf..3df1c334a 100644 --- a/geo/src/algorithm/line_interpolate_point.rs +++ b/geo/src/algorithm/line_interpolate_point.rs @@ -1,4 +1,8 @@ use crate::coords_iter::CoordsIter; +// This algorithm will be deprecated in the future, replaced by a unified implementation +// rather than being Euclidean specific. Until the alternative is available, lets allow deprecations +// so as not to change the method signature for existing users. +#[allow(deprecated)] use crate::{CoordFloat, EuclideanLength, Line, LineString, Point}; use std::ops::AddAssign; @@ -66,6 +70,7 @@ where } } +#[allow(deprecated)] impl LineInterpolatePoint for LineString where T: CoordFloat + AddAssign + std::fmt::Debug, diff --git a/geo/src/algorithm/line_locate_point.rs b/geo/src/algorithm/line_locate_point.rs index cf2a78cab..5d34c2d94 100644 --- a/geo/src/algorithm/line_locate_point.rs +++ b/geo/src/algorithm/line_locate_point.rs @@ -1,3 +1,7 @@ +// This algorithm will be deprecated in the future, replaced by a unified implementation +// rather than being Euclidean specific. Until the alternative is available, lets allow deprecations +// so as not to change the method signature for existing users. +#[allow(deprecated)] use crate::{ CoordFloat, Line, LineString, Point, {euclidean_distance::EuclideanDistance, euclidean_length::EuclideanLength}, @@ -75,6 +79,7 @@ where } } +#[allow(deprecated)] impl LineLocatePoint> for LineString where T: CoordFloat + AddAssign, diff --git a/geo/src/algorithm/line_measures/metric_spaces/euclidean.rs b/geo/src/algorithm/line_measures/metric_spaces/euclidean.rs index d753bb4e4..74dcb81fe 100644 --- a/geo/src/algorithm/line_measures/metric_spaces/euclidean.rs +++ b/geo/src/algorithm/line_measures/metric_spaces/euclidean.rs @@ -1,5 +1,5 @@ use super::super::Distance; -use crate::{GeoFloat, Point}; +use crate::{CoordFloat, Point}; /// Operations on the [Euclidean plane] measure distance with the pythagorean formula - /// what you'd measure with a ruler. @@ -19,7 +19,7 @@ use crate::{GeoFloat, Point}; pub struct Euclidean; /// Calculate the Euclidean distance (a.k.a. pythagorean distance) between two Points -impl Distance, Point> for Euclidean { +impl Distance, Point> for Euclidean { /// Calculate the Euclidean distance (a.k.a. pythagorean distance) between two Points /// /// # Units @@ -48,7 +48,8 @@ impl Distance, Point> for Euclidean { /// [`Geodesic`]: super::Geodesic /// [metric spaces]: super fn distance(origin: Point, destination: Point) -> F { - crate::EuclideanDistance::euclidean_distance(&origin, &destination) + let delta = origin - destination; + delta.x().hypot(delta.y()) } } diff --git a/geo/src/algorithm/line_measures/metric_spaces/haversine.rs b/geo/src/algorithm/line_measures/metric_spaces/haversine.rs index 869d6ad25..6813bbe77 100644 --- a/geo/src/algorithm/line_measures/metric_spaces/haversine.rs +++ b/geo/src/algorithm/line_measures/metric_spaces/haversine.rs @@ -23,7 +23,7 @@ impl Bearing for Haversine { /// # Units /// /// - `origin`, `destination`: Points where x/y are lon/lat degree coordinates - /// returns: degrees, where: North: 0°, East: 90°, South: 180°, West: 270° + /// - returns: degrees, where: North: 0°, East: 90°, South: 180°, West: 270° /// /// # Examples /// diff --git a/geo/src/algorithm/linestring_segment.rs b/geo/src/algorithm/linestring_segment.rs index 319cc4e13..b361c1069 100644 --- a/geo/src/algorithm/linestring_segment.rs +++ b/geo/src/algorithm/linestring_segment.rs @@ -1,6 +1,6 @@ use crate::line_interpolate_point::LineInterpolatePoint; use crate::{ - Coord, Densify, DensifyHaversine, EuclideanLength, HaversineLength, LineString, LinesIter, + Coord, Densify, DensifyHaversine, Euclidean, Haversine, Length, LineString, LinesIter, MultiLineString, }; @@ -47,7 +47,7 @@ pub trait LineStringSegmentizeHaversine { } macro_rules! implement_segmentize { - ($trait_name:ident, $method_name:ident, $distance_method:ident, $densify_method:ident) => { + ($trait_name:ident, $method_name:ident, $metric_space:ty, $densify_method:ident) => { impl $trait_name for LineString { fn $method_name(&self, n: usize) -> Option { if (n == usize::MIN) || (n == usize::MAX) { @@ -58,7 +58,7 @@ macro_rules! implement_segmentize { } let mut res_coords: Vec> = Vec::with_capacity(n); - let total_length = self.$distance_method().abs(); + let total_length = self.length::<$metric_space>(); let mut cum_length = 0_f64; let segment_prop = (1_f64) / (n as f64); let segment_length = total_length * segment_prop; @@ -81,7 +81,7 @@ macro_rules! implement_segmentize { ln_vec.push(segment.start) } - let length = segment.$distance_method().abs(); + let length = segment.length::<$metric_space>(); cum_length += length; if (cum_length >= segment_length) && (i != (n_lines - 1)) { @@ -112,17 +112,12 @@ macro_rules! implement_segmentize { }; } -implement_segmentize!( - LineStringSegmentize, - line_segmentize, - euclidean_length, - densify -); +implement_segmentize!(LineStringSegmentize, line_segmentize, Euclidean, densify); implement_segmentize!( LineStringSegmentizeHaversine, line_segmentize_haversine, - haversine_length, + Haversine, densify_haversine ); @@ -131,7 +126,7 @@ mod test { use approx::RelativeEq; use super::*; - use crate::{EuclideanLength, LineString}; + use crate::LineString; #[test] fn n_elems_bug() { @@ -157,7 +152,10 @@ mod test { let segments = linestring.line_segmentize(4).unwrap(); assert_eq!(segments.0.len(), 4); - assert_eq!(segments.euclidean_length(), linestring.euclidean_length()); + assert_eq!( + segments.length::(), + linestring.length::() + ); } #[test] @@ -176,8 +174,8 @@ mod test { let segments = linestring.line_segmentize(5).unwrap(); assert_eq!(segments.0.len(), 5); assert_relative_eq!( - linestring.euclidean_length(), - segments.euclidean_length(), + linestring.length::(), + segments.length::(), epsilon = f64::EPSILON ); } @@ -189,8 +187,8 @@ mod test { let segments = linestring.line_segmentize(5).unwrap(); assert_eq!(segments.0.len(), 5); assert_relative_eq!( - linestring.euclidean_length(), - segments.euclidean_length(), + linestring.length::(), + segments.length::(), epsilon = f64::EPSILON ); } @@ -227,8 +225,8 @@ mod test { assert_eq!(segments.0.len(), 5); assert_relative_eq!( - linestring.euclidean_length(), - segments.euclidean_length(), + linestring.length::(), + segments.length::(), epsilon = f64::EPSILON ); } @@ -259,7 +257,7 @@ mod test { // assert that the lines are equal length let lens = segments .into_iter() - .map(|x| x.euclidean_length()) + .map(|x| x.length::()) .collect::>(); let first = lens[0]; @@ -276,8 +274,8 @@ mod test { let segments = linestring.line_segmentize(2).unwrap(); assert_relative_eq!( - linestring.euclidean_length(), - segments.euclidean_length(), + linestring.length::(), + segments.length::(), epsilon = f64::EPSILON ) } @@ -335,7 +333,7 @@ mod test { let lens = segments .0 .iter() - .map(|li| li.haversine_length()) + .map(|li| li.length::()) .collect::>(); let epsilon = 1e-6; // 6th decimal place which is micrometers @@ -351,14 +349,16 @@ mod test { ] .into(); + assert_relative_eq!(linestring.length::(), 83.3523000093029); + let n = 8; let segments = linestring.line_segmentize_haversine(n).unwrap(); // different at 12th decimal which is a picometer assert_relative_eq!( - linestring.haversine_length(), - segments.haversine_length(), + linestring.length::(), + segments.length::(), epsilon = 1e-11 ); } diff --git a/geo/src/algorithm/mod.rs b/geo/src/algorithm/mod.rs index 24c146b6f..9ced466c7 100644 --- a/geo/src/algorithm/mod.rs +++ b/geo/src/algorithm/mod.rs @@ -84,6 +84,7 @@ pub use euclidean_distance::EuclideanDistance; /// Calculate the length of a planar line between two `Geometries`. pub mod euclidean_length; +#[allow(deprecated)] pub use euclidean_length::EuclideanLength; /// Calculate the extreme coordinates and indices of a geometry. @@ -119,6 +120,7 @@ pub use geodesic_intermediate::GeodesicIntermediate; /// Calculate the Geodesic length of a line. pub mod geodesic_length; +#[allow(deprecated)] pub use geodesic_length::GeodesicLength; /// Calculate the Hausdorff distance between two geometries. @@ -147,6 +149,7 @@ pub use haversine_intermediate::HaversineIntermediate; /// Calculate the Haversine length of a Line. pub mod haversine_length; +#[allow(deprecated)] pub use haversine_length::HaversineLength; /// Calculate the closest point on a Great Circle arc geometry to a given point. @@ -187,7 +190,7 @@ pub use lines_iter::LinesIter; pub mod line_measures; pub use line_measures::metric_spaces::{Euclidean, Geodesic, Haversine, Rhumb}; -pub use line_measures::{Bearing, Destination, Distance, InterpolatePoint}; +pub use line_measures::{Bearing, Destination, Distance, InterpolatePoint, Length}; /// Split a LineString into n segments pub mod linestring_segment; @@ -298,6 +301,5 @@ pub use monotone::{monotone_subdivision, MonoPoly, MonotonicPolygons}; /// Rhumb-line-related algorithms and utils pub mod rhumb; -pub use rhumb::RhumbLength; #[allow(deprecated)] -pub use rhumb::{RhumbBearing, RhumbDestination, RhumbDistance, RhumbIntermediate}; +pub use rhumb::{RhumbBearing, RhumbDestination, RhumbDistance, RhumbIntermediate, RhumbLength}; diff --git a/geo/src/algorithm/rhumb/length.rs b/geo/src/algorithm/rhumb/length.rs index 3aaf7dc8a..2e97021d9 100644 --- a/geo/src/algorithm/rhumb/length.rs +++ b/geo/src/algorithm/rhumb/length.rs @@ -1,6 +1,6 @@ use num_traits::FromPrimitive; -use crate::{CoordFloat, Distance, Line, LineString, MultiLineString, Rhumb}; +use crate::{CoordFloat, Length, Line, LineString, MultiLineString, Rhumb}; #[deprecated( since = "0.29.0", @@ -44,34 +44,32 @@ pub trait RhumbLength { fn rhumb_length(&self) -> T; } +#[allow(deprecated)] impl RhumbLength for Line where T: CoordFloat + FromPrimitive, { fn rhumb_length(&self) -> T { - let (start, end) = self.points(); - Rhumb::distance(start, end) + self.length::() } } +#[allow(deprecated)] impl RhumbLength for LineString where T: CoordFloat + FromPrimitive, { fn rhumb_length(&self) -> T { - self.lines().fold(T::zero(), |total_length, line| { - total_length + line.rhumb_length() - }) + self.length::() } } +#[allow(deprecated)] impl RhumbLength for MultiLineString where T: CoordFloat + FromPrimitive, { fn rhumb_length(&self) -> T { - self.0 - .iter() - .fold(T::zero(), |total, line| total + line.rhumb_length()) + self.length::() } } diff --git a/geo/src/algorithm/rhumb/mod.rs b/geo/src/algorithm/rhumb/mod.rs index 8c581b940..689fb497a 100644 --- a/geo/src/algorithm/rhumb/mod.rs +++ b/geo/src/algorithm/rhumb/mod.rs @@ -26,6 +26,7 @@ mod intermediate; pub use intermediate::RhumbIntermediate; mod length; +#[allow(deprecated)] pub use length::RhumbLength; pub(crate) struct RhumbCalculations {