initial commit

This commit is contained in:
Liam Fitzpatrick 2024-06-20 16:21:42 -04:00
commit f3ea65fa21
5 changed files with 1604 additions and 0 deletions

1
nominatimapi/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
target/

1497
nominatimapi/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

9
nominatimapi/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "nominatonapi"
version = "0.1.0"
edition = "2021"
[dependencies]
reqwest = { version = "0.12.4", features = ["json"] }
serde_json = "1.0.117"
tokio = { version = "1.38.0", features = ["full"] }

77
nominatimapi/src/lib.rs Normal file
View File

@ -0,0 +1,77 @@
use reqwest;
use serde_json;
use std::{collections::HashMap, error::Error};
use reqwest::header::USER_AGENT;
pub struct Address {
street: String,
city: String,
state: String,
country: String,
postalcode: String
}
impl Address {
pub fn new(street: &str, city: &str, state: &str, postalcode: &str) -> Address{
Address { street: String::from(street), city: String::from(city), state: String::from(state), country: String::from("United States of America"), postalcode: String::from(postalcode)}
}
}
struct GeoCoordinates{
latitude_deg: f32,
longitude_deg: f32
}
async fn geolocation(address: Address) -> Result<GeoCoordinates, Box<dyn Error>> {
const URL3: &str = "https://nominatim.openstreetmap.org/search?street=7935%20Trailview%20Crossing&city=Glen%20Burnie&state=Maryland&country=United%20States%20of%20America&postalcode=21060&format=json";
let req: String = format!("https://nominatim.openstreetmap.org/search?street={}&city={}&state={}&country={}&postalcode={}&format=json", address.street.replace(" ", "%20"), address.city.replace(" ", "%20"), address.state.replace(" ", "%20"), address.country.replace(" ", "%20"), address.postalcode.replace(" ", "%20"));
match reqwest::Client::new().get(&req)
.header(USER_AGENT, "StrategyEats")
.send()
.await {
Ok(resp) => {
let json: serde_json::Value = resp.json().await?;
// let json = resp.text().await?;
let lat: f32 = json[0]["lat"].as_str().unwrap().parse().unwrap();
let lon: f32 = json[0]["lon"].as_str().unwrap().parse().unwrap();
return Ok(GeoCoordinates{latitude_deg: lat, longitude_deg: lon})
},
Err(err) => {
return Err(Box::new(err))
}
}
}
fn haversine(address1: GeoCoordinates, address2: GeoCoordinates) -> f32 {
let lon1 = address1.longitude_deg.to_radians();
let lat1 = address1.latitude_deg.to_radians();
let lon2 = address2.longitude_deg.to_radians();
let lat2 = address2.latitude_deg.to_radians();
let dlon = lon2 - lon1;
let dlat = lat2 - lat1;
let a = dlat/2.0;
let a = a.sin();
let a = a.powf(2.0) + lat1.cos() * lat2.cos() * (dlon/2.0).sin().powf(2.0);
let c = 2.0 * a.sqrt().asin();
let r = 3956.0; // Radius of the earth in miles. Use 6371 for km\
return c * r
}
pub async fn get_distance(address1: Address, address2: Address) -> Result<f32, Box<dyn Error>> {
let address1 = geolocation(address1).await;
match address1 {
Err(e) => return Err(e),
Ok(address1) => {
let address2 = geolocation(address2).await;
match address2 {
Err(e) => return Err(e),
Ok(address2) => {
Ok(haversine(address1, address2))
}
}
}
}
}

20
nominatimapi/src/main.rs Normal file
View File

@ -0,0 +1,20 @@
use nominatonapi::{get_distance, Address};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let address1 = Address::new("7935 Trailview Crossing", "Glen Burnie", "Maryland", "21060");
let address2 = Address::new("1347 Dalton Road", "Parkville", "Maryland", "21234");
let dist = get_distance(address1, address2).await;
match dist {
Err(e) => println!("{:?}", e),
Ok(e) => {
println!("Distance is {} miles", e);
}
}
Ok(())
}