1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
//! Geoutils is a evolving crate to provide several geological computations and utilities.
//! Most computations are based off methods on the [Location](struct.Location.html) struct.
//!
//! Find the full API reference at [docs.rs](http://docs.rs/geoutils).
//!
//! # Examples
//!
//! * Get the distance between two points using [Vincenty's Inverse Formula](https://en.wikipedia.org/wiki/Vincenty%27s_formulae).
//! ```rust
//! extern crate geoutils;
//!
//! use geoutils::Location;
//!
//! let berlin = Location::new(52.518611, 13.408056);
//! let moscow = Location::new(55.751667, 37.617778);
//! let distance = berlin.distance_to(&moscow).unwrap();
//!
//! println!("Distance = {}", distance);
//! ```
//!
//! * Get the distance between two points using the [Haversine Formula](https://en.wikipedia.org/wiki/Haversine_formula).
//! ```rust
//! extern crate geoutils;
//!
//! use geoutils::Location;
//!
//! let berlin = Location::new(52.518611, 13.408056);
//! let moscow = Location::new(55.751667, 37.617778);
//! let distance = berlin.haversine_distance_to(&moscow);
//!
//! println!("Distance = {}", distance);
//! ```
//!
//! * Get the center of a list of coordinates.
//! ```rust
//! extern crate geoutils;
//!
//! use geoutils::Location;
//!
//! let berlin = Location::new(52.518611, 13.408056);
//! let moscow = Location::new(55.751667, 37.617778);
//! let center = Location::center(vec![&berlin, &moscow]);
//!
//! println!("Center {}, {}", center.latitude(), center.longitude());
//! ```
//!
//! * Check if a point falls in a certain radius of another point.
//! ```rust
//! extern crate geoutils;
//!
//! use geoutils::Location;
//!
//! let berlin = Location::new(52.518611, 13.408056);
//! let moscow = Location::new(55.751667, 37.617778);
//! let is_in_radius = berlin.is_in_circle(&moscow, 2000);
//!
//! println!("Is Berlin in 2000m of Moscow? {}", is_in_radius);
//! ```
//!
#![deny(missing_docs)]
mod formula;
/// Location defines a point using it's latitude and longitude.
#[derive(Debug)]
pub struct Location(f64, f64);
impl Location {
/// Create a new Location with it's degree values of latitude and longitude.
pub fn new<T: Into<f64>>(lat: T, lon: T) -> Self {
Location(lat.into(), lon.into())
}
/// Get the latitude.
pub fn latitude(&self) -> f64 {
self.0
}
/// Get the longitude.
pub fn longitude(&self) -> f64 {
self.1
}
/// Find the distance from itself to another point. Internally uses Vincenty's inverse formula.
/// For better performance and lesser accuracy, consider [haversine_distance_to](struct.Location.html#method.haversine_distance_to).
pub fn distance_to(&self, to: &Location) -> Result<f64, String> {
match formula::vincenty_inverse(self, to, 0.00001, 0.0) {
Ok(res) => Ok(res.distance),
Err(e) => Err(e),
}
}
/// Find the distance from itself to another point using Haversine formula.
/// This is usually computationally less intensive than [distance_to](struct.Location.html#method.distance_to) but
/// is generally not as accurate.
pub fn haversine_distance_to(&self, to: &Location) -> f64 {
formula::haversine_distance_to(self, to)
}
/// Check if the point is within a fixed radius of another point.
pub fn is_in_circle<T: Into<f64>>(&self, center: &Location, radius: T) -> Result<bool, String> {
match formula::vincenty_inverse(self, center, 0.00001, 0.0) {
Ok(res) => Ok(res.distance < radius.into()),
Err(e) => Err(e),
}
}
/// Find the center of given locations.
pub fn center(coords: Vec<&Location>) -> Location {
formula::center_of_coords(coords)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
#[test]
fn test_get_distance() {
let l1 = Location::new(27.740068, 85.337576);
let l2 = Location::new(27.740286, 85.337059);
match l1.distance_to(&l2) {
Ok(distance) => {
assert_eq!(distance, 56.409);
}
Err(e) => panic!("Failed: {:?}", e),
}
}
#[test]
fn test_get_distance_haversine() {
let l1 = Location::new(27.740068, 85.337576);
let l2 = Location::new(27.740286, 85.337059);
let distance = l1.haversine_distance_to(&l2);
assert_eq!(distance, 56.36);
}
#[test]
fn test_get_center() {
let l1 = Location::new(52.518611, 13.408056);
let l2 = Location::new(55.751667, 37.617778);
let l = Location::center(vec![&l1, &l2]);
assert_eq!(l.0, 54.743683);
assert_eq!(l.1, 25.033239);
}
}