Skip to content

Commit f683c7a

Browse files
authored
Merge pull request #1228 from georust/mkirk/unify-length
unify `Length` trait (deprecate `EuclideanLength`, `HaversineLength`, etc.)
2 parents 1cafb00 + c3fc7c9 commit f683c7a

21 files changed

+282
-90
lines changed

geo/CHANGES.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@
4343
* `RhumbBearing`, `RhumbDistance`, `RhumbDestination`, `RhumbIntermediate`
4444
* `HaversineBearing`, `HaversineDistance`, `HaversineDestination`, `HaversineIntermediate`
4545
* <https://github.com/georust/geo/pull/1222>
46+
* Deprecated `HaversineLength`, `EuclideanLength`, `RhumbLength`, `GeodesicLength` in favor of new generic `Length` trait.
47+
```
48+
// Before
49+
line_string.euclidean_length();
50+
line_string.haversine_length();
51+
// After
52+
line_string.length::<Euclidean>();
53+
line_string.length::<Haversine>();
54+
```
55+
* <https://github.com/georust/geo/pull/1228>
4656
* Change IntersectionMatrix::is_equal_topo to now consider empty geometries as equal.
4757
* <https://github.com/georust/geo/pull/1223>
4858
* Fix `(LINESTRING EMPTY).contains(LINESTRING EMPTY)` and `(MULTIPOLYGON EMPTY).contains(MULTIPOINT EMPTY)` which previously
@@ -53,7 +63,6 @@
5363
* <https://github.com/georust/geo/pull/1226>
5464
* Enable i128 geometry types
5565
* <https://github.com/georust/geo/pull/1230>
56-
5766
## 0.28.0
5867

5968
* BREAKING: The `HasKernel` trait was removed and it's functionality was merged

geo/src/algorithm/centroid.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::cmp::Ordering;
33
use crate::area::{get_linestring_area, Area};
44
use crate::dimensions::{Dimensions, Dimensions::*, HasDimensions};
55
use crate::geometry::*;
6-
use crate::EuclideanLength;
6+
use crate::line_measures::{Euclidean, Length};
77
use crate::GeoFloat;
88

99
/// Calculation of the centroid.
@@ -465,9 +465,11 @@ impl<T: GeoFloat> CentroidOperation<T> {
465465
fn add_line(&mut self, line: &Line<T>) {
466466
match line.dimensions() {
467467
ZeroDimensional => self.add_coord(line.start),
468-
OneDimensional => {
469-
self.add_centroid(OneDimensional, line.centroid().0, line.euclidean_length())
470-
}
468+
OneDimensional => self.add_centroid(
469+
OneDimensional,
470+
line.centroid().0,
471+
line.length::<Euclidean>(),
472+
),
471473
_ => unreachable!("Line must be zero or one dimensional"),
472474
}
473475
}

geo/src/algorithm/closest_point.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::algorithm::{EuclideanLength, Intersects};
1+
use crate::algorithm::{Euclidean, Intersects, Length};
22
use crate::geometry::*;
33
use crate::Closest;
44
use crate::GeoFloat;
@@ -52,7 +52,7 @@ impl<F: GeoFloat> ClosestPoint<F> for Point<F> {
5252
#[allow(clippy::many_single_char_names)]
5353
impl<F: GeoFloat> ClosestPoint<F> for Line<F> {
5454
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
55-
let line_length = self.euclidean_length();
55+
let line_length = self.length::<Euclidean>();
5656
if line_length == F::zero() {
5757
// if we've got a zero length line, technically the entire line
5858
// is the closest point...

geo/src/algorithm/concave_hull.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::convex_hull::qhull;
22
use crate::utils::partial_min;
33
use crate::{
4-
coord, Centroid, Coord, CoordNum, EuclideanDistance, EuclideanLength, GeoFloat, Line,
4+
coord, Centroid, Coord, CoordNum, Euclidean, EuclideanDistance, GeoFloat, Length, Line,
55
LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon,
66
};
77
use rstar::{RTree, RTreeNum};
@@ -116,7 +116,7 @@ where
116116
T: GeoFloat + RTreeNum,
117117
{
118118
let h = max_dist + max_dist;
119-
let w = line.euclidean_length() + h;
119+
let w = line.length::<Euclidean>() + h;
120120
let two = T::add(T::one(), T::one());
121121
let search_dist = T::div(T::sqrt(T::powi(w, 2) + T::powi(h, 2)), two);
122122
let centroid = line.centroid();
@@ -217,7 +217,7 @@ where
217217
line_tree.insert(line);
218218
}
219219
while let Some(line) = line_queue.pop_front() {
220-
let edge_length = line.euclidean_length();
220+
let edge_length = line.length::<Euclidean>();
221221
let dist = edge_length / concavity;
222222
let possible_closest_point = find_point_closest_to_line(
223223
&interior_points_tree,

geo/src/algorithm/densify.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
use crate::{
2-
CoordFloat, EuclideanLength, Line, LineInterpolatePoint, LineString, MultiLineString,
3-
MultiPolygon, Point, Polygon, Rect, Triangle,
2+
CoordFloat, Line, LineInterpolatePoint, LineString, MultiLineString, MultiPolygon, Point,
3+
Polygon, Rect, Triangle,
44
};
55

6+
// This is still used in the trait constraints - but Densify too will soon be replaced with a
7+
// generic version, at which point this implementation detail can be removed.
8+
#[allow(deprecated)]
9+
use crate::EuclideanLength;
10+
611
/// Return a new linear geometry containing both existing and new interpolated coordinates with
712
/// a maximum distance of `max_distance` between them.
813
///
@@ -26,6 +31,7 @@ pub trait Densify<F: CoordFloat> {
2631
}
2732

2833
// Helper for densification trait
34+
#[allow(deprecated)]
2935
fn densify_line<T: CoordFloat>(line: Line<T>, container: &mut Vec<Point<T>>, max_distance: T) {
3036
assert!(max_distance > T::zero());
3137
container.push(line.start_point());
@@ -44,6 +50,7 @@ fn densify_line<T: CoordFloat>(line: Line<T>, container: &mut Vec<Point<T>>, max
4450
}
4551
}
4652

53+
#[allow(deprecated)]
4754
impl<T> Densify<T> for MultiPolygon<T>
4855
where
4956
T: CoordFloat,
@@ -61,6 +68,7 @@ where
6168
}
6269
}
6370

71+
#[allow(deprecated)]
6472
impl<T> Densify<T> for Polygon<T>
6573
where
6674
T: CoordFloat,
@@ -80,6 +88,7 @@ where
8088
}
8189
}
8290

91+
#[allow(deprecated)]
8392
impl<T> Densify<T> for MultiLineString<T>
8493
where
8594
T: CoordFloat,
@@ -97,6 +106,7 @@ where
97106
}
98107
}
99108

109+
#[allow(deprecated)]
100110
impl<T> Densify<T> for LineString<T>
101111
where
102112
T: CoordFloat,
@@ -120,6 +130,7 @@ where
120130
}
121131
}
122132

133+
#[allow(deprecated)]
123134
impl<T> Densify<T> for Line<T>
124135
where
125136
T: CoordFloat,
@@ -137,6 +148,7 @@ where
137148
}
138149
}
139150

151+
#[allow(deprecated)]
140152
impl<T> Densify<T> for Triangle<T>
141153
where
142154
T: CoordFloat,
@@ -150,6 +162,7 @@ where
150162
}
151163
}
152164

165+
#[allow(deprecated)]
153166
impl<T> Densify<T> for Rect<T>
154167
where
155168
T: CoordFloat,

geo/src/algorithm/densify_haversine.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use num_traits::FromPrimitive;
22

3-
use crate::line_measures::{Haversine, InterpolatePoint};
3+
use crate::line_measures::{Haversine, InterpolatePoint, Length};
4+
// Densify will soon be deprecated too, so let's just allow deprecated for now
5+
#[allow(deprecated)]
46
use crate::HaversineLength;
57
use crate::{
68
CoordFloat, CoordsIter, Line, LineString, MultiLineString, MultiPolygon, Point, Polygon, Rect,
@@ -42,7 +44,7 @@ fn densify_line<T: CoordFloat + FromPrimitive>(
4244
) {
4345
assert!(max_distance > T::zero());
4446
container.push(line.start_point());
45-
let num_segments = (line.haversine_length() / max_distance)
47+
let num_segments = (line.length::<Haversine>() / max_distance)
4648
.ceil()
4749
.to_u64()
4850
.unwrap();
@@ -57,6 +59,7 @@ fn densify_line<T: CoordFloat + FromPrimitive>(
5759
}
5860
}
5961

62+
#[allow(deprecated)]
6063
impl<T> DensifyHaversine<T> for MultiPolygon<T>
6164
where
6265
T: CoordFloat + FromPrimitive,
@@ -74,6 +77,7 @@ where
7477
}
7578
}
7679

80+
#[allow(deprecated)]
7781
impl<T> DensifyHaversine<T> for Polygon<T>
7882
where
7983
T: CoordFloat + FromPrimitive,
@@ -93,6 +97,7 @@ where
9397
}
9498
}
9599

100+
#[allow(deprecated)]
96101
impl<T> DensifyHaversine<T> for MultiLineString<T>
97102
where
98103
T: CoordFloat + FromPrimitive,
@@ -110,6 +115,7 @@ where
110115
}
111116
}
112117

118+
#[allow(deprecated)]
113119
impl<T> DensifyHaversine<T> for LineString<T>
114120
where
115121
T: CoordFloat + FromPrimitive,
@@ -132,6 +138,7 @@ where
132138
}
133139
}
134140

141+
#[allow(deprecated)]
135142
impl<T> DensifyHaversine<T> for Line<T>
136143
where
137144
T: CoordFloat + FromPrimitive,
@@ -149,6 +156,7 @@ where
149156
}
150157
}
151158

159+
#[allow(deprecated)]
152160
impl<T> DensifyHaversine<T> for Triangle<T>
153161
where
154162
T: CoordFloat + FromPrimitive,
@@ -162,6 +170,7 @@ where
162170
}
163171
}
164172

173+
#[allow(deprecated)]
165174
impl<T> DensifyHaversine<T> for Rect<T>
166175
where
167176
T: CoordFloat + FromPrimitive,

geo/src/algorithm/euclidean_distance.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use crate::utils::{coord_pos_relative_to_ring, CoordPos};
2-
use crate::EuclideanLength;
3-
use crate::Intersects;
42
use crate::{
53
Coord, GeoFloat, GeoNum, Geometry, GeometryCollection, Line, LineString, MultiLineString,
64
MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle,
75
};
6+
use crate::{Distance, Euclidean, Intersects};
87
use num_traits::{float::FloatConst, Bounded, Float, Signed};
98

109
use rstar::primitives::CachedEnvelope;
@@ -104,7 +103,7 @@ where
104103
{
105104
/// Minimum distance between two `Coord`s
106105
fn euclidean_distance(&self, c: &Coord<T>) -> T {
107-
Line::new(*self, *c).euclidean_length()
106+
Euclidean::distance((*self).into(), (*c).into())
108107
}
109108
}
110109

geo/src/algorithm/euclidean_length.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
use std::iter::Sum;
22

3-
use crate::{CoordFloat, Line, LineString, MultiLineString};
3+
use crate::{CoordFloat, Euclidean, Length, Line, LineString, MultiLineString};
44

55
/// Calculation of the length
66
7+
#[deprecated(
8+
since = "0.29.0",
9+
note = "Please use the `line.length::<Euclidean>()` via the `Length` trait instead."
10+
)]
711
pub trait EuclideanLength<T, RHS = Self> {
812
/// Calculation of the length of a Line
913
///
@@ -26,51 +30,56 @@ pub trait EuclideanLength<T, RHS = Self> {
2630
fn euclidean_length(&self) -> T;
2731
}
2832

33+
#[allow(deprecated)]
2934
impl<T> EuclideanLength<T> for Line<T>
3035
where
3136
T: CoordFloat,
3237
{
3338
fn euclidean_length(&self) -> T {
34-
::geo_types::private_utils::line_euclidean_length(*self)
39+
self.length::<Euclidean>()
3540
}
3641
}
3742

43+
#[allow(deprecated)]
3844
impl<T> EuclideanLength<T> for LineString<T>
3945
where
4046
T: CoordFloat + Sum,
4147
{
4248
fn euclidean_length(&self) -> T {
43-
self.lines().map(|line| line.euclidean_length()).sum()
49+
self.length::<Euclidean>()
4450
}
4551
}
4652

53+
#[allow(deprecated)]
4754
impl<T> EuclideanLength<T> for MultiLineString<T>
4855
where
4956
T: CoordFloat + Sum,
5057
{
5158
fn euclidean_length(&self) -> T {
52-
self.0
53-
.iter()
54-
.fold(T::zero(), |total, line| total + line.euclidean_length())
59+
self.length::<Euclidean>()
5560
}
5661
}
5762

5863
#[cfg(test)]
5964
mod test {
6065
use crate::line_string;
66+
#[allow(deprecated)]
6167
use crate::EuclideanLength;
6268
use crate::{coord, Line, MultiLineString};
6369

70+
#[allow(deprecated)]
6471
#[test]
6572
fn empty_linestring_test() {
6673
let linestring = line_string![];
6774
assert_relative_eq!(0.0_f64, linestring.euclidean_length());
6875
}
76+
#[allow(deprecated)]
6977
#[test]
7078
fn linestring_one_point_test() {
7179
let linestring = line_string![(x: 0., y: 0.)];
7280
assert_relative_eq!(0.0_f64, linestring.euclidean_length());
7381
}
82+
#[allow(deprecated)]
7483
#[test]
7584
fn linestring_test() {
7685
let linestring = line_string![
@@ -83,6 +92,7 @@ mod test {
8392
];
8493
assert_relative_eq!(10.0_f64, linestring.euclidean_length());
8594
}
95+
#[allow(deprecated)]
8696
#[test]
8797
fn multilinestring_test() {
8898
let mline = MultiLineString::new(vec![
@@ -101,6 +111,7 @@ mod test {
101111
]);
102112
assert_relative_eq!(15.0_f64, mline.euclidean_length());
103113
}
114+
#[allow(deprecated)]
104115
#[test]
105116
fn line_test() {
106117
let line0 = Line::new(coord! { x: 0., y: 0. }, coord! { x: 0., y: 1. });

geo/src/algorithm/geodesic_area.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ impl GeodesicArea<f64> for Geometry<f64> {
350350
#[cfg(test)]
351351
mod test {
352352
use super::*;
353-
use crate::algorithm::geodesic_length::GeodesicLength;
353+
use crate::algorithm::line_measures::{Geodesic, Length};
354354
use crate::polygon;
355355

356356
#[test]
@@ -380,7 +380,7 @@ mod test {
380380

381381
// Confirm that the exterior ring geodesic_length is the same as the perimeter
382382
assert_relative_eq!(
383-
polygon.exterior().geodesic_length(),
383+
polygon.exterior().length::<Geodesic>(),
384384
polygon.geodesic_perimeter()
385385
);
386386
}
@@ -410,7 +410,7 @@ mod test {
410410

411411
// Confirm that the exterior ring geodesic_length is the same as the perimeter
412412
assert_relative_eq!(
413-
polygon.exterior().geodesic_length(),
413+
polygon.exterior().length::<Geodesic>(),
414414
polygon.geodesic_perimeter()
415415
);
416416
}
@@ -440,7 +440,7 @@ mod test {
440440

441441
// Confirm that the exterior ring geodesic_length is the same as the perimeter
442442
assert_relative_eq!(
443-
polygon.exterior().geodesic_length(),
443+
polygon.exterior().length::<Geodesic>(),
444444
polygon.geodesic_perimeter()
445445
);
446446
}

0 commit comments

Comments
 (0)