dms_coordinates/
lib.rs

1//! Package to manipulate 1D and 3D sexagesimal coordinates.
2//! Homepage: <https://github.com/gwbres/dms-coordinates>
3#![cfg_attr(not(feature = "std"), no_std)]
4
5pub mod cardinal;
6pub mod dms;
7pub mod dms3d;
8
9#[derive(Debug)]
10pub enum Error {
11    InvalidLatitude,
12    MissingLatitude,
13    InvalidLongitude,
14    MissingLongitude,
15    /// When adding two cardinals toghether, they
16    /// must be compatible.
17    IncompatibleCardinals,
18    #[cfg(feature = "gpx")]
19    GpxParsingError,
20    #[cfg(feature = "gpx")]
21    GpxError,
22}
23
24pub use crate::{cardinal::Cardinal, dms::DMS, dms3d::DMS3d};
25
26/// Mean radius of the Earth: 6.37 * 10^(6) m
27const EARTH_RADIUS: f64 = 6.37e6_f64;
28
29/// Returns distance (m) between two decimal degrees coordinates
30/// coord1: (lat,lon), coord2: (lat, lon)
31pub fn projected_distance(coord1: (f64, f64), coord2: (f64, f64)) -> f64 {
32    let dphi = map_3d::deg2rad(coord2.0) - map_3d::deg2rad(coord1.0);
33    let d_lambda = map_3d::deg2rad(coord2.1) - map_3d::deg2rad(coord1.1);
34    let a: f64 = (dphi / 2.0_f64).sin().powf(2.0_f64)
35        + map_3d::deg2rad(coord1.0).cos()
36            * map_3d::deg2rad(coord2.0).cos()
37            * (d_lambda / 2.0_f64).sin().powf(2.0_f64);
38    let c = 2.0_f64 * a.powf(0.5_f64).atan2((1.0 - a).powf(0.5_f64));
39    EARTH_RADIUS * c
40}
41
42#[cfg(test)]
43#[macro_use]
44extern crate assert_float_eq;