data parsed?

main
Zynh0722 2024-04-23 23:18:42 -07:00
parent 36c58bb9e1
commit c613abc83a
3 changed files with 106 additions and 12 deletions

View File

@ -1,6 +1,6 @@
const EARTH_RAD_METERS: f64 = 6371e3; const EARTH_RAD_METERS: f64 = 6371e3;
type LatLon = (f64, f64); pub type LatLon = (f64, f64);
pub fn haversine(a: LatLon, b: LatLon) -> f64 { pub fn haversine(a: LatLon, b: LatLon) -> f64 {
let a_latitude = a.0.to_radians(); let a_latitude = a.0.to_radians();

View File

@ -1,13 +1,88 @@
#![allow(dead_code)]
mod distance; mod distance;
mod parse; mod parse;
use std::collections::HashMap; use std::{
collections::{hash_map::Entry, HashMap},
rc::Rc,
};
use parse::Record; use parse::Record;
#[derive(Debug)] type Graph = HashMap<String, Node>;
type Airports = HashMap<usize, Rc<Airport>>;
#[derive(Debug, Clone)]
struct Node { struct Node {
destinations: Vec<Record>, origin: Rc<Airport>,
destinations: Vec<Destination>,
visited: bool,
}
impl Node {
fn new(origin: Rc<Airport>, destinations: Vec<Destination>) -> Self {
Node {
destinations,
origin,
visited: false,
}
}
}
#[derive(Debug, Clone)]
struct Airport {
id: usize,
code: String,
name: String,
city: String,
country: String,
lat: f64,
lon: f64,
}
#[derive(Debug, Clone)]
struct Destination {
airport: Rc<Airport>,
distance: f64,
}
impl Destination {
fn new(source: &Airport, destination: Rc<Airport>) -> Self {
Destination {
distance: distance::haversine(
(source.lat, source.lon),
(destination.lat, destination.lon),
),
airport: destination,
}
}
}
fn insert_airports_from_record(airports: &mut Airports, record: &Record) {
if let Entry::Vacant(entry) = airports.entry(record.origin_airport_id) {
entry.insert(Rc::new(Airport {
id: record.origin_airport_id,
code: record.origin_airport_code.clone(),
name: record.origin_airport.clone(),
city: record.origin_city.clone(),
country: record.origin_country.clone(),
lat: record.origin_airport_latitude,
lon: record.origin_airport_longitude,
}));
}
if let Entry::Vacant(entry) = airports.entry(record.destination_airport_id) {
entry.insert(Rc::new(Airport {
id: record.destination_airport_id,
code: record.destination_airport_code.clone(),
name: record.destination_airport.clone(),
city: record.destination_city.clone(),
country: record.destination_country.clone(),
lat: record.destination_airport_latitude,
lon: record.destination_airport_longitude,
}));
}
} }
fn main() { fn main() {
@ -17,17 +92,25 @@ fn main() {
.flatten() .flatten()
.collect(); .collect();
let mut graph: HashMap<String, Node> = HashMap::new(); let mut airports: Airports = HashMap::new();
for record in data.into_iter() { for record in &data {
use std::collections::hash_map::Entry; insert_airports_from_record(&mut airports, record);
}
let mut graph: Graph = HashMap::new();
for record in data {
match graph.entry(record.origin_airport_code.clone()) { match graph.entry(record.origin_airport_code.clone()) {
Entry::Occupied(mut entry) => entry.get_mut().destinations.push(record), Entry::Occupied(mut entry) => entry
.get_mut()
.destinations
.push(record.get_destination(&airports)),
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
entry.insert(Node { entry.insert(Node::new(
destinations: vec![record], airports[&record.origin_airport_id].clone(),
}); vec![record.get_destination(&airports)],
));
} }
} }
} }

View File

@ -1,4 +1,6 @@
#[derive(Debug, serde::Deserialize)] use crate::{Airports, Destination};
#[derive(Debug, Clone, serde::Deserialize)]
pub struct Record { pub struct Record {
pub origin_airport_code: String, pub origin_airport_code: String,
pub origin_airport: String, pub origin_airport: String,
@ -15,3 +17,12 @@ pub struct Record {
pub destination_city: String, pub destination_city: String,
pub destination_country: String, pub destination_country: String,
} }
impl Record {
pub fn get_destination(&self, airports: &Airports) -> Destination {
Destination::new(
&airports[&self.origin_airport_id],
airports[&self.destination_airport_id].clone(),
)
}
}