geo
geo copied to clipboard
One Length trait to rule them all π
The following code is blocked on https://github.com/rust-lang/rust/issues/51344. Relevant discussion happened in https://github.com/georust/rust-geo/issues/47.
pub struct Line<T> {
start: (T, T),
end: (T, T),
}
////////////
pub trait LengthAlgo<T> {
fn length(line: Line<T>) -> T;
}
////////////
pub enum Haversine {}
impl<T> LengthAlgo<T> for Haversine {
fn length(line: Line<T>) -> T {
unimplemented!()
}
}
pub enum Vincenty {}
impl<T> LengthAlgo<T> for Vincenty {
fn length(line: Line<T>) -> T {
unimplemented!()
}
}
////////////
pub trait Length<T, Algo: LengthAlgo<T> = Haversine> {
fn length(self) -> T;
}
impl<T, Algo: LengthAlgo<T>> Length<T, Algo> for Line<T> {
fn length(self) -> T {
Algo::length(self)
}
}
////////////
fn main() {
let line: Line<i32> = Line {
start: (4, 6),
end: (2, 23),
};
// This doesn't compile β error message says `Algo` type needs to be specified
// let haversine_length = line.length();
// This compiles, despite us not specifying the type for `Algo`
let haversine_length = Length::<i32>::length(line);
}
There are two topics that need to be discussed here:
- What should the trait look like?
- What should the default algorithm be?
I agree about euclidean distance by default.
The trait here takes ownership of a Line. Would it be better to take a reference to 2 points? To prevent creating and discarding a Line struct each time? (or am I misunderstanding something about rust? π)
On 4 June 2018 14:38:44 CEST, "Stephan HΓΌgel" [email protected] wrote:
I would say the default should be Euclidean, since
Geodeals primarily with planar geometry.
-- Sent from my Android device with K-9 Mail. Please excuse my brevity.
I have opinions about euclidean as a default, but short on time right now to expand.
Regarding taking ownership, you're right, it should take &self. Unfortunately can't make much progress here until my Rust issue is addressed :-/
PostGIS has a geography type (as opposed to it's older geometry) which stores everything in lat/lons and distance/area functions use a 'spherical/surface distance' and return values in metres. That's very useful in many cases.
Maybe a feature like that would be very useful for rust-geo, and avoid the "which should it be?" discussion?
As long as the underlying Rust issue remains open, I don't think we can make much progress on this, so I'm going to close.