From 1bc9bc12b8dba1f79d86850dc651dbec46994004 Mon Sep 17 00:00:00 2001 From: Arunkumar Mourougappane Date: Fri, 9 Aug 2024 22:14:01 -0500 Subject: [PATCH] Add geo location by latitude and longitude coordinates --- Cargo.toml | 1 + src/geo_location/geo_data.rs | 32 ++++++++++++++++++++++++++++++++ src/main.rs | 17 ++++++++--------- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1139378..f73b083 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,3 +29,4 @@ postcode = "0.1.1" public-ip = "0.2.2" ipgeolocate = "0.3.6" tokio = { version = "1.39.2", features = ["full", "fs"] } +geo_rust = "0.4.1" diff --git a/src/geo_location/geo_data.rs b/src/geo_location/geo_data.rs index 6c88bb8..83c9ba1 100644 --- a/src/geo_location/geo_data.rs +++ b/src/geo_location/geo_data.rs @@ -1,5 +1,6 @@ use std::net::IpAddr; +use geo_rust::{get_nearest_postcode, get_postal_data, Country, GeoLocation}; use ipgeolocate::{Locator, Service}; use postcode::Postcode; use serde::Serialize; @@ -15,6 +16,8 @@ pub enum GeoLocationError { CannotParseFromPostCode(#[from] postcode::Error), #[error("Cannot obtain location using IP geolocate.")] GeolocationError(#[from] ipgeolocate::GeoError), + #[error("Cannot obtain location coordinates.")] + CoordinatesParseError, #[error("Cannot parse `{0}` to `{1}.")] ParseError(String, String), #[error("unknown data store error")] @@ -156,3 +159,32 @@ pub async fn local_from_public_ip() -> Result } } } + +pub async fn locate_from_coordinates( + latitude: f64, + longitude: f64, +) -> Result { + let geonames_data = get_postal_data(Country::All); + let location = GeoLocation { + latitude, + longitude, + }; + let location_data = match get_nearest_postcode(location, &geonames_data) { + Some(location_data) => location_data, + None => return Err(GeoLocationError::CoordinatesParseError), + }; + let postal_code = location_data.postal_code.clone(); + + let ip_address = match public_ip::addr().await { + Some(ip) => ip_addr_to_string(ip), + None => return Err(GeoLocationError::CannotParseIP), + }; + + Ok(GeoLocationData::new( + latitude, + longitude, + ip_address, + postal_code, + "".to_owned(), + )) +} diff --git a/src/main.rs b/src/main.rs index a8f7998..7d558fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use meteo_wizard::{ web_protocols::http_fetch, }; -use std::{process::exit}; +use std::process::exit; #[tokio::main] async fn main() { @@ -13,14 +13,13 @@ async fn main() { .filter_level(log::LevelFilter::Debug) .init(); - let geo_location_data= match geo_location::geo_data::local_from_public_ip().await { - Ok(location_data) => location_data, - Err(error) => { - log::error!("{}", error); - exit(-1) - } - }; - + let geo_location_data = match geo_location::geo_data::local_from_public_ip().await { + Ok(location_data) => location_data, + Err(error) => { + log::error!("{}", error); + exit(-1) + } + }; let url_config = UrlConfig::new( geo_location_data.get_latitude(),