Skip to content

Commit

Permalink
Merge #583
Browse files Browse the repository at this point in the history
583: Allow external crates to implement generic float methods for Geometry<T> r=rmanoka,urschrei a=michaelkirk

- [x] I agree to follow the project's [code of conduct](https://github.com/georust/geo/blob/master/CODE_OF_CONDUCT.md).
- [x] I added an entry to `CHANGES.md` if knowledge of this change could be valuable to users.
---

Solves #577 (see discussion there for context)

You can see it in use here: https://github.com/urschrei/polylabel-rs/pull/6/files


Co-authored-by: Michael Kirk <michael.code@endoftheworl.de>
  • Loading branch information
bors[bot] and michaelkirk committed Jan 1, 2021
2 parents 7dc6ef4 + 620dd58 commit bfe6d0e
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 96 deletions.
6 changes: 6 additions & 0 deletions geo/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@
* <https://github.com/georust/geo/pull/561>
* Add new `EuclideanDistance` implementations: `impl EuclideanDistance<Coordinate<T>> for Line`, `impl EuclideanDistance<Line> for Coordinate`, `impl EuclideanDistance<Coordinate> for Coordinate`
* <https://github.com/georust/geo/pull/580>
* Introduce `geo::Float` trait so external crates can implement methods which
operate on geometries generically.
* <https://github.com/georust/geo/pull/583>
* Make `HasKernel` public to allow geo on exotic numeric types.
* <https://github.com/georust/geo/pull/583>
* Fix panic when `simplify` is given a negative epsilon
* <https://github.com/georust/geo/pull/584>
* Performance improvements to `simplify`
* <https://github.com/georust/geo/pull/584>


## 0.16.0

* Fix panic when `simplify` is given a negative epsilon
Expand Down
26 changes: 13 additions & 13 deletions geo/src/algorithm/closest_point.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::kernels::*;
use crate::prelude::*;
use crate::{Closest, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon};
use num_traits::Float;
use crate::{
Closest, GeoFloat, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon,
};
use std::iter;

/// Find the closest `Point` between a given geometry and an input `Point`.
Expand All @@ -23,22 +23,22 @@ use std::iter;
/// let closest = horizontal_line.closest_point(&p);
/// assert_eq!(closest, Closest::SinglePoint(Point::new(0.0, 0.0)));
/// ```
pub trait ClosestPoint<F: Float, Rhs = Point<F>> {
pub trait ClosestPoint<F: GeoFloat, Rhs = Point<F>> {
/// Find the closest point between `self` and `p`.
fn closest_point(&self, p: &Rhs) -> Closest<F>;
}

impl<'a, F, C> ClosestPoint<F> for &'a C
where
C: ClosestPoint<F>,
F: Float,
F: GeoFloat,
{
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
(*self).closest_point(p)
}
}

impl<F: Float> ClosestPoint<F> for Point<F> {
impl<F: GeoFloat> ClosestPoint<F> for Point<F> {
fn closest_point(&self, p: &Self) -> Closest<F> {
if self == p {
Closest::Intersection(*self)
Expand All @@ -49,7 +49,7 @@ impl<F: Float> ClosestPoint<F> for Point<F> {
}

#[allow(clippy::many_single_char_names)]
impl<F: Float + HasKernel> ClosestPoint<F> for Line<F> {
impl<F: GeoFloat> ClosestPoint<F> for Line<F> {
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
let line_length = self.euclidean_length();
if line_length == F::zero() {
Expand Down Expand Up @@ -94,7 +94,7 @@ impl<F: Float + HasKernel> ClosestPoint<F> for Line<F> {
/// If the iterator is empty, we get `Closest::Indeterminate`.
fn closest_of<C, F, I>(iter: I, p: Point<F>) -> Closest<F>
where
F: Float,
F: GeoFloat,
I: IntoIterator<Item = C>,
C: ClosestPoint<F>,
{
Expand All @@ -108,32 +108,32 @@ where
best
}

impl<F: Float + HasKernel> ClosestPoint<F> for LineString<F> {
impl<F: GeoFloat> ClosestPoint<F> for LineString<F> {
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
closest_of(self.lines(), *p)
}
}

impl<F: Float + HasKernel> ClosestPoint<F> for Polygon<F> {
impl<F: GeoFloat> ClosestPoint<F> for Polygon<F> {
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
let prospectives = self.interiors().iter().chain(iter::once(self.exterior()));
closest_of(prospectives, *p)
}
}

impl<F: Float + HasKernel> ClosestPoint<F> for MultiPolygon<F> {
impl<F: GeoFloat> ClosestPoint<F> for MultiPolygon<F> {
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
closest_of(self.iter(), *p)
}
}

impl<F: Float> ClosestPoint<F> for MultiPoint<F> {
impl<F: GeoFloat> ClosestPoint<F> for MultiPoint<F> {
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
closest_of(self.iter(), *p)
}
}

impl<F: Float + HasKernel> ClosestPoint<F> for MultiLineString<F> {
impl<F: GeoFloat> ClosestPoint<F> for MultiLineString<F> {
fn closest_point(&self, p: &Point<F>) -> Closest<F> {
closest_of(self.iter(), *p)
}
Expand Down
20 changes: 10 additions & 10 deletions geo/src/algorithm/concave_hull.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::algorithm::convex_hull::qhull;
use crate::algorithm::euclidean_distance::EuclideanDistance;
use crate::algorithm::euclidean_length::EuclideanLength;
use crate::algorithm::kernels::HasKernel;
use crate::prelude::Centroid;
use crate::utils::partial_min;
use crate::{Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon};
use crate::{
GeoFloat, Line, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon,
};
use geo_types::{Coordinate, CoordinateType};
use num_traits::Float;
use rstar::{RTree, RTreeNum};
use std::collections::VecDeque;

Expand Down Expand Up @@ -51,7 +51,7 @@ pub trait ConcaveHull {

impl<T> ConcaveHull for Polygon<T>
where
T: Float + RTreeNum + HasKernel,
T: GeoFloat + RTreeNum,
{
type Scalar = T;
fn concave_hull(&self, concavity: Self::Scalar) -> Polygon<Self::Scalar> {
Expand All @@ -62,7 +62,7 @@ where

impl<T> ConcaveHull for MultiPolygon<T>
where
T: Float + RTreeNum + HasKernel,
T: GeoFloat + RTreeNum,
{
type Scalar = T;
fn concave_hull(&self, concavity: Self::Scalar) -> Polygon<Self::Scalar> {
Expand All @@ -77,7 +77,7 @@ where

impl<T> ConcaveHull for LineString<T>
where
T: Float + RTreeNum + HasKernel,
T: GeoFloat + RTreeNum,
{
type Scalar = T;
fn concave_hull(&self, concavity: Self::Scalar) -> Polygon<Self::Scalar> {
Expand All @@ -87,7 +87,7 @@ where

impl<T> ConcaveHull for MultiLineString<T>
where
T: Float + RTreeNum + HasKernel,
T: GeoFloat + RTreeNum,
{
type Scalar = T;
fn concave_hull(&self, concavity: T) -> Polygon<T> {
Expand All @@ -99,7 +99,7 @@ where

impl<T> ConcaveHull for MultiPoint<T>
where
T: Float + RTreeNum + HasKernel,
T: GeoFloat + RTreeNum,
{
type Scalar = T;
fn concave_hull(&self, concavity: T) -> Polygon<T> {
Expand All @@ -117,7 +117,7 @@ fn find_point_closest_to_line<T>(
line_tree: &RTree<Line<T>>,
) -> Option<Coordinate<T>>
where
T: Float + RTreeNum,
T: GeoFloat + RTreeNum,
{
let h = max_dist + max_dist;
let w = line.euclidean_length() + h;
Expand Down Expand Up @@ -188,7 +188,7 @@ where
// https://github.com/mapbox/concaveman/blob/54838e1/index.js#L11
fn concave_hull<T>(coords: &mut [Coordinate<T>], concavity: T) -> LineString<T>
where
T: Float + RTreeNum + HasKernel,
T: GeoFloat + RTreeNum,
{
let hull = qhull::quick_hull(coords);

Expand Down
Loading

0 comments on commit bfe6d0e

Please sign in to comment.