diff --git a/game/src/edit/roads.rs b/game/src/edit/roads.rs index 5a7db162df..e085e10044 100644 --- a/game/src/edit/roads.rs +++ b/game/src/edit/roads.rs @@ -531,8 +531,8 @@ fn width_choices(app: &App, l: LaneID) -> Vec> { LaneSpec::typical_lane_widths(lane.lane_type, &app.primary.map.get_r(lane.parent).osm_tags); if !choices.iter().any(|(x, _)| *x == lane.width) { choices.push((lane.width, "custom")); - choices.sort(); } + choices.sort(); choices .into_iter() .map(|(x, label)| Choice::new(format!("{} - {}", x.to_string(&app.opts.units), label), x)) diff --git a/map_model/src/lib.rs b/map_model/src/lib.rs index f128b405f7..7375e82ac7 100644 --- a/map_model/src/lib.rs +++ b/map_model/src/lib.rs @@ -32,7 +32,7 @@ use serde::{Deserialize, Serialize}; use abstio::MapName; use abstutil::{deserialize_btreemap, serialize_btreemap}; -use geom::{Bounds, Distance, GPSBounds, Polygon}; +use geom::{Bounds, GPSBounds, Polygon}; pub use crate::city::City; pub use crate::edits::{ @@ -46,7 +46,10 @@ pub use crate::objects::building::{ }; pub use crate::objects::bus_stop::{BusRoute, BusRouteID, BusStop, BusStopID}; pub use crate::objects::intersection::{Intersection, IntersectionID, IntersectionType}; -pub use crate::objects::lane::{Lane, LaneID, LaneSpec, LaneType, PARKING_LOT_SPOT_LENGTH}; +pub use crate::objects::lane::{ + Lane, LaneID, LaneSpec, LaneType, NORMAL_LANE_THICKNESS, PARKING_LOT_SPOT_LENGTH, + SIDEWALK_THICKNESS, +}; pub use crate::objects::parking_lot::{ParkingLot, ParkingLotID}; pub use crate::objects::road::{DirectedRoadID, Direction, Road, RoadID}; pub use crate::objects::stop_signs::{ControlStopSign, RoadWithStopSign}; @@ -73,12 +76,6 @@ mod pathfind; pub mod raw; mod traversable; -// TODO Minimize uses of these! -pub const NORMAL_LANE_THICKNESS: Distance = Distance::const_meters(2.5); -pub(crate) const SERVICE_ROAD_LANE_THICKNESS: Distance = Distance::const_meters(1.5); -pub const SIDEWALK_THICKNESS: Distance = Distance::const_meters(1.5); -pub(crate) const SHOULDER_THICKNESS: Distance = Distance::const_meters(0.5); - // The map used by the simulation and UI. This struct is declared here so that the rest of the // crate can reach into private fields. #[derive(Serialize, Deserialize)] diff --git a/map_model/src/make/initial/lane_specs.rs b/map_model/src/make/initial/lane_specs.rs index f881bc29b1..548d86a748 100644 --- a/map_model/src/make/initial/lane_specs.rs +++ b/map_model/src/make/initial/lane_specs.rs @@ -3,36 +3,20 @@ use std::iter; use abstutil::Tags; -use crate::{ - osm, Direction, DrivingSide, LaneSpec, LaneType, MapConfig, NORMAL_LANE_THICKNESS, - SERVICE_ROAD_LANE_THICKNESS, SHOULDER_THICKNESS, SIDEWALK_THICKNESS, -}; - -fn fwd(lt: LaneType) -> LaneSpec { - LaneSpec { - lt, - dir: Direction::Fwd, - width: match lt { - LaneType::Sidewalk => SIDEWALK_THICKNESS, - LaneType::Shoulder => SHOULDER_THICKNESS, - _ => NORMAL_LANE_THICKNESS, - }, - } -} - -fn back(lt: LaneType) -> LaneSpec { - LaneSpec { - lt, - dir: Direction::Back, - width: match lt { - LaneType::Sidewalk => SIDEWALK_THICKNESS, - LaneType::Shoulder => SHOULDER_THICKNESS, - _ => NORMAL_LANE_THICKNESS, - }, - } -} +use crate::{osm, Direction, DrivingSide, LaneSpec, LaneType, MapConfig}; pub fn get_lane_specs_ltr(tags: &Tags, cfg: &MapConfig) -> Vec { + let fwd = |lt: LaneType| LaneSpec { + lt, + dir: Direction::Fwd, + width: LaneSpec::typical_lane_widths(lt, tags)[0].0, + }; + let back = |lt: LaneType| LaneSpec { + lt, + dir: Direction::Back, + width: LaneSpec::typical_lane_widths(lt, tags)[0].0, + }; + // Easy special cases first. if tags.is_any("railway", vec!["light_rail", "rail"]) { return vec![fwd(LaneType::LightRail)]; @@ -41,7 +25,7 @@ pub fn get_lane_specs_ltr(tags: &Tags, cfg: &MapConfig) -> Vec { return vec![fwd(LaneType::Sidewalk)]; } // Eventually, we should have some kind of special LaneType for shared walking/cycling paths of - // different kinds. Until then, model by making a narrow bike lane and a shoulder for walking. + // different kinds. Until then, model by making bike lanes and a shoulder for walking. if tags.is_any( osm::HIGHWAY, vec!["cycleway", "footway", "path", "pedestrian", "track"], @@ -57,15 +41,11 @@ pub fn get_lane_specs_ltr(tags: &Tags, cfg: &MapConfig) -> Vec { } // Otherwise, there'll always be a bike lane. - let half_width = |mut spec: LaneSpec| { - spec.width = spec.width / 2.0; - spec - }; - let mut fwd_side = vec![half_width(fwd(LaneType::Biking))]; + let mut fwd_side = vec![fwd(LaneType::Biking)]; let mut back_side = if tags.is("oneway", "yes") { vec![] } else { - vec![half_width(back(LaneType::Biking))] + vec![back(LaneType::Biking)] }; if !tags.is("foot", "no") { @@ -289,14 +269,6 @@ pub fn get_lane_specs_ltr(tags: &Tags, cfg: &MapConfig) -> Vec { } } - if tags.is(osm::HIGHWAY, "service") || tags.is("narrow", "yes") { - for spec in fwd_side.iter_mut().chain(back_side.iter_mut()) { - if spec.lt == LaneType::Driving || spec.lt == LaneType::Parking { - spec.width = SERVICE_ROAD_LANE_THICKNESS; - } - } - } - let mut need_fwd_shoulder = fwd_side .last() .map(|spec| spec.lt != LaneType::Sidewalk) diff --git a/map_model/src/objects/lane.rs b/map_model/src/objects/lane.rs index ee4a802349..85a8590519 100644 --- a/map_model/src/objects/lane.rs +++ b/map_model/src/objects/lane.rs @@ -8,14 +8,18 @@ use geom::{Distance, Line, PolyLine, Polygon, Pt2D, Ring}; use crate::{ osm, BusStopID, DirectedRoadID, Direction, IntersectionID, Map, MapConfig, Road, RoadID, - TurnType, NORMAL_LANE_THICKNESS, SERVICE_ROAD_LANE_THICKNESS, SHOULDER_THICKNESS, - SIDEWALK_THICKNESS, + TurnType, }; /// From some manually audited cases in Seattle, the length of parallel street parking spots is a /// bit different than the length in parking lots, so set a different value here. pub const PARKING_LOT_SPOT_LENGTH: Distance = Distance::const_meters(6.4); +pub const NORMAL_LANE_THICKNESS: Distance = Distance::const_meters(2.5); +const SERVICE_ROAD_LANE_THICKNESS: Distance = Distance::const_meters(1.5); +pub const SIDEWALK_THICKNESS: Distance = Distance::const_meters(1.5); +const SHOULDER_THICKNESS: Distance = Distance::const_meters(0.5); + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct LaneID( #[serde( @@ -405,13 +409,20 @@ impl LaneSpec { // https://en.wikipedia.org/wiki/Lane#Lane_width LaneType::Driving => { let mut choices = vec![ - (Distance::feet(8.2), "narrow"), + (Distance::feet(8.0), "narrow"), (SERVICE_ROAD_LANE_THICKNESS, "alley"), (Distance::feet(10.0), "typical"), - (Distance::feet(12.0), "highways"), + (Distance::feet(12.0), "highway"), ]; - if rank == osm::RoadRank::Highway { + if rank == osm::RoadRank::Highway + && tags + .get(osm::HIGHWAY) + .map(|x| !x.ends_with("_link")) + .unwrap_or(true) + { choices.rotate_right(1); + } else if tags.is(osm::HIGHWAY, "service") || tags.is("narrow", "yes") { + choices.swap(1, 0); } choices } @@ -427,11 +438,18 @@ impl LaneSpec { (Distance::feet(10.0), "minimum"), ], // https://nacto.org/publication/urban-street-design-guide/street-design-elements/lane-width/ - LaneType::Parking => vec![ - (Distance::feet(7.0), "narrow"), - (Distance::feet(9.0), "wide"), - (Distance::feet(15.0), "loading zone"), - ], + LaneType::Parking => { + let mut choices = vec![ + (Distance::feet(7.0), "narrow"), + (SERVICE_ROAD_LANE_THICKNESS, "alley"), + (Distance::feet(9.0), "wide"), + (Distance::feet(15.0), "loading zone"), + ]; + if tags.is(osm::HIGHWAY, "service") || tags.is("narrow", "yes") { + choices.swap(1, 0); + } + choices + } // Just a guess LaneType::SharedLeftTurn => vec![(NORMAL_LANE_THICKNESS, "default")], // These're often converted from existing lanes, so just retain that width diff --git a/traffic_signal_data/data/53189942.json b/traffic_signal_data/data/53189942.json deleted file mode 100644 index e9e3086617..0000000000 --- a/traffic_signal_data/data/53189942.json +++ /dev/null @@ -1,349 +0,0 @@ -{ - "intersection_osm_node_id": 53189942, - "plans": [ - { - "start_time_seconds": 0, - "stages": [ - { - "protected_turns": [ - { - "from": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": false - }, - "to": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": true - }, - { - "from": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": true - }, - "to": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": true - }, - { - "from": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": false - }, - "to": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": true - }, - { - "from": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": true - }, - "to": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": true - }, - { - "from": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": false - }, - "to": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": true - }, - { - "from": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": true - }, - "to": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": true - } - ], - "permitted_turns": [ - { - "from": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": true - }, - "to": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": true - }, - "to": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": true - }, - "to": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": false - }, - "to": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": false - }, - "to": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": false - }, - "to": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - } - ], - "stage_type": { - "Fixed": 30 - } - }, - { - "protected_turns": [ - { - "from": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": false - }, - "to": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": true - }, - "to": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": false - }, - "to": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": true - }, - { - "from": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": true - }, - "to": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": true - } - ], - "permitted_turns": [ - { - "from": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": false - }, - "to": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 337673338, - "osm_node1": 53189942, - "osm_node2": 3447400931, - "is_forwards": false - }, - "to": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": true - }, - "to": { - "osm_way_id": 395714916, - "osm_node1": 5466048585, - "osm_node2": 53189942, - "is_forwards": false - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - }, - { - "from": { - "osm_way_id": 395714915, - "osm_node1": 829673827, - "osm_node2": 53189942, - "is_forwards": true - }, - "to": { - "osm_way_id": 462700204, - "osm_node1": 53189942, - "osm_node2": 3447400930, - "is_forwards": true - }, - "intersection_osm_node_id": 53189942, - "is_crosswalk": false - } - ], - "stage_type": { - "Fixed": 30 - } - } - ], - "offset_seconds": 0 - } - ] -} \ No newline at end of file