minimal routing code

This commit is contained in:
Nicholas Orlowsky 2025-11-19 18:32:06 -05:00
parent 2d8f131b91
commit a7d323056a
No known key found for this signature in database
GPG key ID: A9F3BA4C0AA7A70B
6 changed files with 151 additions and 20 deletions

View file

@ -1,6 +1,7 @@
use actix_web::{get, web::{self, Data}, HttpRequest, HttpResponse, Responder};
use anyhow::anyhow;
use std::{collections::HashSet, sync::Arc, time::Instant};
use log::info;
use std::{collections::{HashMap, HashSet}, sync::Arc, time::Instant};
use libseptastic::{direction, route::RouteType, stop_schedule::Trip};
use serde::{Serialize, Deserialize};
@ -35,6 +36,7 @@ async fn get_routes_html(req: HttpRequest, state: Data<Arc<AppState>>) -> impl R
}).await
}
#[get("/routes.json")]
async fn get_routes_json(state: Data<Arc<AppState>>) -> impl Responder {
let all_routes: Vec<libseptastic::route::Route> = state.gtfs_service.get_routes();
@ -73,6 +75,106 @@ async fn get_route_info(route_id: String, state: Data<Arc<AppState>>) -> ::anyho
schedule: trips
})
}
pub fn haversine_distance(lat1: f64, lon1: f64, lat2: f64, lon2: f64) -> f64 {
let r = 6371.0; // Earth's radius in kilometers
let d_lat = (lat2 - lat1).to_radians();
let d_lon = (lon2 - lon1).to_radians();
let lat1_rad = lat1.to_radians();
let lat2_rad = lat2.to_radians();
let a = (d_lat / 2.0).sin().powi(2)
+ lat1_rad.cos() * lat2_rad.cos() * (d_lon / 2.0).sin().powi(2);
let c = 2.0 * a.sqrt().asin();
r * c
}
enum RoutingNodeType {
Origin,
Destination,
Midpoint
}
struct RoutingNodePointer {
pub stop_id: String,
pub route_id: String,
pub stop_sequence: u64,
pub direction: u64
}
struct RoutingNode {
pub node_type: RoutingNodeType,
pub stop_id: String,
pub next_stops_per_routes: HashMap<String, HashSet<RoutingNodePointer>>,
pub visited: bool
}
struct TripState {
pub used_lines: HashSet<String>
}
struct Coordinates {
pub lat: f64,
pub lng: f64,
}
#[get("/directions")]
async fn get_directions(state: Data<Arc<AppState>>) -> impl Responder {
let near_thresh = 0.45;
let sig_cds = Coordinates {
lat: 40.008420,
lng: -75.213439
};
let home_cds = Coordinates {
lat: 39.957210,
lng: -75.166214
};
let all_stops = state.gtfs_service.get_all_stops();
let mut response = String::new();
let mut origin_stops: HashSet<String> = HashSet::new();
let mut dest_stops: HashSet<String> = HashSet::new();
let mut graph = HashMap::<String, RoutingNode>::new();
for stop_p in &all_stops {
let stop = stop_p.1;
let dist = haversine_distance(sig_cds.lat, sig_cds.lng, stop.lat, stop.lng);
if dist.abs() < near_thresh {
origin_stops.insert(stop.id.clone());
graph.insert(stop.id.clone(), RoutingNode {
node_type: RoutingNodeType::Origin,
stop_id: stop.id.clone(),
next_stops_per_routes: ,
visited: false
});
}
}
for stop_p in &all_stops {
let stop = stop_p.1;
let dist = haversine_distance(home_cds.lat, home_cds.lng, stop.lat, stop.lng);
if dist.abs() < near_thresh {
dest_stops.insert(stop.id.clone());
}
}
return response;
}
#[get("/route/{route_id}")]
async fn get_route(state: Data<Arc<AppState>>, req: HttpRequest, info: web::Query<RouteQueryParams>, path: web::Path<String>) -> impl Responder {