Longitude

A coordinate library in Rust. Dealing with coordinate math is tricky because you are trying to move a point on a spherical object (the earth). Manipulating the longitude is pretty straight forward as it is just the length from the North Pole to the South Pole. Latitude is a bit more complicated because the circumference of the earth varies based on how close you are to the equator. I use this library whenever I need to deal with interactive maps, triangulation, etc. I've used this in my app sardines and another app called Batch Watch.

Dealing with Units of Distance

Create a distance which is a value associated with a unit. rust use longitude::{Distance, DistanceUnit}; let distance_a = Distance::from_kilometers(10.); let distance_b = Distance::from_miles(6.213712); You can now perform operations on these measurements including conversion, addition, subtraction and multiplying by a scalar.

```rust println!("{:?}", distancea.convertto(DistanceUnit::Kilometers));

```

Performing operators on coordinates

```rust // Add a distance to a coordinate point: let locationa = Location::from(40.7885447, -111.7656248); let distancea = Distance::from_kilometers(8.2);

let locationb = locationa.add(&distancea, Direction::North); let locationresult = Location::from(40.8622065532978, -111.7656248);

assert!(locationb == locationresult) ```

```rust // Measure the distance between 2 coordinate points: let locationa = Location::from(40.7885447, -111.7656248); let locationb = Location::from(40.7945846, -111.6950349); let distancea = locationa.distance(&locationb); let distanceb = Distance::from_kilometers(5.9868);

assert!(distancea == distanceb);

```

How does it work?

First it uses the Distance struct for all measurements. This makes conversion easy and ensures you never get confused about units. The location struct stores longitude and latitude. This is how the distance of 2 points is calculated: ```rust impl Location { pub fn distance(&self, other: &Location) -> Distance { let (lat1, lng1) = (self.latitude, self.longitude); let (lat2, lng2) = (other.latitude, other.longitude);

    let pi_180 = |x: f64| (x * PI) / 180.;
    let d_lat = pi_180(lat2) - pi_180(lat1);
    let d_lng = pi_180(lng2) - pi_180(lng1);

    let a = (d_lat / 2.).sin().powf(2.) +
        pi_180(lat2).cos().powf(2.) *
        (d_lng / 2.).sin().powf(2.);

    let c = 2. * atan2(a.sqrt(), (1. - a).sqrt());

    RADIUS_OF_EARTH.clone() * c
}

}

``` This function uses the Haversine Formula. (Read more here: https://en.wikipedia.org/wiki/Haversine_formula)

You can also add some distance to coordinate point. rust pub fn add(&self, distance: &Distance, direction: Direction) -> Self The function add takes a distance and direction. The direction is North, South, East of West. If it East or West we can use this formula: ```rust let d = distance.kilometers() / RADIUSOFEARTH.kilometers(); let c = 180. / PI; let offset = d * c / (self.latitude * PI / 180.).cos(); let scalar = if direction == Direction::East { 1. } else { -1. };

Self { latitude: self.latitude, longitude: self.longitude + (offset * scalar), } ``` We need the trig because the latitude will vary based on distance from the equator.

Adding to the North or South is a bit more straight forward: ```rust let d = distance.kilometers() / RADIUSOFEARTH.kilometers(); let c = 180. / PI; let offset = d * c; let scalar = if direction == Direction::North { 1. } else { -1. };

Self { latitude: self.latitude + (offset * scalar), longitude: self.longitude, }

```