data parsed?
parent
36c58bb9e1
commit
c613abc83a
|
@ -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();
|
||||||
|
|
103
src/main.rs
103
src/main.rs
|
@ -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)],
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/parse.rs
13
src/parse.rs
|
@ -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(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue