initial commit
This commit is contained in:
commit
f3ea65fa21
1
nominatimapi/.gitignore
vendored
Normal file
1
nominatimapi/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
target/
|
||||||
1497
nominatimapi/Cargo.lock
generated
Normal file
1497
nominatimapi/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
9
nominatimapi/Cargo.toml
Normal file
9
nominatimapi/Cargo.toml
Normal 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
77
nominatimapi/src/lib.rs
Normal 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
20
nominatimapi/src/main.rs
Normal 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(())
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user