From 9f8ce0a63ef84ab37f17afc4c6e040c87202b6d6 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Fri, 5 Jan 2024 17:22:23 +0000 Subject: [PATCH] Show two routes, before & after --- backend/src/map_model.rs | 22 +++++++++++++++++++--- backend/src/route.rs | 1 + backend/src/scrape.rs | 6 ++++-- web/src/RenderNeighbourhood.svelte | 2 +- web/src/RouteMode.svelte | 17 ++++++++++++++--- 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/backend/src/map_model.rs b/backend/src/map_model.rs index 868a18a..836b280 100644 --- a/backend/src/map_model.rs +++ b/backend/src/map_model.rs @@ -16,7 +16,9 @@ pub struct MapModel { pub intersections: Vec, // All geometry stored in worldspace, including rtrees pub mercator: Mercator, - pub router: Router, + // TODO Wasteful, can share some + pub router_original: Router, + pub router_current: Router, // TODO Keep edits / state here or not? pub modal_filters: BTreeMap, @@ -111,6 +113,11 @@ impl MapModel { )); self.undo_stack.push(cmd); self.redo_queue.clear(); + self.after_edited(); + } + + fn after_edited(&mut self) { + self.router_current = Router::new(&self.roads, &self.intersections, &self.modal_filters); } pub fn add_many_modal_filters( @@ -131,12 +138,14 @@ impl MapModel { let cmd = self.do_edit(Command::Multiple(edits)); self.undo_stack.push(cmd); self.redo_queue.clear(); + self.after_edited(); } pub fn delete_modal_filter(&mut self, r: RoadID) { let cmd = self.do_edit(Command::SetModalFilter(r, None)); self.undo_stack.push(cmd); self.redo_queue.clear(); + self.after_edited(); } // Returns the command to undo this one @@ -166,6 +175,7 @@ impl MapModel { if let Some(cmd) = self.undo_stack.pop() { let cmd = self.do_edit(cmd); self.redo_queue.push(cmd); + self.after_edited(); } } @@ -176,6 +186,7 @@ impl MapModel { let cmd = self.redo_queue.remove(0); let cmd = self.do_edit(cmd); self.undo_stack.push(cmd); + self.after_edited(); } pub fn to_savefile(&self, neighbourhood: Option<&Neighbourhood>) -> GeoJson { @@ -236,14 +247,19 @@ impl MapModel { x => bail!("Unknown kind in savefile {x}"), } } + self.router_current = Router::new(&self.roads, &self.intersections, &self.modal_filters); Ok(boundary) } pub fn compare_route(&self, pt1: Coord, pt2: Coord) -> GeoJson { let mut features = Vec::new(); - // TODO before, after - if let Some(linestring) = self.router.route(self, pt1, pt2) { + if let Some(linestring) = self.router_original.route(self, pt1, pt2) { + let mut f = Feature::from(Geometry::from(&self.mercator.to_wgs84(&linestring))); + f.set_property("kind", "before"); + features.push(f); + } + if let Some(linestring) = self.router_current.route(self, pt1, pt2) { let mut f = Feature::from(Geometry::from(&self.mercator.to_wgs84(&linestring))); f.set_property("kind", "after"); features.push(f); diff --git a/backend/src/route.rs b/backend/src/route.rs index 7e3e708..508da8e 100644 --- a/backend/src/route.rs +++ b/backend/src/route.rs @@ -7,6 +7,7 @@ use rstar::RTree; use crate::{Intersection, IntersectionID, MapModel, ModalFilter, NodeMap, Road, RoadID}; +#[derive(Clone)] pub struct Router { ch: FastGraph, node_map: NodeMap, diff --git a/backend/src/scrape.rs b/backend/src/scrape.rs index 76a9921..ac66d82 100644 --- a/backend/src/scrape.rs +++ b/backend/src/scrape.rs @@ -54,13 +54,15 @@ pub fn scrape_osm(input_bytes: &[u8]) -> Result { } let modal_filters = BTreeMap::new(); - let router = Router::new(&roads, &intersections, &modal_filters); + let router_original = Router::new(&roads, &intersections, &modal_filters); + let router_current = router_original.clone(); Ok(MapModel { roads, intersections, mercator, - router, + router_original, + router_current, modal_filters, undo_stack: Vec::new(), diff --git a/web/src/RenderNeighbourhood.svelte b/web/src/RenderNeighbourhood.svelte index 636b8c9..2e0c9ce 100644 --- a/web/src/RenderNeighbourhood.svelte +++ b/web/src/RenderNeighbourhood.svelte @@ -66,7 +66,7 @@ manageHoverState paint={{ "fill-color": ["get", "color"], - "fill-opacity": hoverStateFilter(0.3, 0.5), + "fill-opacity": interactive ? hoverStateFilter(0.3, 0.5) : 0.3, }} /> diff --git a/web/src/RouteMode.svelte b/web/src/RouteMode.svelte index 2d2ba6a..df3d5e4 100644 --- a/web/src/RouteMode.svelte +++ b/web/src/RouteMode.svelte @@ -2,7 +2,7 @@ import { LngLat } from "maplibre-gl"; import { onDestroy, onMount } from "svelte"; import { GeoJSON, LineLayer, Marker } from "svelte-maplibre"; - import { bbox } from "./common"; + import { bbox, constructMatchExpression } from "./common"; import RenderNeighbourhood from "./RenderNeighbourhood.svelte"; import SplitComponent from "./SplitComponent.svelte"; import { app, map, mode } from "./stores"; @@ -48,6 +48,10 @@

Drag markers for a route

+

+ Route before, + route after +

@@ -58,8 +62,15 @@