use crate::LatLon;
use chrono::NaiveDate;
use rstar::{PointDistance, RTreeObject, AABB};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct StationWithDistance {
pub station: Station,
pub distance_km: f64,
pub requested_point: LatLon,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Station {
pub id: String,
pub country: String,
pub region: Option<String>,
pub timezone: Option<String>,
pub name: HashMap<String, String>,
pub identifiers: Identifiers,
pub location: StationLocation,
pub inventory: Inventory,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct Inventory {
pub daily: DateRange,
pub hourly: DateRange,
pub model: DateRange,
pub monthly: YearRange,
pub normals: YearRange,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct DateRange {
pub start: Option<NaiveDate>,
pub end: Option<NaiveDate>,
}
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
pub struct YearRange {
pub start: Option<i32>,
pub end: Option<i32>,
}
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
pub struct Identifiers {
pub national: Option<String>,
pub wmo: Option<String>,
pub icao: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct StationLocation {
pub latitude: f64,
pub longitude: f64,
pub elevation: Option<i32>,
}
impl RTreeObject for Station {
type Envelope = AABB<[f64; 2]>;
fn envelope(&self) -> Self::Envelope {
AABB::from_point([self.location.latitude, self.location.longitude])
}
}
impl PointDistance for Station {
fn distance_2(&self, point: &[f64; 2]) -> f64 {
let dx = self.location.latitude - point[0];
let dy = self.location.longitude - point[1];
dx.mul_add(dx, dy * dy)
}
}