giving up on db schema in favor of prototyping

This commit is contained in:
Pagwin 2024-02-17 16:21:59 -05:00
parent 9676f7d7e1
commit aa3902f1a4
8 changed files with 298 additions and 6 deletions

View file

@ -0,0 +1,45 @@
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20240217_000000_create_route_table" // Make sure this matches with the file name
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
// Define how to apply this migration: Create the table.
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(RouteStopRelation::Table)
.col(
ColumnDef::new(RouteStopRelation::RouteId)
.integer()
.not_null()
.primary_key(),
)
.col(ColumnDef::new(RouteStopRelationRoute::Name).string().not_null())
.col(ColumnDef::new(RouteStopRelationBakery::ProfitMargin).double().not_null())
.to_owned(),
)
.await
}
// Define how to rollback this migration: Drop the Bakery table.
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(Bakery::Table).to_owned())
.await
}
}
#[derive(Iden)]
pub enum RouteStopRelation{
Table,
RouteId,
StopId,
}

View file

@ -0,0 +1,45 @@
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20240217_000000_create_route_table" // Make sure this matches with the file name
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
// Define how to apply this migration: Create the table.
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(Route::Table)
.col(
ColumnDef::new(Route::Id)
.integer()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(Route::Name).string().not_null())
.to_owned(),
)
.await
}
// Define how to rollback this migration: Drop the Bakery table.
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(Bakery::Table).to_owned())
.await
}
}
#[derive(Iden)]
pub enum Route {
Table,
Id,
Name,
}

View file

@ -2,9 +2,11 @@ extern crate tokio;
extern crate reqwest;
extern crate tide;
extern crate anyhow;
extern crate sea_orm;
//extern crate sea_orm;
mod state;
mod route;
mod stop;
use tide::prelude::*;
@ -13,7 +15,8 @@ async fn main() -> anyhow::Result<()> {
let mut app = tide::with_state(state::State::new().await?);
app.at("/path").get(transit_path);
app.at("/time-to-arrive").get(transit_estimate);
app.at("/time_to_arrive").get(transit_estimate);
app.at("/route_draw").get(bus_route_draw);
// TODO: change to 0.0.0.0 when docker image done
app.listen("127.0.0.1:8080").await?;
@ -21,12 +24,51 @@ async fn main() -> anyhow::Result<()> {
}
/// return the best path with the request specifying ISO time, lat and longitude in query params
/// return the best path of buses with the request specifying ISO time, lat and longitude in query params
/// Example return
/// {
/// "path": [
/// {
/// "route_name": "WS Outbound",
/// "enter_stop_id": 3,
/// "exit_stop_id": 10,
/// "enter_stop_coords": {"lat":23.3512, "lon": 1231.123123}
/// },
/// ...
/// ]
/// }
async fn transit_path(mut req: tide::Request<state::State>)->tide::Result{
Ok("".into())
}
/// return the num of estimated seconds for bus id and stop ids given in query params
/// return the num of estimated seconds for stop ids given in query params
/// example return:
/// 23
async fn transit_estimate(mut req: tide::Request<state::State>)->tide::Result{
Ok("".into())
}
/// return the coord pairs as json and line color forgiven route id in query params
/// Example return:
/// {"color":"#0000ff", "stops":[[-75,23],[-21,72]]}
async fn bus_route_draw(mut req: tide::Request<state::State>)->tide::Result{
match req.query::<RouteDrawQuery>()?.id.split("_").collect::<Vec<&str>>()[..] {
["OCCT", id] => {
let route = route::occt_route_get(id.parse());
},
["BC", id] => {
let route = route::broome_county_route_get(id.parse());
},
_ => {
return Ok(tide::Response::builder(400).body("Error: invalid id").into())
}
}
Ok("".into())
}
#[derive(serde::Deserialize)]
struct RouteDrawQuery{
id: String
}

91
src/route.rs Normal file
View file

@ -0,0 +1,91 @@
struct Route {
id:u32,
name: String,
short_name: String,
color: String,
poly_line: String,
stops: Vec<crate::stop::Stop>
}
#[derive(serde::Deserialize)]
struct OcctRoute {
id:u32,
name: String,
#[serde(rename(deserialize = "abbr"))]
short_name: String,
#[serde(rename(deserialize = "encLine"))]
poly_line: String,
stops:Vec<u32>,
color: String
}
//impl From<OcctRoute> for Route{
// fn from(OcctRoute{id,name,short_name,poly_line,stops, color}: OcctRoute) -> Self {
// Self {
// id,
// name,
// short_name,
// color,
// poly_line,
//
// }
// }
//}
#[derive(serde::Deserialize)]
struct BCRoute{
id:u32,
name: String,
short_name: String,
color: String,
path: Vec<f64>,
active: bool,
stops:Vec<u32>
}
#[derive(serde::Deserialize)]
struct OcctWrap{
get_routes:Vec<OcctRoute>
}
async fn occt_routes_get()->anyhow::Result<Vec<Route>>{
let resp = reqwest::get("http://binghamtonupublic.etaspot.net/service.php?service=get_routes&token=TESTING").await?;
let body = resp.text().await?;
let OcctWrap{get_routes: routes} = serde_json::from_str(body.as_str())?;
let stops = crate::stop::occt_stops_get().await?;
let routes = routes.into_iter().map(|route|{
let stops = stops.iter()
.filter(|stop|{
route.stops.iter().any(|id|*id==stop.id)
}).map(Clone::clone).collect();
Route{
id:route.id,
color:route.color,
name:route.name,
poly_line:route.poly_line,
short_name: route.short_name,
stops
}
}).collect();
Ok(routes)
}
async fn broom_county_routes_get()->anyhow::Result<Route>{
let resp = reqwest::get("https://bctransit.doublemap.com/map/v2/routes").await?;
let body = resp.text().await?;
let routes:Vec<BCRoute> = serde_json::from_str(body.as_str())?;
let stops = crate::stop::BC_stops_get().await?;
let routes = routes.into_iter().map(|route|{
let stops = stops.iter()
.filter(|stop|{
route.stops.iter().any(|id|*id==stop.id)
}).map(Clone::clone).collect();
let poly_line = crate::stop::poly_encode_stops(stops).await;
Route{
id:route.id,
color:route.color,
name:route.name,
poly_line,
short_name: route.short_name,
stops
}
}).collect();
Ok(routes)
}

View file

@ -1,13 +1,13 @@
#[derive(Clone)]
pub struct State{
pub db: sea_orm::DatabaseConnection
//pub db: sea_orm::DatabaseConnection
}
const DEFAULT_DB_CONN:&'static str = "sqlite://default_db.db";
impl State{
pub async fn new() -> anyhow::Result<Self> {
Ok(Self{
db: sea_orm::Database::connect(DEFAULT_DB_CONN).await?
//db: sea_orm::Database::connect(DEFAULT_DB_CONN).await?
})
}
}

69
src/stop.rs Normal file
View file

@ -0,0 +1,69 @@
#[derive(Clone)]
pub struct Stop{
pub id:u32,
pub name:String,
pub lat: f64,
pub lon: f64,
}
#[derive(serde::Deserialize)]
struct OcctStop{
id:u32,
name:String,
lat: f64,
#[serde(rename(deserialize = "lng"))]
lon: f64,
}
impl From<OcctStop> for Stop{
fn from(OcctStop{id,name,lat,lon}: OcctStop) -> Self {
Self {
id,
name,
lat,
lon
}
}
}
#[derive(serde::Deserialize)]
struct BCStop{
id:u32,
name:String,
lat: f64,
lon: f64,
}
impl From<BCStop> for Stop{
fn from(BCStop{id,name,lat,lon}: BCStop) -> Self {
Self {
id,
name,
lat,
lon
}
}
}
pub async fn occt_stops_get()->anyhow::Result<Vec<Stop>>{
Ok(Vec::new())
}
pub async fn BC_stops_get()->anyhow::Result<Vec<Stop>>{
Ok(Vec::new())
}
pub fn poly_encode_stops<I:IntoIterator<Item=Stop>>(stops:I)->String{
stops.into_iter()
.map(|stop|{
enc_float(stop.lat)
})
.reduce(|s1,s2|s1+&s2)
fn enc_float(num:f64)->String{
let mut working:i32 = (num*1e5).round();
//hopethis does what's needed
working<<=1;
if num < 0 {
working = !working;
}
let mut bits:[bool;30] = [false;30];
for i in 0..30{
bits[i] = working % 2 == 1;
working >>=1;
}
}