Skip to content

Commit

Permalink
Make all Haversine customizable, removing CustomHaversine
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelkirk committed Jan 16, 2025
1 parent 0688393 commit 0dcb842
Show file tree
Hide file tree
Showing 17 changed files with 149 additions and 208 deletions.
12 changes: 10 additions & 2 deletions geo/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Unreleased

- BREAKING: `Densify` and `Length` are now defined on the metric space, rather than a generic method on the geometry.
```
```rust
// before
line_string.length::<Euclidean>()
line_string.densify::<Euclidean>()
Expand All @@ -12,8 +12,16 @@
Euclidean.length(&line_string)
Euclidean.densify(&line_string)
```
- Add `CustomHaversine` for doing calculations on spheres with a custom radius.
- `Haversine` can be configured with a custom radius for doing calculations on custom sphere. Use `HAVERSINE` for the default earth radius.
- <https://github.com/georust/geo/pull/1298>
```rust
// before
Haversine::distance(point1, point2)

// after
Haversine::new(3_389_500.0).distance(point1, point2)
HAVERSINE.distance(point_1, point_2)
```
- Docs: Fix page location of citation for mean earth radius used in Haversine calculations
- <https://github.com/georust/geo/pull/1297>
- Docs: Add top-level doc link for `InteriorPoint`
Expand Down
14 changes: 7 additions & 7 deletions geo/src/algorithm/cross_track_distance.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Bearing, Distance, Haversine, MEAN_EARTH_RADIUS};
use crate::{Bearing, Distance, HAVERSINE, MEAN_EARTH_RADIUS};
use geo_types::{CoordFloat, Point};
use num_traits::FromPrimitive;

Expand Down Expand Up @@ -43,9 +43,9 @@ where
{
fn cross_track_distance(&self, line_point_a: &Point<T>, line_point_b: &Point<T>) -> T {
let mean_earth_radius = T::from(MEAN_EARTH_RADIUS).unwrap();
let l_delta_13: T = Haversine.distance(*line_point_a, *self) / mean_earth_radius;
let theta_13: T = Haversine.bearing(*line_point_a, *self).to_radians();
let theta_12: T = Haversine.bearing(*line_point_a, *line_point_b).to_radians();
let l_delta_13: T = HAVERSINE.distance(*line_point_a, *self) / mean_earth_radius;
let theta_13: T = HAVERSINE.bearing(*line_point_a, *self).to_radians();
let theta_12: T = HAVERSINE.bearing(*line_point_a, *line_point_b).to_radians();
let l_delta_xt: T = (l_delta_13.sin() * (theta_12 - theta_13).sin()).asin();
mean_earth_radius * l_delta_xt.abs()
}
Expand All @@ -55,7 +55,7 @@ where
mod test {
use crate::CrossTrackDistance;
use crate::Point;
use crate::{Distance, Haversine};
use crate::{Distance, HAVERSINE};

#[test]
fn distance1_test() {
Expand Down Expand Up @@ -90,13 +90,13 @@ mod test {

assert_relative_eq!(
p.cross_track_distance(&line_point_a, &line_point_b),
Haversine.distance(p, Point::new(1., 0.)),
HAVERSINE.distance(p, Point::new(1., 0.)),
epsilon = 1.0e-6
);

assert_relative_eq!(
p.cross_track_distance(&line_point_b, &line_point_a),
Haversine.distance(p, Point::new(1., 0.)),
HAVERSINE.distance(p, Point::new(1., 0.)),
epsilon = 1.0e-6
);
}
Expand Down
18 changes: 9 additions & 9 deletions geo/src/algorithm/densify_haversine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use num_traits::FromPrimitive;

use crate::line_measures::Haversine;
use crate::line_measures::HAVERSINE;
// Densify will soon be deprecated too, so let's just allow deprecated for now
#[allow(deprecated)]
use crate::HaversineLength;
Expand All @@ -10,7 +10,7 @@ use crate::{

#[deprecated(
since = "0.29.0",
note = "Please use the `Haversine.densify(&line)` via the `Densify` trait instead."
note = "Please use the `HAVERSINE.densify(&line)` via the `Densify` trait instead."
)]
/// Returns a new spherical geometry containing both existing and new interpolated coordinates with
/// a maximum distance of `max_distance` between them.
Expand Down Expand Up @@ -50,7 +50,7 @@ where
type Output = MultiPolygon<T>;

fn densify_haversine(&self, max_distance: T) -> Self::Output {
Haversine.densify(self, max_distance)
HAVERSINE.densify(self, max_distance)
}
}

Expand All @@ -64,7 +64,7 @@ where
type Output = Polygon<T>;

fn densify_haversine(&self, max_distance: T) -> Self::Output {
Haversine.densify(self, max_distance)
HAVERSINE.densify(self, max_distance)
}
}

Expand All @@ -78,7 +78,7 @@ where
type Output = MultiLineString<T>;

fn densify_haversine(&self, max_distance: T) -> Self::Output {
Haversine.densify(self, max_distance)
HAVERSINE.densify(self, max_distance)
}
}

Expand All @@ -92,7 +92,7 @@ where
type Output = LineString<T>;

fn densify_haversine(&self, max_distance: T) -> Self::Output {
Haversine.densify(self, max_distance)
HAVERSINE.densify(self, max_distance)
}
}

Expand All @@ -106,7 +106,7 @@ where
type Output = LineString<T>;

fn densify_haversine(&self, max_distance: T) -> Self::Output {
Haversine.densify(self, max_distance)
HAVERSINE.densify(self, max_distance)
}
}

Expand All @@ -120,7 +120,7 @@ where
type Output = Polygon<T>;

fn densify_haversine(&self, max_distance: T) -> Self::Output {
Haversine.densify(self, max_distance)
HAVERSINE.densify(self, max_distance)
}
}

Expand All @@ -134,7 +134,7 @@ where
type Output = Polygon<T>;

fn densify_haversine(&self, max_distance: T) -> Self::Output {
Haversine.densify(self, max_distance)
HAVERSINE.densify(self, max_distance)
}
}

Expand Down
2 changes: 1 addition & 1 deletion geo/src/algorithm/haversine_bearing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{CoordFloat, Point};

#[deprecated(
since = "0.29.0",
note = "Please use the `Haversine.bearing` method from the `Bearing` trait instead"
note = "Please use the `HAVERSINE.bearing` method from the `Bearing` trait instead"
)]
/// Returns the bearing to another Point in degrees.
///
Expand Down
22 changes: 11 additions & 11 deletions geo/src/algorithm/haversine_closest_point.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::line_measures::{Bearing, Destination, Distance, Haversine};
use crate::line_measures::{Bearing, Destination, Distance, HAVERSINE};
use crate::{Closest, Contains};
use crate::{CoordsIter, GeoFloat, Point, MEAN_EARTH_RADIUS};
use geo_types::{
Expand Down Expand Up @@ -92,7 +92,7 @@ where
}

// This can probably be done cheaper
let d3 = Haversine.distance(p2, p1);
let d3 = HAVERSINE.distance(p2, p1);
if d3 <= T::epsilon() {
// I think here it should be return Closest::SinglePoint(p1)
// If the line segment is degenerated to a point, that point is still the closest
Expand All @@ -102,18 +102,18 @@ where
}

let pi = T::from(std::f64::consts::PI).unwrap();
let crs_ad = Haversine.bearing(p1, *from).to_radians();
let crs_ab = Haversine.bearing(p1, p2).to_radians();
let crs_ad = HAVERSINE.bearing(p1, *from).to_radians();
let crs_ab = HAVERSINE.bearing(p1, p2).to_radians();
let crs_ba = if crs_ab > T::zero() {
crs_ab - pi
} else {
crs_ab + pi
};
let crs_bd = Haversine.bearing(p2, *from).to_radians();
let crs_bd = HAVERSINE.bearing(p2, *from).to_radians();
let d_crs1 = crs_ad - crs_ab;
let d_crs2 = crs_bd - crs_ba;

let d1 = Haversine.distance(p1, *from);
let d1 = HAVERSINE.distance(p1, *from);

// d1, d2, d3 are in principle not needed, only the sign matters
let projection1 = d_crs1.cos();
Expand All @@ -127,13 +127,13 @@ where
if xtd < T::epsilon() {
return Closest::Intersection(*from);
} else {
return Closest::SinglePoint(Haversine.destination(p1, crs_ab.to_degrees(), atd));
return Closest::SinglePoint(HAVERSINE.destination(p1, crs_ab.to_degrees(), atd));
}
}

// Projected falls outside the GC Arc
// Return shortest distance pt, project either on point sp1 or sp2
let d2 = Haversine.distance(p2, *from);
let d2 = HAVERSINE.distance(p2, *from);
if d1 < d2 {
return Closest::SinglePoint(p1);
}
Expand Down Expand Up @@ -166,7 +166,7 @@ where
return intersect;
}
Closest::SinglePoint(pt) => {
let dist = Haversine.distance(pt, *from);
let dist = HAVERSINE.distance(pt, *from);
if dist < min_distance {
min_distance = dist;
rv = Closest::SinglePoint(pt);
Expand Down Expand Up @@ -198,7 +198,7 @@ where
return (intersect, T::zero());
}
Closest::SinglePoint(pt) => {
let dist = Haversine.distance(pt, *from);
let dist = HAVERSINE.distance(pt, *from);
if dist < min_distance {
min_distance = dist;
rv = Closest::SinglePoint(pt);
Expand Down Expand Up @@ -301,7 +301,7 @@ where
// This mean on top of the line.
Closest::Intersection(pt) => return Closest::Intersection(pt),
Closest::SinglePoint(pt) => {
let dist = Haversine.distance(pt, *from);
let dist = HAVERSINE.distance(pt, *from);
if dist < min_distance {
min_distance = dist;
rv = Closest::SinglePoint(pt);
Expand Down
6 changes: 3 additions & 3 deletions geo/src/algorithm/haversine_destination.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{CoordFloat, Destination, Haversine, Point};
use crate::{CoordFloat, Destination, Point, HAVERSINE};
use num_traits::FromPrimitive;

#[deprecated(
since = "0.29.0",
note = "Please use the `Haversine.destination` method from the `Destination` trait instead"
note = "Please use the `HAVERSINE.destination` method from the `Destination` trait instead"
)]
/// Returns a new Point using the distance to the existing Point and a bearing for the direction
///
Expand Down Expand Up @@ -39,7 +39,7 @@ where
T: CoordFloat + FromPrimitive,
{
fn haversine_destination(&self, bearing: T, distance: T) -> Point<T> {
Haversine.destination(*self, bearing, distance)
HAVERSINE.destination(*self, bearing, distance)
}
}

Expand Down
6 changes: 3 additions & 3 deletions geo/src/algorithm/haversine_distance.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{CoordFloat, Distance, Haversine, Point};
use crate::{CoordFloat, Distance, Point, HAVERSINE};
use num_traits::FromPrimitive;

#[deprecated(
since = "0.29.0",
note = "Please use the `Haversine.distance` method from the `Distance` trait instead"
note = "Please use the `HAVERSINE.distance` method from the `Distance` trait instead"
)]
/// Determine the distance between two geometries using the [haversine formula].
///
Expand Down Expand Up @@ -55,7 +55,7 @@ where
T: CoordFloat + FromPrimitive,
{
fn haversine_distance(&self, rhs: &Point<T>) -> T {
Haversine.distance(*self, *rhs)
HAVERSINE.distance(*self, *rhs)
}
}

Expand Down
10 changes: 5 additions & 5 deletions geo/src/algorithm/haversine_intermediate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{CoordFloat, Haversine, InterpolatePoint, Point};
use crate::{CoordFloat, InterpolatePoint, Point, HAVERSINE};
use num_traits::FromPrimitive;

#[deprecated(
Expand All @@ -9,7 +9,7 @@ use num_traits::FromPrimitive;
pub trait HaversineIntermediate<T: CoordFloat> {
#[deprecated(
since = "0.29.0",
note = "Please use `Haversine.point_at_ratio_between` from the `InterpolatePoint` trait instead"
note = "Please use `HAVERSINE.point_at_ratio_between` from the `InterpolatePoint` trait instead"
)]
/// Returns a new `Point` along a great circle route between `self` and `other`.
///
Expand Down Expand Up @@ -40,7 +40,7 @@ pub trait HaversineIntermediate<T: CoordFloat> {

#[deprecated(
since = "0.29.0",
note = "Please use `Haversine.points_along_line` from the `InterpolatePoint` trait instead"
note = "Please use `HAVERSINE.points_along_line` from the `InterpolatePoint` trait instead"
)]
/// Interpolates `Point`s along a great circle route between self and `other`.
///
Expand All @@ -62,7 +62,7 @@ where
T: CoordFloat + FromPrimitive,
{
fn haversine_intermediate(&self, other: &Point<T>, ratio: T) -> Point<T> {
Haversine.point_at_ratio_between(*self, *other, ratio)
HAVERSINE.point_at_ratio_between(*self, *other, ratio)
}

fn haversine_intermediate_fill(
Expand All @@ -71,7 +71,7 @@ where
max_dist: T,
include_ends: bool,
) -> Vec<Point<T>> {
Haversine
HAVERSINE
.points_along_line(*self, *other, max_dist, include_ends)
.collect()
}
Expand Down
10 changes: 5 additions & 5 deletions geo/src/algorithm/haversine_length.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use num_traits::FromPrimitive;

use crate::{CoordFloat, Line, LineString, MultiLineString};
use crate::{Haversine, Length};
use crate::{Length, HAVERSINE};

#[deprecated(
since = "0.29.0",
note = "Please use the `Haversine.length(&line)` via the `Length` trait instead."
note = "Please use the `HAVERSINE.length(&line)` via the `Length` trait instead."
)]
/// Determine the length of a geometry using the [haversine formula].
///
Expand Down Expand Up @@ -51,7 +51,7 @@ where
T: CoordFloat + FromPrimitive,
{
fn haversine_length(&self) -> T {
Haversine.length(self)
HAVERSINE.length(self)
}
}

Expand All @@ -61,7 +61,7 @@ where
T: CoordFloat + FromPrimitive,
{
fn haversine_length(&self) -> T {
Haversine.length(self)
HAVERSINE.length(self)
}
}

Expand All @@ -71,6 +71,6 @@ where
T: CoordFloat + FromPrimitive,
{
fn haversine_length(&self) -> T {
Haversine.length(self)
HAVERSINE.length(self)
}
}
Loading

0 comments on commit 0dcb842

Please sign in to comment.