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

Replace HaversineIntermediate with HaversineLineInterpolatePoint and HaversineDensify #1181

Open
michaelkirk opened this issue May 17, 2024 · 4 comments

Comments

@michaelkirk
Copy link
Member

michaelkirk commented May 17, 2024

We have a lot of traits! It took me a while to realize that we had haversine corollaries to these euclidean methods. I think we can arrange things differently to make this more obvious and discoverable to users (like me), like we do with {Euclidean|Haversine}Length and {Euclidean|Haversine}Distance traits.

HaversineIntermediate.haversine_intermediate_fill is the same thing as the existing DensifyHaversine, right?

HaversineIntermediate.haversine_intermediate is pretty much the haversine corollary to the Euclidean LineInterpolatePoint

Proposal:

Let's delete HaversineIntermediate (after a deprecation cycle). HaversineIntermediate .haversine_intermediate will live on in a new trait HaversineLineInterpolatePoint that more closely mirrors (Euclidiean)LineInterpolatePoint and HaversineIntermediate .haversine_intermediate_fill will go away because it's redundant with DensifyHaversine.

This won't be completely trivial because the API's don't exactly align, but it's not much of a stretch.

One difference: HaversineIntermediate.haversine_intermediate_fill takes two points as input, so conceptually it only works on a Line, whereas DensifyHaversine is implemented on other geometry types, like Polygon, but I think that's more of a benefit than anything.

Another difference: HaversineIntermediate.haversine_intermediate_fill has an includes_end parameters. We could add a similar parameter or method flavor to the existing Densify trait to match this new proposed HaversineDensify, but my instinct is actually just to get rid of the parameter and pretend like it's always true. If the user doesn't want the first and last point they can manually trim the output.

Also, I think we should rename DensifyHaversine to HaversineDensify to be consistent with most of our other algorithm variants, but I don't feel that strongly about it.

Measurement Trait Matrix

As a csv: measurements.csv

Rendered:

Trait area_signed area_unsigned bearing closest_point densify destination distance intermediate intermediate_fill length (➡Oddballs ➡) interpolate_point cross_track_distance bearing_distance perimeter perimeter_and_area_signed perimeter_and_area_unsigned
GeodesicArea geodesic_area_signed geodesic_area_unsigned geodesic_perimeter geodesic_perimeter_area_signed geodesic_perimeter_area_unsigned
GeodesicBearing geodesic_bearing geodesic_bearing_distance
GeodesicDestination geodesic_destination
GeodesicDistance geodesic_distance (point to point only)
GeodesicIntermediate geodesic_intermediate geodesic_intermediate_fill
GeodesicLength geodesic_length
HaversineBearing haversine_bearing
HaversineClosestPoint haversine_closest_point
DensifyHaversine densify_haversine
HaversineDestination haversine_destination
HaversineDistance haversine_distance (point to point only)
HaversineIntermediate haversine_intermediate haversine_intermediate_fill
HaversineLength haversine_length
Area (Euclidean) signed_area unsigned_area
ClosestPoint (Euclidean) closest_point
Densify (Euclidean) densify (euclidean)
EuclideanDistance euclidean_distance (all geoms)
EuclideanLength euclidean_length
RhumbBearing rhumb_bearing
RhumbDestination rhumb_destination
RhumbDistance rhumb_distance
RhumbIntermediate rhumb_intermediate rhumb_intermediate_fill
RhumbLength rhumb_length
(⬇Oddballs ⬇)
HausdorffDistance hausdorff_distance (point to point only)
VincentyDistance vincenty_distance
VincentyLength vincenty_length
CrossTrackDistance cross_track_distance (haversine)
LineInterpolatePoint line_interpolate_point (euclidean)

/cc @JivanRoquet original author of the HaversineIntermediate trait in #230
/cc @JosiahParry original author of the DensifyHaversine trait in #1081

@michaelkirk
Copy link
Member Author

michaelkirk commented May 17, 2024

Oh man, the plot thickens.

Maybe we shouldn't just get rid of HaversineIntermediate, because there are sibling traits: GeodesicIntermediate and RhumbIntermediate.

I don't have a solution yet and have run out of time to think about this today, but I'm open to proposals about how to re-align things to increase uniformity and decrease redundancy.

@JosiahParry
Copy link
Contributor

One option would be to have an IntermediatePoint trait that requires an enum like DistanceType::Rhumb, DistanceType::Haversine, DistanceType::Euclidean, DistanceType::Geodesic. Then, for simplicity have convenience functions in the module.

fn intermediate_haversine(start: &Point, end: &Point, prop: f64) {}
fn intermediate_geodesic(start: &Point, end: &Point, prop: f64) {}
fn intermediate_euclidean(start: &Point, end: &Point, prop: f64) {}
fn intermediate_rhumb(start: &Point, end: &Point, prop: f64) {}

@michaelkirk
Copy link
Member Author

I spent a while trying to understand our existing "measurement" traits - see the new table in the issue description.

It exposes a bit of overlap, some inconsistencies, and some missing functionality. There are also some "similar/related" traits that don't exactly fit the pattern, which I've labeled as "oddballs".

@michaelkirk
Copy link
Member Author

michaelkirk commented Sep 21, 2024

Next up, I want to collapse these into some kind of conceptual "metric space" trait:

Screenshot 2024-09-20 at 17 56 44

(WIP)

I don't know that it will actually be implementable as such, but if nothing else it will be helpful documentation. I am hopeful that it will lead to some clarify about how to more coherently organize our implementations as well.

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

No branches or pull requests

2 participants