giving up on db schema in favor of prototyping
This commit is contained in:
parent
9676f7d7e1
commit
aa3902f1a4
8 changed files with 298 additions and 6 deletions
|
@ -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,
|
||||
}
|
|
@ -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,
|
||||
}
|
50
src/main.rs
50
src/main.rs
|
@ -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
91
src/route.rs
Normal 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)
|
||||
}
|
|
@ -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
69
src/stop.rs
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue