-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1216 from georust/mkirk/line-measures-3
Unify line measures
- Loading branch information
Showing
19 changed files
with
1,167 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
use geo_types::{CoordFloat, Point}; | ||
|
||
/// Calculate the bearing between two points | ||
pub trait Bearing<F: CoordFloat> { | ||
/// Calculate the bearing from `origin` to `destination` in degrees. | ||
/// | ||
/// See [specific implementations](#implementors) for details. | ||
/// | ||
/// # Units | ||
/// - `origin`, `destination`: Point where the units of x/y depend on the [trait implementation](#implementors). | ||
/// - returns: degrees, where: North: 0°, East: 90°, South: 180°, West: 270° | ||
fn bearing(origin: Point<F>, destination: Point<F>) -> F; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
use geo_types::{CoordFloat, Point}; | ||
|
||
/// Calculate the destination point from an origin point, a bearing and a distance. | ||
pub trait Destination<F: CoordFloat> { | ||
/// Returns a new point having travelled the `distance` along a line | ||
/// from the `origin` point with the given `bearing`. | ||
/// | ||
/// See [specific implementations](#implementors) for details. | ||
/// | ||
/// # Units | ||
/// | ||
/// - `origin`: Point where the units of x/y depend on the [trait implementation](#implementors). | ||
/// - `bearing`: degrees, where: North: 0°, East: 90°, South: 180°, West: 270° | ||
/// - `distance`: depends on the [trait implementation](#implementors). | ||
/// - returns: Point where the units of x/y depend on the [trait implementation](#implementors). | ||
/// | ||
/// [`metric_spaces`]: super::metric_spaces | ||
fn destination(origin: Point<F>, bearing: F, distance: F) -> Point<F>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/// Calculate the distance between the `Origin` and `Destination` geometry. | ||
pub trait Distance<F, Origin, Destination> { | ||
/// Note that not all implementations support all geometry combinations, but at least `Point` to `Point` | ||
/// is supported. | ||
/// See [specific implementations](#implementors) for details. | ||
/// | ||
/// # Units | ||
/// | ||
/// - `origin`, `destination`: geometry where the units of x/y depend on the trait implementation. | ||
/// - returns: depends on the trait implementation. | ||
fn distance(origin: Origin, destination: Destination) -> F; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use crate::{CoordFloat, Point}; | ||
|
||
/// Interpolate a `Point` along a line between two existing points | ||
pub trait InterpolatePoint<F: CoordFloat> { | ||
/// Returns a new Point along a line between two existing points | ||
/// | ||
/// See [specific implementations](#implementors) for details. | ||
fn point_at_ratio_between(start: Point<F>, end: Point<F>, ratio_from_start: F) -> Point<F>; | ||
|
||
// TODO: | ||
// fn point_at_distance_between(start: Point<F>, end: Point<F>, distance_from_start: F) -> Point<F>; | ||
|
||
/// Interpolates `Point`s along a line between `start` and `end`. | ||
/// | ||
/// See [specific implementations](#implementors) for details. | ||
/// | ||
/// As many points as necessary will be added such that the distance between points | ||
/// never exceeds `max_distance`. If the distance between start and end is less than | ||
/// `max_distance`, no additional points will be included in the output. | ||
/// | ||
/// `include_ends`: Should the start and end points be included in the output? | ||
fn points_along_line( | ||
start: Point<F>, | ||
end: Point<F>, | ||
max_distance: F, | ||
include_ends: bool, | ||
) -> impl Iterator<Item = Point<F>>; | ||
} |
78 changes: 78 additions & 0 deletions
78
geo/src/algorithm/line_measures/metric_spaces/euclidean.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use super::super::Distance; | ||
use crate::{GeoFloat, Point}; | ||
|
||
/// Operations on the [Euclidean plane] measure distance with the pythagorean formula - | ||
/// what you'd measure with a ruler. | ||
/// | ||
/// If you have lon/lat points, use the [`Haversine`], [`Geodesic`], or other [metric spaces] - | ||
/// Euclidean methods will give nonsense results. | ||
/// | ||
/// If you wish to use Euclidean operations with lon/lat, the coordinates must first be transformed | ||
/// using the [`Transform::transform`](crate::Transform::transform) / [`Transform::transform_crs_to_crs`](crate::Transform::transform_crs_to_crs) methods or their | ||
/// immutable variants. Use of these requires the proj feature | ||
/// | ||
/// [Euclidean plane]: https://en.wikipedia.org/wiki/Euclidean_plane | ||
/// [`Transform`]: crate::Transform | ||
/// [`Haversine`]: super::Haversine | ||
/// [`Geodesic`]: super::Geodesic | ||
/// [metric spaces]: super | ||
pub struct Euclidean; | ||
|
||
/// Calculate the Euclidean distance (a.k.a. pythagorean distance) between two Points | ||
impl<F: GeoFloat> Distance<F, Point<F>, Point<F>> for Euclidean { | ||
/// Calculate the Euclidean distance (a.k.a. pythagorean distance) between two Points | ||
/// | ||
/// # Units | ||
/// - `origin`, `destination`: Point where the units of x/y represent non-angular units | ||
/// — e.g. meters or miles, not lon/lat. For lon/lat points, use the | ||
/// [`Haversine`] or [`Geodesic`] [metric spaces]. | ||
/// - returns: distance in the same units as the `origin` and `destination` points | ||
/// | ||
/// # Example | ||
/// ``` | ||
/// use geo::{Euclidean, Distance}; | ||
/// use geo::Point; | ||
/// // web mercator | ||
/// let new_york_city = Point::new(-8238310.24, 4942194.78); | ||
/// // web mercator | ||
/// let london = Point::new(-14226.63, 6678077.70); | ||
/// let distance: f64 = Euclidean::distance(new_york_city, london); | ||
/// | ||
/// assert_eq!( | ||
/// 8_405_286., // meters in web mercator | ||
/// distance.round() | ||
/// ); | ||
/// ``` | ||
/// | ||
/// [`Haversine`]: super::Haversine | ||
/// [`Geodesic`]: super::Geodesic | ||
/// [metric spaces]: super | ||
fn distance(origin: Point<F>, destination: Point<F>) -> F { | ||
crate::EuclideanDistance::euclidean_distance(&origin, &destination) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
type MetricSpace = Euclidean; | ||
|
||
mod distance { | ||
use super::*; | ||
|
||
#[test] | ||
fn new_york_to_london() { | ||
// web mercator | ||
let new_york_city = Point::new(-8238310.24, 4942194.78); | ||
// web mercator | ||
let london = Point::new(-14226.63, 6678077.70); | ||
let distance: f64 = MetricSpace::distance(new_york_city, london); | ||
|
||
assert_relative_eq!( | ||
8_405_286., // meters in web mercator | ||
distance.round() | ||
); | ||
} | ||
} | ||
} |
Oops, something went wrong.