diff --git a/editor/src/plugins/show_owner.rs b/editor/src/plugins/show_owner.rs index 822babf17c..07479d9b5e 100644 --- a/editor/src/plugins/show_owner.rs +++ b/editor/src/plugins/show_owner.rs @@ -11,7 +11,7 @@ pub enum ShowOwnerState { Inactive, BuildingSelected(BuildingID, HashSet), CarSelected(CarID, Option), - ShapeSelected(ExtraShapeID, Option), + ShapeSelected(ExtraShapeID, Option<(RoadID, bool)>), } impl ShowOwnerState { @@ -88,8 +88,11 @@ impl Plugin for ShowOwnerState { return Some(color); } } - (ShowOwnerState::ShapeSelected(_, Some(r)), ID::Lane(l)) => { - if ctx.map.get_parent(l).id == *r { + (ShowOwnerState::ShapeSelected(_, Some((r, fwds))), ID::Lane(l)) => { + let parent = ctx.map.get_parent(l); + if parent.id == *r + && ((*fwds && parent.is_forwards(l)) || (!fwds && parent.is_backwards(l))) + { return Some(color); } } diff --git a/editor/src/render/extra_shape.rs b/editor/src/render/extra_shape.rs index bd14c7c4ab..2c6516a42e 100644 --- a/editor/src/render/extra_shape.rs +++ b/editor/src/render/extra_shape.rs @@ -28,7 +28,7 @@ pub struct DrawExtraShape { pub id: ExtraShapeID, shape: Shape, pub attributes: BTreeMap, - pub road: Option, + pub road: Option<(RoadID, bool)>, } impl DrawExtraShape { @@ -36,7 +36,7 @@ impl DrawExtraShape { id: ExtraShapeID, s: ExtraShape, gps_bounds: &GPSBounds, - closest: &FindClosest, + closest: &FindClosest<(RoadID, bool)>, ) -> Option { let mut pts: Vec = Vec::new(); for pt in s.points.into_iter() { diff --git a/editor/src/render/map.rs b/editor/src/render/map.rs index ed46a339bc..8944ff6292 100644 --- a/editor/src/render/map.rs +++ b/editor/src/render/map.rs @@ -7,7 +7,7 @@ use geom::{Bounds, Pt2D}; use kml::ExtraShape; use map_model::{ AreaID, BuildingID, BusStopID, FindClosest, IntersectionID, Lane, LaneID, Map, ParcelID, - RoadID, Turn, TurnID, + RoadID, Turn, TurnID, LANE_THICKNESS, }; use objects::ID; use plugins::hider::Hider; @@ -86,11 +86,15 @@ impl DrawMap { let mut extra_shapes: Vec = Vec::new(); if !raw_extra_shapes.is_empty() { - // Match shapes with the nearest road - let mut closest: FindClosest = map_model::FindClosest::new(&map.get_bounds()); - // TODO double each road into two sides... + // Match shapes with the nearest road + direction (true for forwards) + let mut closest: FindClosest<(RoadID, bool)> = + map_model::FindClosest::new(&map.get_bounds()); for r in map.all_roads().iter() { - closest.add(r.id, &r.center_pts); + closest.add((r.id, true), &r.center_pts.shift_blindly(LANE_THICKNESS)); + closest.add( + (r.id, false), + &r.center_pts.reversed().shift_blindly(LANE_THICKNESS), + ); } let gps_bounds = map.get_gps_bounds(); diff --git a/map_model/src/road.rs b/map_model/src/road.rs index c651b0fcb7..67ad18da74 100644 --- a/map_model/src/road.rs +++ b/map_model/src/road.rs @@ -50,6 +50,20 @@ impl Road { ) } + pub fn is_forwards(&self, lane: LaneID) -> bool { + self.children_forwards + .iter() + .find(|(id, _)| *id == lane) + .is_some() + } + + pub fn is_backwards(&self, lane: LaneID) -> bool { + self.children_backwards + .iter() + .find(|(id, _)| *id == lane) + .is_some() + } + // lane must belong to this road. Offset 0 is the centermost lane on each side of a road, then // it counts up from there. Returns true for the forwards direction, false for backwards. pub fn dir_and_offset(&self, lane: LaneID) -> (bool, usize) {