diff --git a/weather-service/src/airports/model.rs b/weather-service/src/airports/model.rs index 14b77b0..a9d373f 100644 --- a/weather-service/src/airports/model.rs +++ b/weather-service/src/airports/model.rs @@ -3,6 +3,7 @@ use crate::error_handler::CustomError; use crate::schema::airports; use diesel::prelude::*; use postgis_diesel::types::*; +use postgis_diesel::functions::*; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, AsChangeset, Insertable)] @@ -39,24 +40,12 @@ pub struct Airports { pub point: Point } -#[derive(Debug, Serialize, Deserialize)] -pub struct Bounds { - pub north_east: LatLng, - pub south_west: LatLng, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct LatLng { - pub lat: f32, - pub lon: f32 -} - impl Airports { - pub fn find_all(bounds: Bounds, limit: i32, page: i32) -> Result, CustomError> { + pub fn find_all(bounds: Polygon, limit: i32, page: i32) -> Result, CustomError> { let mut conn = db::connection()?; let airports = airports::table .limit(limit as i64) - .filter(airports::id.gt(page * limit)) + .filter(airports::id.gt(page * limit).and(st_contains(bounds, airports::point))) .load::(&mut conn)?; Ok(airports) } diff --git a/weather-service/src/airports/routes.rs b/weather-service/src/airports/routes.rs index 978f66a..24d67d4 100644 --- a/weather-service/src/airports/routes.rs +++ b/weather-service/src/airports/routes.rs @@ -1,19 +1,26 @@ -use crate::{airports::{Airport, Airports, Bounds, LatLng}, db}; +use crate::{airports::{Airport, Airports}, db}; use actix_web::{delete, get, post, put, web, HttpResponse, HttpRequest}; use log::error; +use postgis_diesel::types::{Polygon, Point}; use serde::{Serialize, Deserialize}; use serde_json::json; #[derive(Debug, Serialize, Deserialize)] struct FindAllParams { - ne_lat: f32, - ne_lon: f32, - sw_lat: f32, - sw_lon: f32, + ne_lat: f64, + ne_lon: f64, + sw_lat: f64, + sw_lon: f64, limit: i32, page: i32 } +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +struct Coordinate { + lon: f64, + lat: f64 +} + #[get("/setup")] async fn setup() -> HttpResponse { db::import_data(); @@ -23,11 +30,13 @@ async fn setup() -> HttpResponse { #[get("/airports")] async fn find_all(req: HttpRequest) -> HttpResponse { let params = web::Query::::from_query(req.query_string()).unwrap(); - let bounds = Bounds { - north_east: LatLng { lat: params.ne_lat, lon: params.ne_lon }, - south_west: LatLng { lat: params.sw_lat, lon: params.sw_lon } - }; - match web::block(move || Airports::find_all(bounds, params.limit, params.page)).await.unwrap() { + let mut polygon: Polygon = Polygon::new(Some(4326)); + polygon.add_point(Point { x: params.sw_lon, y: params.sw_lat, srid: Some(4326) }); + polygon.add_point(Point { x: params.ne_lon, y: params.sw_lat, srid: Some(4326) }); + polygon.add_point(Point { x: params.ne_lon, y: params.ne_lat, srid: Some(4326) }); + polygon.add_point(Point { x: params.sw_lon, y: params.ne_lat, srid: Some(4326) }); + polygon.add_point(Point { x: params.sw_lon, y: params.sw_lat, srid: Some(4326) }); + match web::block(move || Airports::find_all(polygon, params.limit, params.page)).await.unwrap() { Ok(a) => HttpResponse::Ok().json(a), Err(err) => { error!("{}", err); diff --git a/weather-service/src/metars/model.rs b/weather-service/src/metars/model.rs index e91d83c..2e41a9a 100644 --- a/weather-service/src/metars/model.rs +++ b/weather-service/src/metars/model.rs @@ -14,18 +14,17 @@ pub struct QualityControlFlags { #[derive(Serialize, Deserialize, AsChangeset, Insertable)] #[diesel(table_name = metars)] pub struct Metar { - pub icao: String, pub raw_text: String, pub station_id: String, pub observation_time: String, pub latitude: f64, pub longitude: f64, - pub temp_c: f64, - pub dewpoint_c: f64, - pub wind_dir_degrees: i32, - pub wind_speed_kt: i32, - pub visibility_statute_mi: String, - pub altim_in_hg: f64, + pub temp_c: Option, + pub dewpoint_c: Option, + pub wind_dir_degrees: Option, + pub wind_speed_kt: Option, + pub visibility_statute_mi: Option, + pub altim_in_hg: Option, pub sea_level_pressure_mb: Option, // pub quality_control_flags: Option, pub wx_string: Option, @@ -35,7 +34,7 @@ pub struct Metar { pub metar_type: String, #[serde(rename = "maxT_c")] pub max_t_c: Option, - #[serde(rename = "minT_c")] + #[serde(rename = " ")] pub min_t_c: Option, pub precip_in: Option, pub elevation_m: i32 @@ -43,19 +42,17 @@ pub struct Metar { #[derive(Serialize, Deserialize, Queryable)] pub struct Metars { - // pub id: i32, - // pub icao: String, pub raw_text: String, pub station_id: String, pub observation_time: String, pub latitude: f64, pub longitude: f64, - pub temp_c: f64, - pub dewpoint_c: f64, - pub wind_dir_degrees: i32, - pub wind_speed_kt: i32, - pub visibility_statute_mi: String, - pub altim_in_hg: f64, + pub temp_c: Option, + pub dewpoint_c: Option, + pub wind_dir_degrees: Option, + pub wind_speed_kt: Option, + pub visibility_statute_mi: Option, + pub altim_in_hg: Option, pub sea_level_pressure_mb: Option, pub quality_control_flags: Option, pub wx_string: Option, @@ -119,8 +116,10 @@ impl Metars { let metar_bytes = Metars::read_to_end_into_buffer(&mut reader, &e, &mut junk_buf).unwrap(); let str = std::str::from_utf8(&metar_bytes).unwrap(); let mut deserializer = Deserializer::from_str(str); - let metar = Metars::deserialize(&mut deserializer).unwrap(); - metars.push(metar); + match Metars::deserialize(&mut deserializer) { + Ok(m) => metars.push(m), + Err(err) => warn!("{}", err) + }; }, _ => () } diff --git a/weather-service/src/schema.rs b/weather-service/src/schema.rs index 54e6a47..9e330ca 100644 --- a/weather-service/src/schema.rs +++ b/weather-service/src/schema.rs @@ -27,12 +27,12 @@ diesel::table! { observation_time -> Text, latitude -> Double, longitude -> Double, - temp_c -> Double, - dewpoint_c -> Double, - wind_dir_degrees -> Integer, - wind_speed_kt -> Integer, - visibility_statute_mi -> Text, - altim_in_hg -> Double, + temp_c -> Nullable, + dewpoint_c -> Nullable, + wind_dir_degrees -> Nullable, + wind_speed_kt -> Nullable, + visibility_statute_mi -> Nullable, + altim_in_hg -> Nullable, sea_level_pressure_mb -> Nullable, wx_string -> Nullable, flight_category -> Text, diff --git a/weather-ui/src/components/MetarMap.tsx b/weather-ui/src/components/MetarMap.tsx index 56f818f..10ccc32 100644 --- a/weather-ui/src/components/MetarMap.tsx +++ b/weather-ui/src/components/MetarMap.tsx @@ -17,7 +17,7 @@ export default function Map() { center={[38.7209, -77.5133]} zoom={8} maxZoom={12} - minZoom={3} + minZoom={1} zoomControl={false} style={{ height: '96.5vh' }} className='overflow-y-hidden overflow-x-hidden' @@ -55,13 +55,17 @@ function MapTiles() { ne_lon: ne.lng, sw_lat: sw.lat, sw_lon: sw.lng, - limit: 10, + limit: 100, page: 1 }); const metars = await getMetars(_airports); - for (let i = 0; i < metars.length; i++) { - _airports[i].metar = metars[i]; - } + metars.forEach((metar) => { + _airports.forEach((airport) => { + if (metar.station_id == airport.icao) { + airport.metar = metar; + } + }); + }); setAirports(_airports); } @@ -89,7 +93,7 @@ function MapTiles() { } else if (metar?.flight_category == 'LIFR') { return 'text-red-700'; } else { - return 'text-black'; + return 'text-black/50'; } } @@ -141,15 +145,15 @@ function MapTiles() { url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' /> {airports.map((airport) => ( - + - {airport.icao} + {airport.icao} - {airport.full_name}

- {airport.icao} {airport.name} + {airport.icao} {airport.full_name}


diff --git a/weather-ui/src/js/api/airport.ts b/weather-ui/src/js/api/airport.ts index 07839d5..ce37e84 100644 --- a/weather-ui/src/js/api/airport.ts +++ b/weather-ui/src/js/api/airport.ts @@ -28,7 +28,7 @@ export async function getAirports({ page = 1 }: GetAirportsProps): Promise { const response = await axios - .get(`http://localhost:5000/airports`, { params: { ne_lat, ne_lon, sw_lat, sw_lon, page, limit } }) + .get(`http://localhost:5000/airports`, { params: { ne_lat, ne_lon, sw_lat, sw_lon, limit, page } }) .catch((error) => console.error(error)); - return response?.data; + return response?.data || []; } diff --git a/weather-ui/src/js/api/airport.types.ts b/weather-ui/src/js/api/airport.types.ts index 822b08e..15545fb 100644 --- a/weather-ui/src/js/api/airport.types.ts +++ b/weather-ui/src/js/api/airport.types.ts @@ -1,9 +1,21 @@ import { Metar } from './metar.types'; export interface Airport { - name: string; icao: string; - latitude: number; - longitude: number; + category: string; + full_name: string; + elevation_ft: string; + continent: string; + iso_country: string; + iso_region: string; + municipality: string; + gps_code: string; + iata_code: string; + local_code: string; + point: { + x: number; + y: number; + srid: number; + }; metar?: Metar; } diff --git a/weather-ui/src/js/api/metar.ts b/weather-ui/src/js/api/metar.ts index d80ae19..ecc148f 100644 --- a/weather-ui/src/js/api/metar.ts +++ b/weather-ui/src/js/api/metar.ts @@ -6,5 +6,5 @@ export async function getMetars(airports: Airport[]): Promise { const stationICAOs: string = airports.map((airport) => airport.icao).join(','); const url = `http://localhost:5000/metars/${stationICAOs}`; const response = await axios.get(url).catch((error) => console.error(error)); - return response?.data; + return response?.data || []; }