Skip to content

Commit

Permalink
Adds Point to point funcions
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben Calnan committed May 14, 2024
1 parent b3e099b commit 0891197
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "geo-core"
version = "0.1.1"
version = "0.1.2"
authors = ["Ben Calnan <[email protected]>"]
description = "Common tools for working with spatial data"
edition = "2021"
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,7 @@ Library of common geographic functions and tools in Rust
### Utilities

- Convert degrees to radians
- Convert radians to degrees
- Convert radians to degrees
- Point To Point Distance Cosine
- Point To Point Distance Haversine
- Point To Point Distance Cartesian
10 changes: 5 additions & 5 deletions src/latlng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,32 @@ impl LatLng {
}
}

fn new_from_point(p: Point) -> LatLng {
pub fn new_from_point(p: Point) -> LatLng {
LatLng { lat: p.y, lng: p.x }
}

fn convert_to_radian(&self) -> LatLng {
pub fn convert_to_radian(&self) -> LatLng {
LatLng {
lat: deg_to_rad(self.lat),
lng: deg_to_rad(self.lng),
}
}

fn convert_to_degrees(&self) -> LatLng {
pub fn convert_to_degrees(&self) -> LatLng {
LatLng {
lat: rad_to_deg(self.lat),
lng: rad_to_deg(self.lng),
}
}

fn convert_to_point(&self) -> Point {
pub fn convert_to_point(&self) -> Point {
Point {
x: self.lng,
y: self.lat,
}
}

fn convert_to_point3d(&self) -> Point3D {
pub fn convert_to_point3d(&self) -> Point3D {
Point3D {
x: EARTH_RADIUS * self.lat.cos() * self.lng.cos(),
y: EARTH_RADIUS * self.lat.cos() * self.lng.sin(),
Expand Down
85 changes: 85 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::f64::consts::PI;

use crate::{constants::EARTH_RADIUS, latlng::LatLng, point::Point};

// DegToRad - Convert degrees to radians
pub fn deg_to_rad(angle: f64) -> f64 {
angle * PI / 180.0
Expand All @@ -9,3 +11,86 @@ pub fn deg_to_rad(angle: f64) -> f64 {
pub fn rad_to_deg(angle: f64) -> f64 {
angle * 180.0 / PI
}

//PointToPointDistanceCosine Get distance (in meters) between two Lat/Lons using cosine formula. Has some benefits over using Haversine formula.
//Input and Output in Radians
pub fn point_to_point_distance_cosine(start_point: Point, end_point: Point) -> f64 {
(start_point.y.sin() * end_point.y.sin() + start_point.y.cos() * end_point.y.cos() * (start_point.x - end_point.x).cos()).acos() * EARTH_RADIUS
}


// //PointToPointHaversine - Alternative method for getting distance (in meters) bewteen two Lat/Longs using cosine formula. Possibly slightly faster.
pub fn point_to_point_haversine(start: LatLng, end: LatLng) ->f64 {
let start_radian = start.convert_to_radian();
let end_radian = end.convert_to_radian();
let dif_lat = end_radian.lat - start_radian.lat;
let dif_lng = end_radian.lng - start_radian.lng;

let a = (dif_lat/2.0).sin() * (dif_lat/2.0).sin() + start_radian.lat.cos() * end_radian.lat.cos()* (dif_lng / 2.0).sin()*(dif_lng/2.0).sin();
let c = 2.0 * (a.sqrt().atan2((1.0-a).sqrt()));
let d = EARTH_RADIUS * c;
return d
}

//PointToPointCartesianDistance - Get distance betweeen two cartesian points
pub fn point_to_point_cartesian_distance(source: Point, target: Point) ->f64 {
((target.x-source.x).powi(2) + (target.y-source.y).powi(2)).sqrt()
}


#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_point_to_point_distance_cosine() {
let start_lat = 51.27936;
let start_lng = 1.07263;
let end_lat = 51.27741;
let end_lng = 1.07281;

let start_point = Point {
x: deg_to_rad(start_lng),
y: deg_to_rad(start_lat)
};

let end_point = Point{
x: deg_to_rad(end_lng),
y: deg_to_rad(end_lat)
};

let distance = point_to_point_distance_cosine(start_point, end_point);

assert_eq!(distance.round(), 217.0);

}
#[test]
fn test_point_to_point_distance_haversine() {

let start_lat = 51.27936;
let start_lng = 1.07263;
let end_lat = 51.27741;
let end_lng = 1.07281;


let start_lat_lng = LatLng{
lat: start_lat,
lng: start_lng
};

let end_lat_lng = LatLng{
lat: end_lat,
lng: end_lng
};

let distance = point_to_point_haversine(start_lat_lng, end_lat_lng);

assert_eq!(distance.round(), 217.0);

}

}




0 comments on commit 0891197

Please sign in to comment.