Error handling
This commit is contained in:
16
backend/Cargo.lock
generated
16
backend/Cargo.lock
generated
@@ -19,6 +19,21 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-cors"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b340e9cfa5b08690aae90fb61beb44e9b06f44fe3d0f93781aaa58cfba86245e"
|
||||||
|
dependencies = [
|
||||||
|
"actix-utils",
|
||||||
|
"actix-web",
|
||||||
|
"derive_more",
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-http"
|
name = "actix-http"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
@@ -258,6 +273,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||||||
name = "aviation-weather-backend"
|
name = "aviation-weather-backend"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"actix-cors",
|
||||||
"actix-rt",
|
"actix-rt",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
@@ -23,3 +23,4 @@ serde_json = "1.0.105"
|
|||||||
tokio = { version = "1.32.0", features = ["macros", "rt"] }
|
tokio = { version = "1.32.0", features = ["macros", "rt"] }
|
||||||
uuid = { version = "1.4.1", features = ["serde", "v4"] }
|
uuid = { version = "1.4.1", features = ["serde", "v4"] }
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
|
actix-cors = "0.6.4"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
CREATE TABLE "airports" (
|
CREATE TABLE "airports" (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
full_name VARCHAR NOT NULL,
|
full_name TEXT NOT NULL,
|
||||||
icao VARCHAR NOT NULL,
|
icao TEXT NOT NULL,
|
||||||
latitude INT NOT NULL,
|
latitude DOUBLE PRECISION NOT NULL,
|
||||||
longitude INT NOT NULL
|
longitude DOUBLE PRECISION NOT NULL
|
||||||
)
|
)
|
||||||
@@ -1,38 +1,66 @@
|
|||||||
use crate::airports::{Airport, Airports};
|
use crate::airports::{Airport, Airports};
|
||||||
use crate::error_handler::CustomError;
|
use crate::error_handler::CustomError;
|
||||||
use actix_web::{delete, get, post, put, web, HttpResponse};
|
use actix_web::{delete, get, post, put, web, HttpResponse};
|
||||||
|
use log::error;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
#[get("/airports")]
|
#[get("/airports")]
|
||||||
async fn find_all() -> Result<HttpResponse, CustomError> {
|
async fn find_all() -> Result<HttpResponse, CustomError> {
|
||||||
let airports = web::block(|| Airports::find_all()).await.unwrap();
|
let airports = match web::block(|| Airports::find_all()).await.unwrap() {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(err) => {
|
||||||
|
error!("{}", err);
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
Ok(HttpResponse::Ok().json(airports))
|
Ok(HttpResponse::Ok().json(airports))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/airports/{id}")]
|
#[get("/airports/{id}")]
|
||||||
async fn find(id: web::Path<i32>) -> Result<HttpResponse, CustomError> {
|
async fn find(id: web::Path<i32>) -> Result<HttpResponse, CustomError> {
|
||||||
let airport = Airports::find(id.into_inner())?;
|
let airport = match Airports::find(id.into_inner()) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(err) => {
|
||||||
|
error!("{}", err);
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
Ok(HttpResponse::Ok().json(airport))
|
Ok(HttpResponse::Ok().json(airport))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/airports")]
|
#[post("/airports")]
|
||||||
async fn create(airport: web::Json<Airport>) -> Result<HttpResponse, CustomError> {
|
async fn create(airport: web::Json<Airport>) -> Result<HttpResponse, CustomError> {
|
||||||
let airport = Airports::create(airport.into_inner())?;
|
let airport = match Airports::create(airport.into_inner()) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(err) => {
|
||||||
|
error!("{}", err);
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
Ok(HttpResponse::Ok().json(airport))
|
Ok(HttpResponse::Ok().json(airport))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put("/airports/{id}")]
|
#[put("/airports/{id}")]
|
||||||
async fn update(
|
async fn update(id: web::Path<i32>, airport: web::Json<Airport>) -> Result<HttpResponse, CustomError> {
|
||||||
id: web::Path<i32>,
|
let airport = match Airports::update(id.into_inner(), airport.into_inner()) {
|
||||||
airport: web::Json<Airport>,
|
Ok(a) => a,
|
||||||
) -> Result<HttpResponse, CustomError> {
|
Err(err) => {
|
||||||
let airport = Airports::update(id.into_inner(), airport.into_inner())?;
|
error!("{}", err);
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
Ok(HttpResponse::Ok().json(airport))
|
Ok(HttpResponse::Ok().json(airport))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[delete("/airports/{id}")]
|
#[delete("/airports/{id}")]
|
||||||
async fn delete(id: web::Path<i32>) -> Result<HttpResponse, CustomError> {
|
async fn delete(id: web::Path<i32>) -> Result<HttpResponse, CustomError> {
|
||||||
let deleted_airport = Airports::delete(id.into_inner())?;
|
let deleted_airport = match Airports::delete(id.into_inner()) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(err) => {
|
||||||
|
error!("{}", err);
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
Ok(HttpResponse::Ok().json(json!({ "deleted": deleted_airport })))
|
Ok(HttpResponse::Ok().json(json!({ "deleted": deleted_airport })))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ extern crate diesel;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel_migrations;
|
extern crate diesel_migrations;
|
||||||
|
|
||||||
use actix_web::{App, HttpServer};
|
use actix_cors::Cors;
|
||||||
|
use actix_web::{App, HttpServer, middleware::Logger};
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use listenfd::ListenFd;
|
use listenfd::ListenFd;
|
||||||
|
use log::debug;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
mod airports;
|
mod airports;
|
||||||
@@ -17,20 +19,31 @@ mod schema;
|
|||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
if std::env::var_os("RUST_LOG").is_none() {
|
||||||
|
std::env::set_var("RUST_LOG", "info,actix=info,diesel_migrations=warn,reqwest=warn,hyper=warn");
|
||||||
|
}
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
db::init();
|
db::init();
|
||||||
|
|
||||||
let mut listenfd = ListenFd::from_env();
|
let mut listenfd = ListenFd::from_env();
|
||||||
let mut server = HttpServer::new(|| App::new()
|
let mut server = HttpServer::new(|| {
|
||||||
|
let cors = Cors::default()
|
||||||
|
.allow_any_origin()
|
||||||
|
.allow_any_method()
|
||||||
|
.allow_any_header();
|
||||||
|
App::new()
|
||||||
.configure(airports::init_routes)
|
.configure(airports::init_routes)
|
||||||
.configure(metars::init_routes)
|
.configure(metars::init_routes)
|
||||||
);
|
.wrap(cors)
|
||||||
|
.wrap(Logger::default())
|
||||||
|
});
|
||||||
|
|
||||||
server = match listenfd.take_tcp_listener(0)? {
|
server = match listenfd.take_tcp_listener(0)? {
|
||||||
Some(listener) => server.listen(listener)?,
|
Some(listener) => server.listen(listener)?,
|
||||||
None => {
|
None => {
|
||||||
let host = env::var("HOST").expect("Please set host in .env");
|
let host = env::var("HOST").expect("Please set host in .env");
|
||||||
let port = env::var("PORT").expect("Please set port in .env");
|
let port = env::var("PORT").expect("Please set port in .env");
|
||||||
|
debug!("Binding server to {}:{}", host, port);
|
||||||
server.bind(format!("{}:{}", host, port))?
|
server.bind(format!("{}:{}", host, port))?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,27 @@
|
|||||||
use crate::error_handler::CustomError;
|
use crate::error_handler::CustomError;
|
||||||
use crate::metars::Metars;
|
use crate::metars::Metars;
|
||||||
use actix_web::{get, web, HttpResponse};
|
use actix_web::{get, web, HttpResponse, Responder};
|
||||||
|
|
||||||
|
// #[get("metars/{ids}")]
|
||||||
|
// async fn get_all(ids: web::Path<String>) -> Result<HttpResponse, CustomError> {
|
||||||
|
// let airports = web::block(|| Ok::<_, CustomError>(async {Metars::get_all(ids.into_inner()).await}))
|
||||||
|
// .await
|
||||||
|
// .unwrap()
|
||||||
|
// .unwrap()
|
||||||
|
// .await
|
||||||
|
// .unwrap();
|
||||||
|
// Ok(HttpResponse::Ok().json(airports))
|
||||||
|
// }
|
||||||
|
|
||||||
#[get("metars/{ids}")]
|
#[get("metars/{ids}")]
|
||||||
async fn get_all(ids: web::Path<String>) -> Result<HttpResponse, CustomError> {
|
async fn get_all(ids: web::Path<String>) -> impl Responder {
|
||||||
let airports = web::block(|| Ok::<_, CustomError>(async {Metars::get_all(ids.into_inner()).await}))
|
let airports = web::block(|| Ok::<_, CustomError>(async {Metars::get_all(ids.into_inner()).await}))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(HttpResponse::Ok().json(airports))
|
HttpResponse::Ok().json(airports)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_routes(config: &mut web::ServiceConfig) {
|
pub fn init_routes(config: &mut web::ServiceConfig) {
|
||||||
|
|||||||
@@ -3,25 +3,23 @@ import { setAirport } from "@/js/state";
|
|||||||
import { Airport } from "@/js/airport";
|
import { Airport } from "@/js/airport";
|
||||||
import Metar from '@/components/Metar';
|
import Metar from '@/components/Metar';
|
||||||
|
|
||||||
setAirport('KJYO', new Airport('Leesburg Executive Airport', 'KJYO'))
|
// setAirport('KJYO', new Airport('Leesburg Executive Airport', 'KJYO'))
|
||||||
setAirport('KHEF', new Airport('Manassas Regional Airpoirt', 'KHEF'))
|
setAirport('KHEF', new Airport('Manassas Regional Airpoirt', 'KHEF', 38.724, -77517))
|
||||||
setAirport('KIAD', new Airport('Dulles International Airport', 'KIAD'))
|
// setAirport('KIAD', new Airport('Dulles International Airport', 'KIAD'))
|
||||||
setAirport('KFDK', new Airport('Frederick Municipal Airport', 'KFDK'))
|
// setAirport('KFDK', new Airport('Frederick Municipal Airport', 'KFDK'))
|
||||||
setAirport('KMRB', new Airport('Eastern West Virginia Regional Airport', 'KMRB'))
|
// setAirport('KMRB', new Airport('Eastern West Virginia Regional Airport', 'KMRB'))
|
||||||
setAirport('KOKV', new Airport('Winchester Regional Airport', 'KOKV'))
|
// setAirport('KOKV', new Airport('Winchester Regional Airport', 'KOKV'))
|
||||||
setAirport('KFRR', new Airport('Front Royal-Warren County Airport', 'KFRR'))
|
// setAirport('KFRR', new Airport('Front Royal-Warren County Airport', 'KFRR'))
|
||||||
setAirport('KLUA', new Airport('Luray Caverns Airport', 'KLUA'))
|
// setAirport('KLUA', new Airport('Luray Caverns Airport', 'KLUA'))
|
||||||
setAirport('KSHD', new Airport('Shenandoah Valley Airport', 'KSHD'))
|
// setAirport('KSHD', new Airport('Shenandoah Valley Airport', 'KSHD'))
|
||||||
setAirport('KCHO', new Airport('Charlottesville-Albemarle Airport', 'KCHO'))
|
// setAirport('KCHO', new Airport('Charlottesville-Albemarle Airport', 'KCHO'))
|
||||||
setAirport('KCJR', new Airport('Culpeper Regional Airport', 'KCJR'))
|
// setAirport('KCJR', new Airport('Culpeper Regional Airport', 'KCJR'))
|
||||||
setAirport('KHWY', new Airport('Warrenton-Fauquier Airport', 'KHWY'))
|
// setAirport('KHWY', new Airport('Warrenton-Fauquier Airport', 'KHWY'))
|
||||||
setAirport('KRMN', new Airport('Stafford Regional Airport', 'KRMN'))
|
// setAirport('KRMN', new Airport('Stafford Regional Airport', 'KRMN'))
|
||||||
setAirport('KEZF', new Airport('Shannon Airport', 'KEZF'))
|
// setAirport('KEZF', new Airport('Shannon Airport', 'KEZF'))
|
||||||
setAirport('KDCA', new Airport('Ronald Reagan Washington National Airport', 'KDCA'))
|
// setAirport('KDCA', new Airport('Ronald Reagan Washington National Airport', 'KDCA'))
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div>
|
<div>
|
||||||
<Metar/>
|
<Metar/>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default async function Metar() {
|
|||||||
async function update() {
|
async function update() {
|
||||||
const airports: Airport[] = getAirports();
|
const airports: Airport[] = getAirports();
|
||||||
const metars = await getMetars(airports);
|
const metars = await getMetars(airports);
|
||||||
for (let i = 0; i < airports.length; i++) {
|
for (let i = 0; i < metars.length; i++) {
|
||||||
airports[i].metar = metars[i];
|
airports[i].metar = metars[i];
|
||||||
airports[i].latitude = metars[i].latitude;
|
airports[i].latitude = metars[i].latitude;
|
||||||
airports[i].longitude = metars[i].longitude;
|
airports[i].longitude = metars[i].longitude;
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ export class Airport {
|
|||||||
longitude: number;
|
longitude: number;
|
||||||
metar: Metar | undefined;
|
metar: Metar | undefined;
|
||||||
|
|
||||||
constructor(name: string, icao: string) {
|
constructor(name: string, icao: string, latitude: number, longitude: number) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.icao = icao;
|
this.icao = icao;
|
||||||
this.latitude = 0;
|
this.latitude = latitude;
|
||||||
this.longitude = 0;
|
this.longitude = longitude;
|
||||||
this.metar = undefined;
|
this.metar = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,78 +2,88 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { xml2json } from 'xml-js';
|
// import { xml2json } from 'xml-js';
|
||||||
import { Airport } from './airport';
|
import { Airport } from './airport';
|
||||||
|
|
||||||
const base_url = 'https://beta.aviationweather.gov/cgi-bin/data';
|
// const base_url = 'https://beta.aviationweather.gov/cgi-bin/data';
|
||||||
|
|
||||||
export async function getMetars(airports: Airport[]): Promise<Metar[]> {
|
export async function getMetars(airports: Airport[]): Promise<Metar[]> {
|
||||||
const stationICAOs: string = airports
|
const stationICAOs: string = airports
|
||||||
.map((airport) => airport.icao)
|
.map((airport) => airport.icao)
|
||||||
.join(',');
|
.join(',');
|
||||||
const url = `${base_url}/metar.php?ids=${stationICAOs}&format=xml`;
|
const url = `http://localhost:5000/metars/KHEF`;
|
||||||
const response = await axios
|
const response = await axios.get(url).catch((error) => console.error(error));
|
||||||
.get(`${url}`)
|
console.log(response);
|
||||||
.catch((error) => console.error(`${error}`));
|
return [];
|
||||||
const metars: Metar[] = [];
|
|
||||||
if (response != null && response != undefined) {
|
|
||||||
const json = xml2json(response.data, { compact: true });
|
|
||||||
const jsonObject = JSON.parse(json);
|
|
||||||
let metarData = jsonObject?.response?.data?.METAR;
|
|
||||||
if (!Array.isArray(metarData)) {
|
|
||||||
metarData = [metarData];
|
|
||||||
}
|
|
||||||
for (const data of metarData) {
|
|
||||||
const sky_condition: {
|
|
||||||
sky_cover: string;
|
|
||||||
cloud_base_ft_agl: number;
|
|
||||||
}[] = [];
|
|
||||||
if (Array.isArray(data.sky_condition)) {
|
|
||||||
for (const sc of data.sky_condition) {
|
|
||||||
sky_condition.push({
|
|
||||||
sky_cover: sc.sky_cover,
|
|
||||||
cloud_base_ft_agl: Number(sc.cloud_base_ft_agl)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sky_condition.push({
|
|
||||||
sky_cover: data.sky_condition?.sky_cover,
|
|
||||||
cloud_base_ft_agl: Number(data.sky_condition?.cloud_base_ft_agl)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const metar: Metar = {
|
|
||||||
raw_text: data.raw_text._text,
|
|
||||||
station_id: data.station_id._text,
|
|
||||||
observation_time: data.observation_time._text,
|
|
||||||
latitude: Number(data.latitude._text),
|
|
||||||
longitude: Number(data.longitude._text),
|
|
||||||
temp_c: Number(data.temp_c._text),
|
|
||||||
dewpoint_c: Number(data.dewpoint_c._text),
|
|
||||||
wind_dir_degrees: data.wind_dir_degrees._text,
|
|
||||||
wind_speed_kt: Number(data.wind_speed_kt._text),
|
|
||||||
visibility_statute_mi: data.visibility_statute_mi?._text,
|
|
||||||
altim_in_hg: Number(data.altim_in_hg?._text),
|
|
||||||
sea_level_pressure_mb: data.sea_level_pressure_mb?._text,
|
|
||||||
quality_control_flags: {
|
|
||||||
auto: data.quality_control_flags?.auto?._text == 'TRUE',
|
|
||||||
auto_station: data.quality_control_flags?.auto_station?._text == 'TRUE',
|
|
||||||
},
|
|
||||||
wx_string: data.wx_string?._text,
|
|
||||||
sky_condition: sky_condition,
|
|
||||||
flight_category: data.flight_category._text,
|
|
||||||
three_hr_pressure_tendency_mb: data.three_hr_pressure_tendency_mb?._text,
|
|
||||||
metar_type: data.metar_type._text,
|
|
||||||
maxT_c: Number(data.maxT_c?._text),
|
|
||||||
minT_c: Number(data.minT_c?._text),
|
|
||||||
precip_in: Number(data.precip_in?._text),
|
|
||||||
elevation_m: Number(data.elevation_m._text),
|
|
||||||
};
|
|
||||||
metars.push(metar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return metars;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// export async function getMetars(airports: Airport[]): Promise<Metar[]> {
|
||||||
|
// const stationICAOs: string = airports
|
||||||
|
// .map((airport) => airport.icao)
|
||||||
|
// .join(',');
|
||||||
|
// const url = `${base_url}/metar.php?ids=${stationICAOs}&format=xml`;
|
||||||
|
// const response = await axios
|
||||||
|
// .get(`${url}`)
|
||||||
|
// .catch((error) => console.error(`${error}`));
|
||||||
|
// const metars: Metar[] = [];
|
||||||
|
// if (response != null && response != undefined) {
|
||||||
|
// const json = xml2json(response.data, { compact: true });
|
||||||
|
// const jsonObject = JSON.parse(json);
|
||||||
|
// let metarData = jsonObject?.response?.data?.METAR;
|
||||||
|
// if (!Array.isArray(metarData)) {
|
||||||
|
// metarData = [metarData];
|
||||||
|
// }
|
||||||
|
// for (const data of metarData) {
|
||||||
|
// const sky_condition: {
|
||||||
|
// sky_cover: string;
|
||||||
|
// cloud_base_ft_agl: number;
|
||||||
|
// }[] = [];
|
||||||
|
// if (Array.isArray(data.sky_condition)) {
|
||||||
|
// for (const sc of data.sky_condition) {
|
||||||
|
// sky_condition.push({
|
||||||
|
// sky_cover: sc.sky_cover,
|
||||||
|
// cloud_base_ft_agl: Number(sc.cloud_base_ft_agl)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// sky_condition.push({
|
||||||
|
// sky_cover: data.sky_condition?.sky_cover,
|
||||||
|
// cloud_base_ft_agl: Number(data.sky_condition?.cloud_base_ft_agl)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// const metar: Metar = {
|
||||||
|
// raw_text: data.raw_text._text,
|
||||||
|
// station_id: data.station_id._text,
|
||||||
|
// observation_time: data.observation_time._text,
|
||||||
|
// latitude: Number(data.latitude._text),
|
||||||
|
// longitude: Number(data.longitude._text),
|
||||||
|
// temp_c: Number(data.temp_c._text),
|
||||||
|
// dewpoint_c: Number(data.dewpoint_c._text),
|
||||||
|
// wind_dir_degrees: data.wind_dir_degrees._text,
|
||||||
|
// wind_speed_kt: Number(data.wind_speed_kt._text),
|
||||||
|
// visibility_statute_mi: data.visibility_statute_mi?._text,
|
||||||
|
// altim_in_hg: Number(data.altim_in_hg?._text),
|
||||||
|
// sea_level_pressure_mb: data.sea_level_pressure_mb?._text,
|
||||||
|
// quality_control_flags: {
|
||||||
|
// auto: data.quality_control_flags?.auto?._text == 'TRUE',
|
||||||
|
// auto_station: data.quality_control_flags?.auto_station?._text == 'TRUE',
|
||||||
|
// },
|
||||||
|
// wx_string: data.wx_string?._text,
|
||||||
|
// sky_condition: sky_condition,
|
||||||
|
// flight_category: data.flight_category._text,
|
||||||
|
// three_hr_pressure_tendency_mb: data.three_hr_pressure_tendency_mb?._text,
|
||||||
|
// metar_type: data.metar_type._text,
|
||||||
|
// maxT_c: Number(data.maxT_c?._text),
|
||||||
|
// minT_c: Number(data.minT_c?._text),
|
||||||
|
// precip_in: Number(data.precip_in?._text),
|
||||||
|
// elevation_m: Number(data.elevation_m._text),
|
||||||
|
// };
|
||||||
|
// metars.push(metar);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return metars;
|
||||||
|
// }
|
||||||
|
|
||||||
export interface Metar {
|
export interface Metar {
|
||||||
raw_text: string;
|
raw_text: string;
|
||||||
station_id: string;
|
station_id: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user