From 80be8d4a99ed463289e6ec4af087f0d46ccb72c6 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sun, 26 May 2024 15:30:05 +0100 Subject: [PATCH] Change the start time --- backend/src/isochrone.rs | 17 +++++++++++------ backend/src/lib.rs | 5 +++++ backend/src/transit_route.rs | 3 +-- web/src/IsochroneMode.svelte | 14 ++++++++++++-- web/src/RouteMode.svelte | 25 +++++++++++++++++++++---- web/src/worker.ts | 4 ++++ 6 files changed, 54 insertions(+), 14 deletions(-) diff --git a/backend/src/isochrone.rs b/backend/src/isochrone.rs index ddfd79f..b1ea457 100644 --- a/backend/src/isochrone.rs +++ b/backend/src/isochrone.rs @@ -16,13 +16,21 @@ pub fn calculate( mode: Mode, contours: bool, public_transit: bool, + start_time: NaiveTime, mut timer: Timer, ) -> Result { // 15 minutes let limit = Duration::from_secs(15 * 60); timer.step("get_costs"); - let cost_per_road = get_costs(graph, req, mode, public_transit, limit); + let cost_per_road = get_costs( + graph, + req, + mode, + public_transit, + start_time, + start_time + limit, + ); timer.push("render to GJ"); // Show cost per road @@ -58,12 +66,9 @@ fn get_costs( req: Coord, mode: Mode, public_transit: bool, - limit: Duration, + start_time: NaiveTime, + end_time: NaiveTime, ) -> HashMap { - // TODO plumb in - let start_time = NaiveTime::from_hms_opt(7, 0, 0).unwrap(); - let end_time = start_time + limit; - let start = graph.closest_intersection[mode] .nearest_neighbor(&[req.x, req.y]) .unwrap() diff --git a/backend/src/lib.rs b/backend/src/lib.rs index 79191ee..9ea2f5f 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -5,6 +5,7 @@ extern crate log; use std::sync::Once; +use chrono::NaiveTime; use geo::Coord; use serde::Deserialize; use wasm_bindgen::prelude::*; @@ -95,6 +96,7 @@ impl MapModel { mode, req.contours, req.mode == "transit", + NaiveTime::parse_from_str(&req.start_time, "%H:%M").map_err(err_to_js)?, Timer::new("isochrone request", None), ) .map_err(err_to_js) @@ -135,6 +137,7 @@ impl MapModel { end, req.debug_search, req.use_heuristic, + NaiveTime::parse_from_str(&req.start_time, "%H:%M").map_err(err_to_js)?, Timer::new("route request", None), ) .map_err(err_to_js) @@ -152,6 +155,7 @@ pub struct IsochroneRequest { y: f64, mode: String, contours: bool, + start_time: String, } #[derive(Deserialize)] @@ -164,6 +168,7 @@ pub struct RouteRequest { // TODO Only works for transit debug_search: bool, use_heuristic: bool, + start_time: String, } fn err_to_js(err: E) -> JsValue { diff --git a/backend/src/transit_route.rs b/backend/src/transit_route.rs index 55ab2e5..fceae7f 100644 --- a/backend/src/transit_route.rs +++ b/backend/src/transit_route.rs @@ -21,10 +21,9 @@ pub fn route( // like a good idea yet debug_search: bool, use_heuristic: bool, + start_time: NaiveTime, mut timer: Timer, ) -> Result { - // TODO We'll need a start time too (and a day of the week) - let start_time = NaiveTime::from_hms_opt(7, 0, 0).unwrap(); if start == end { bail!("start = end"); } diff --git a/web/src/IsochroneMode.svelte b/web/src/IsochroneMode.svelte index e187730..35c1f1a 100644 --- a/web/src/IsochroneMode.svelte +++ b/web/src/IsochroneMode.svelte @@ -13,6 +13,7 @@ import { onMount } from "svelte"; let travelMode: TravelMode = "foot"; + let startTime = "07:00"; let start: { lng: number; lat: number } | null = null; onMount(async () => { @@ -35,6 +36,7 @@ _x: { lng: number; lat: number } | null, _y: TravelMode, _z: boolean, + _t: string, ) { if (start) { try { @@ -42,6 +44,7 @@ start, mode: travelMode, contours, + startTime, }); err = ""; } catch (err: any) { @@ -50,11 +53,12 @@ } } } - $: updateIsochrone(start, travelMode, contours); + $: updateIsochrone(start, travelMode, contours, startTime); async function updateRoute( x: { lng: number; lat: number } | null, _y: Feature | null, + _t: string, ) { if (start && hoveredAmenity) { try { @@ -64,6 +68,7 @@ mode: travelMode, debugSearch: false, useHeuristic: false, + startTime, }); err = ""; } catch (err: any) { @@ -74,7 +79,7 @@ routeGj = null; } } - $: updateRoute(start, hoveredAmenity); + $: updateRoute(start, hoveredAmenity, startTime); function lerp(pct: number, a: number, b: number): number { return a + pct * (b - a); @@ -102,6 +107,11 @@ + + diff --git a/web/src/RouteMode.svelte b/web/src/RouteMode.svelte index 854a150..039e3a3 100644 --- a/web/src/RouteMode.svelte +++ b/web/src/RouteMode.svelte @@ -17,6 +17,7 @@ let travelMode: TravelMode = "foot"; let useHeuristic = true; + let startTime = "07:00"; let start: { lng: number; lat: number } | null = null; let end: { lng: number; lat: number } | null = null; @@ -41,6 +42,7 @@ _y: { lng: number; lat: number } | null, mode: TravelMode, _z: boolean, + _t: string, ) { if (start && end) { try { @@ -50,6 +52,7 @@ mode, debugSearch: false, useHeuristic, + startTime, }); err = ""; } catch (error: any) { @@ -58,7 +61,7 @@ } } } - $: updateRoute(start, end, travelMode, useHeuristic); + $: updateRoute(start, end, travelMode, useHeuristic, startTime); function onRightClick(e: CustomEvent) { // Move the first marker, for convenience @@ -77,6 +80,7 @@ mode: travelMode, debugSearch: true, useHeuristic, + startTime, }); $mode = { kind: "debug-route", @@ -102,11 +106,19 @@ >Isochrone mode + + + + +

Move the A and B pins to find a route. (Hint: right-click to set the first pin somewhere.) @@ -119,10 +131,15 @@ {#each gj.features as f} {@const props = notNull(f.properties)} {#if props.kind == "road"} -

  • Walk
  • + {#if props.time1} +
  • [{props.time1} - {props.time2}] Walk
  • + {:else} +
  • Walk / cycle / drive
  • + {/if} {:else}
  • - Take {props.route} for {props.num_stops} stops + [{props.time1} - {props.time2}] Take {props.route} for {props.num_stops} + stops
  • {/if} {/each} diff --git a/web/src/worker.ts b/web/src/worker.ts index 7f30379..defeb1e 100644 --- a/web/src/worker.ts +++ b/web/src/worker.ts @@ -67,6 +67,7 @@ export class Backend { start: { lng: number; lat: number }; mode: TravelMode; contours: boolean; + startTime: string; }): FeatureCollection { if (!this.inner) { throw new Error("Backend used without a file loaded"); @@ -78,6 +79,7 @@ export class Backend { y: req.start.lat, mode: req.mode, contours: req.contours, + start_time: req.startTime, }), ); } @@ -89,6 +91,7 @@ export class Backend { mode: TravelMode; debugSearch: boolean; useHeuristic: boolean; + startTime: string; }): FeatureCollection { if (!this.inner) { throw new Error("Backend used without a file loaded"); @@ -103,6 +106,7 @@ export class Backend { mode: req.mode, debug_search: req.debugSearch, use_heuristic: req.useHeuristic, + start_time: req.startTime, }), ); }