-
Notifications
You must be signed in to change notification settings - Fork 202
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
base: main
Are you sure you want to change the base?
Conversation
In itself, this adds no new functionality, but sets us up for configurable line measures - e.g. a Haversine with a custom earth radius (or non-earth radius!) or a non wgs84 Geodesic
"long ago" `Densify` was defined on the individual geometries: LineString, Line, etc. Recently, these methods were changed to be generic so they could work with Euclidean vs. Haversine, etc. However, to support configurable metric spaces (e.g. Haversine with custom planet radius) a "type" generic is not enough - we need to pass a (potentially configured) metric space as an argument. However, this made the arguments a little awkward: line.densify(&Haversine, 100) Passing `&Haversine` is a little awkward, so this commits switch to instead be: Haversine.densify(&line, 100) Which allows us to seemlessly add support for something like: let mars_radius = 3_389_500 let mars = CustomHaversine::with_radius(mars_radius); mars.densify(&line, 100)
geo-types/CHANGES.md
Outdated
@@ -2,7 +2,6 @@ | |||
|
|||
## Unreleased | |||
|
|||
- Fix page location of citation for mean earth radius used in Haversine calculations | |||
- Implement `RTreeObject` for `Triangle`. |
There was a problem hiding this comment.
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.
I messed up some docs.
Haven't reviewed, but this is a lot better from a UX perspective, and – I think – worth the churn. |
Converting this to a draft while I incorporate some feedback from @lnicola - what do you think, does In summary: // "long ago" before 0.29.0
point1.haversine_distance(point2)
point1.rhumb_distance(point2)
// as of 0.29.0
Haversine::distance(point1, point2)
Rhumb::distance(point1, point2)
// v1 of this PR:
CustomHaversine::new(3_389_500.0).distance(point1, point2)
Haversine.distance(point1, point2)
Rhumb.distance(point1, point2)
// current version of this PR (with @lnicola's suggestion - removing "CustomHaversine")
Haversine::new(3_389_500.0).distance(point1, point2)
HAVERSINE.distance(point_1, point_2)
RHUMB.distance(point_1, point_2) |
71038e0
to
0dcb842
Compare
What do you think @lnicola - based on the diff do you prefer the If so, I'd like to push through the rest of the changes. |
@michaelkirk sorry for the late reply. It looks.. just as I expected. Seems fine to me, but you might want to ask for a third opinion 😀. |
46124d2
to
24ea6fd
Compare
Incorporating some more feedback... Removes the unpopular SHOUT_CASE: HAVERSINE -> Haversine, while still retaining the single implementation vs having redundant Haversine vs CustomHaversine implementations.
24ea6fd
to
0f26d76
Compare
This is ready for review! I've incorporated some more feedback (from discord) into this and updated the description with a "Version 3 of this PR". |
My concern (perhaps badly articulated on Discord), was that we're shipping public structs that can contain an arbitrary value (e.g. the sphere radius in |
CHANGES.md
if knowledge of this change could be valuable to users.Motivation
Currently, our
Haversine
metric space calculation uses the IUGG's "mean radius", but there are several other reasonable values. Similarly, theGeodesic
internally uses Karney's geographic algorithms which support other geoid parameters.Proposal
By reorganizing our traits, we can let users take advantage of all the associated algorithms (length, densify, distance) for any given (potentially customizable) metric space.
The trick is, almost nobody (by my count) actually wants this configurability, so the resultant API must not make it burdensome for the vast majority who want the "default" case.
Some conversation in #1274 and another in #1140 lead me to revisit the recently overhauled line_measure traits, and that it's possible to support this kind of customization in a reasonable way.
There are a lot of changes, but they are pretty mechanical. You can get a pretty good idea of the kinds of changes our users will need to make by reviewing this diff.
As well as being more expressive, I actually prefer where the code is now, without the turbo-fish. I just wish I'd avoided the churn by thinking of it before the big changes in the v0.29.0 (primarily #1216) were released (on 2024-10-30):
Version 1 of this PR - move trait associated functions to instance methods:
Version 2 of this PR - (based on some PR feedback) make all Haversine customizable (removing distinction of CustomHaversine), and make the "common" Haversine a constant:
Version 3 of this PR - (based on some further feedback in discord) Same as version 2 but stop SHOUTING the
Haversine
constant name, so it nicely avoids the redundant implementations like v2, but still looks like v1 from a user perspective:References
This solves the same problem as #1220, but more generally.
Tracking issue for line_measure overhaul here #1181