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

getting one of the closest point for Closest::Indeterminate #1167

Open
kraktus opened this issue Apr 3, 2024 · 4 comments
Open

getting one of the closest point for Closest::Indeterminate #1167

kraktus opened this issue Apr 3, 2024 · 4 comments
Labels

Comments

@kraktus
Copy link

kraktus commented Apr 3, 2024

Hello, thanks for the great lib!

When using geo::algorithm::closest_point::ClosestPoint, is there a one of the closest point when the result is Closest:: Indeterminate? If defined

@michaelkirk
Copy link
Member

I'm sorry but I don't understand your question. Can you try to rephrase it or give a more specific example?

The docs for Indeterminate if you haven't seen them: https://docs.rs/geo/latest/geo/enum.Closest.html#variant.Indeterminate

@kraktus
Copy link
Author

kraktus commented May 15, 2024

Sorry, some words got missing in my issue. When there is an "infinite number of closest points", is there a way a method that retrieves one of those?

My real use case was:

  • I want to compute the haversine distance between a point and a polygon, but since it is not defined, I approximate it by
  • Computing the closest point between the polygon and the point
  • computing the haversine distance between one polygon and the closest point of the polygon

extract from my code

// licence: AGPLv3
            let arp_pt = airport.to_point();
            let Closest::SinglePoint(closest_point) = polygon.closest_point(&arp_pt) else {
                panic!("no closest point")
            };
            let distance_m = arp_pt.haversine_distance(&closest_point) as usize;

In case of of Indeterminate, I would be fine with any one of closest points. For now I bailed out, fortunately it didn't happen in practice

@michaelkirk
Copy link
Member

michaelkirk commented Oct 31, 2024

I'm wondering if we should get rid of the Indeterminate case.

Here's where it's currently used in the euclidean implementation:

         if line_length == F::zero() {
            // if we've got a zero length line, technically the entire line
            // is the closest point...
            return Closest::Indeterminate;
        }

Arguably we could do something like:

         if line_length == F::zero() {
            // if we've got a zero length line, technically the entire line
            // is the closest point...
-            return Closest::Indeterminate;
+            return Closest::SinglePoint(line.start_point());
        }

A more interesting third case would be to accumulate multiple points if there are multiple distinct points that are closest.

@michaelkirk
Copy link
Member

There remains a need to handle empty geometries - so I guess Indeterminate is still useful there.

We could express that case as Option<Closest>::None

Taking that, and the ability for multiple points to be closest, we could end up with something like:

enum Closest {
  Single(Point),
  Intersection(Point),
  Many(Vec<Point>)
}

pub trait ClosestPoint<F: GeoFloat, Rhs = Point<F>> {
    /// Find the closest point between `self` and `p`.
    fn closest_point(&self, p: &Rhs) -> Option<Closest<F>>;
}

Also, note that technically the ClosestPoint trait accepts a Rhs parameter, implying

If it's there to support higher dimension arguments like: line_string.closest_point(line_string)

That would entail further augmenting our return, since the closest thing might not be a point, but a contiguous segment (or a contiguous area if we're talking polygons).

To be frank, I think we should get rid of the Rhs argument. Or if we go that route, rename the method to closest rather than closest_point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants