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

Customizable metric space for line measures #1298

Merged
merged 11 commits into from
Feb 3, 2025
1 change: 0 additions & 1 deletion geo-types/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

## Unreleased

- Fix page location of citation for mean earth radius used in Haversine calculations
- Implement `RTreeObject` for `Triangle`.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only moved this to geo/CHANGES.md where I think it belongs.

- Implement `AsRef<Coord>` for `Point` and `Coord`.

Expand Down
14 changes: 14 additions & 0 deletions geo/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

## Unreleased

- BREAKING: `Densify` and `Length` are now defined on the metric space, rather than a generic method on the geometry.
```
// before
line_string.length::<Euclidean>()
line_string.densify::<Euclidean>()

// after
Euclidean.length(&line_string)
Euclidean.densify(&line_string)
```
- Add `CustomHaversine` for doing calculations on spheres with a custom radius.
- <https://github.com/georust/geo/pull/1298>
- Fix page location of citation for mean earth radius used in Haversine calculations
- <https://github.com/georust/geo/pull/1297>
- Add top-level doc link for `InteriorPoint`
- Add Unary Union algorithm for fast union ops on adjacent / overlapping geometries
- <https://github.com/georust/geo/pull/1246>
Expand Down
4 changes: 2 additions & 2 deletions geo/benches/euclidean_distance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn criterion_benchmark(c: &mut criterion::Criterion) {
(x: -6.064453, y: 68.49604),
];
bencher.iter(|| {
criterion::black_box(Euclidean::distance(&poly1, &poly2));
criterion::black_box(Euclidean.distance(&poly1, &poly2));
});
});

Expand Down Expand Up @@ -79,7 +79,7 @@ fn criterion_benchmark(c: &mut criterion::Criterion) {
]
.convex_hull();
bencher.iter(|| {
criterion::black_box(Euclidean::distance(&poly1, &poly2));
criterion::black_box(Euclidean.distance(&poly1, &poly2));
});
},
);
Expand Down
2 changes: 1 addition & 1 deletion geo/benches/geodesic_distance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fn criterion_benchmark(c: &mut criterion::Criterion) {
let b = geo::Point::new(16.372477, 48.208810);

bencher.iter(|| {
criterion::black_box(criterion::black_box(Geodesic::distance(a, b)));
criterion::black_box(criterion::black_box(Geodesic.distance(a, b)));
});
});
}
Expand Down
8 changes: 3 additions & 5 deletions geo/src/algorithm/centroid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,11 +465,9 @@ impl<T: GeoFloat> CentroidOperation<T> {
fn add_line(&mut self, line: &Line<T>) {
match line.dimensions() {
ZeroDimensional => self.add_coord(line.start),
OneDimensional => self.add_centroid(
OneDimensional,
line.centroid().0,
line.length::<Euclidean>(),
),
OneDimensional => {
self.add_centroid(OneDimensional, line.centroid().0, Euclidean.length(line))
}
_ => unreachable!("Line must be zero or one dimensional"),
}
}
Expand Down
2 changes: 1 addition & 1 deletion geo/src/algorithm/closest_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<F: GeoFloat> ClosestPoint<F> for Point<F> {
#[allow(clippy::many_single_char_names)]
impl<F: GeoFloat> ClosestPoint<F> for Line<F> {
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
let line_length = self.length::<Euclidean>();
let line_length = Euclidean.length(self);
if line_length == F::zero() {
// if we've got a zero length line, technically the entire line
// is the closest point...
Expand Down
16 changes: 8 additions & 8 deletions geo/src/algorithm/concave_hull.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ where
T: GeoFloat + RTreeNum,
{
let h = max_dist + max_dist;
let w = line.length::<Euclidean>() + h;
let w = Euclidean.length(&line) + 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();
Expand All @@ -134,8 +134,8 @@ where
let closest_point =
candidates.fold(Point::new(point.x, point.y), |acc_point, candidate| {
let candidate_point = Point::new(candidate.x, candidate.y);
if Euclidean::distance(&line, &acc_point)
> Euclidean::distance(&line, &candidate_point)
if Euclidean.distance(&line, &acc_point)
> Euclidean.distance(&line, &candidate_point)
{
candidate_point
} else {
Expand All @@ -154,8 +154,8 @@ where
let closest_edge_option = match peeked_edge {
None => None,
Some(&edge) => Some(edges_nearby_point.fold(*edge, |acc, candidate| {
if Euclidean::distance(&closest_point, &acc)
> Euclidean::distance(&closest_point, candidate)
if Euclidean.distance(&closest_point, &acc)
> Euclidean.distance(&closest_point, candidate)
{
*candidate
} else {
Expand All @@ -164,8 +164,8 @@ where
})),
};
let decision_distance = partial_min(
Euclidean::distance(&closest_point, &line.start_point()),
Euclidean::distance(&closest_point, &line.end_point()),
Euclidean.distance(&closest_point, &line.start_point()),
Euclidean.distance(&closest_point, &line.end_point()),
);
if let Some(closest_edge) = closest_edge_option {
let far_enough = edge_length / decision_distance > concavity;
Expand Down Expand Up @@ -217,7 +217,7 @@ where
line_tree.insert(line);
}
while let Some(line) = line_queue.pop_front() {
let edge_length = line.length::<Euclidean>();
let edge_length = Euclidean.length(&line);
let dist = edge_length / concavity;
let possible_closest_point = find_point_closest_to_line(
&interior_points_tree,
Expand Down
10 changes: 5 additions & 5 deletions geo/src/algorithm/cross_track_distance.rs
Original file line number Diff line number Diff line change
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 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
16 changes: 8 additions & 8 deletions geo/src/algorithm/densify_haversine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{

#[deprecated(
since = "0.29.0",
note = "Please use the `line.densify::<Haversine>()` 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 {
self.densify::<Haversine>(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 {
self.densify::<Haversine>(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 {
self.densify::<Haversine>(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 {
self.densify::<Haversine>(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 {
self.densify::<Haversine>(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 {
self.densify::<Haversine>(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 {
self.densify::<Haversine>(max_distance)
Haversine.densify(self, max_distance)
}
}

Expand Down
Loading
Loading