change speed limits in the map_model layer

This commit is contained in:
Dustin Carlino 2020-05-06 15:18:59 -07:00
parent 3d16c7c626
commit 07c48f612d
11 changed files with 111 additions and 38 deletions

View File

@ -182,19 +182,19 @@ data/input/seattle/parcels_urbansim.txt,db63d7d606e8702d12f9399e87e6a00f,https:/
data/input/seattle/popdat.bin,793dd4075de7a4cf5ea8005cd68a06c8,https://www.dropbox.com/s/wrpji7e14rdwszs/popdat.bin.zip?dl=0
data/input/seattle/sidewalks.bin,129b460f56f5eb41cab3bfd70fb5fde9,https://www.dropbox.com/s/ma9bmisijc7v7xa/sidewalks.bin.zip?dl=0
data/input/seattle/trips_2014.csv,d4a8e733045b28c0385fb81359d6df03,https://www.dropbox.com/s/5ppravwmk6bf20d/trips_2014.csv.zip?dl=0
data/system/maps/23rd.bin,9233bb46ba3496b4ab53197f5c029934,https://www.dropbox.com/s/wjl45codk6rqfg4/23rd.bin.zip?dl=0
data/system/maps/ballard.bin,49ff23b42753cd8d3041d088ae115639,https://www.dropbox.com/s/u4rvz50she3yrk0/ballard.bin.zip?dl=0
data/system/maps/barranquilla.bin,f486f373eb04e0408847527b84ab66fd,https://www.dropbox.com/s/iuvggdfr16u6luw/barranquilla.bin.zip?dl=0
data/system/maps/caphill.bin,417bfe016e8085af60d2d2b9f17bceab,https://www.dropbox.com/s/bh20pn3wxygetw8/caphill.bin.zip?dl=0
data/system/maps/downtown.bin,cf0998f708acb6e86d63f36ab131b19a,https://www.dropbox.com/s/4do5cg4vc17lafo/downtown.bin.zip?dl=0
data/system/maps/downtown_atx.bin,f0c2d19284b3afdd9194d8cece002a4b,https://www.dropbox.com/s/5avnbkd4oxby2hs/downtown_atx.bin.zip?dl=0
data/system/maps/downtown_la.bin,ad73e60a7e078881bd12e4558619b368,https://www.dropbox.com/s/gkcl982cj6kxvrz/downtown_la.bin.zip?dl=0
data/system/maps/huge_austin.bin,cca4408c14146b47715b017449937a3c,https://www.dropbox.com/s/khy0m6v9yt0gjnt/huge_austin.bin.zip?dl=0
data/system/maps/huge_seattle.bin,e383ab41e6626e08d58e09c01de4c0b9,https://www.dropbox.com/s/btvr3qajshnivhb/huge_seattle.bin.zip?dl=0
data/system/maps/intl_district.bin,825f6480fcb54983de9eb6dc055898a9,https://www.dropbox.com/s/fohppni52ekc5l3/intl_district.bin.zip?dl=0
data/system/maps/lakeslice.bin,11d05f5ae2bea0751ca5dc2388fbde1c,https://www.dropbox.com/s/99zi0gcbyvqrkud/lakeslice.bin.zip?dl=0
data/system/maps/montlake.bin,b71aa517fc4774b7fdd7c7643f360547,https://www.dropbox.com/s/zvhm2j5lavixxcr/montlake.bin.zip?dl=0
data/system/maps/west_seattle.bin,ee10fd358d16b005e50a473fd00946ed,https://www.dropbox.com/s/5pp1ik9l40yj3wh/west_seattle.bin.zip?dl=0
data/system/maps/23rd.bin,1b01be89048b08440e9da8a121eaf6c1,https://www.dropbox.com/s/wjl45codk6rqfg4/23rd.bin.zip?dl=0
data/system/maps/ballard.bin,07e65eacf9d158520a86e5ef5345b9e9,https://www.dropbox.com/s/u4rvz50she3yrk0/ballard.bin.zip?dl=0
data/system/maps/barranquilla.bin,51fb8787696fd41f2785233b8899992c,https://www.dropbox.com/s/iuvggdfr16u6luw/barranquilla.bin.zip?dl=0
data/system/maps/caphill.bin,75d42602513554c40190e6dd308d0651,https://www.dropbox.com/s/bh20pn3wxygetw8/caphill.bin.zip?dl=0
data/system/maps/downtown.bin,09ba0aa6ec9307f1f56e75124fee0060,https://www.dropbox.com/s/4do5cg4vc17lafo/downtown.bin.zip?dl=0
data/system/maps/downtown_atx.bin,adaaeb4616d8aba97c67e8e168b69d23,https://www.dropbox.com/s/5avnbkd4oxby2hs/downtown_atx.bin.zip?dl=0
data/system/maps/downtown_la.bin,126479cf28da991b47e75a3300ea1680,https://www.dropbox.com/s/gkcl982cj6kxvrz/downtown_la.bin.zip?dl=0
data/system/maps/huge_austin.bin,8d0dedf397eccd8cfc57bf9a0bc9af65,https://www.dropbox.com/s/khy0m6v9yt0gjnt/huge_austin.bin.zip?dl=0
data/system/maps/huge_seattle.bin,63847b7fbcd3bcb428c2661262671fdd,https://www.dropbox.com/s/btvr3qajshnivhb/huge_seattle.bin.zip?dl=0
data/system/maps/intl_district.bin,5fb9c68f355d5aa571584c153d95ea5d,https://www.dropbox.com/s/fohppni52ekc5l3/intl_district.bin.zip?dl=0
data/system/maps/lakeslice.bin,ede83326617e1c13a0b73f68a8bb94d1,https://www.dropbox.com/s/99zi0gcbyvqrkud/lakeslice.bin.zip?dl=0
data/system/maps/montlake.bin,6f32bf30a3de12bbca8d7ceadd3fd86b,https://www.dropbox.com/s/zvhm2j5lavixxcr/montlake.bin.zip?dl=0
data/system/maps/west_seattle.bin,9ca3dba9a94bfe3857bdf92d2a4574de,https://www.dropbox.com/s/5pp1ik9l40yj3wh/west_seattle.bin.zip?dl=0
data/system/prebaked_results/lakeslice/weekday.bin,54c504f93db1aa7401e38ef7350adfb0,https://www.dropbox.com/s/1c1sohvy50263wg/weekday.bin.zip?dl=0
data/system/prebaked_results/montlake/car vs bike contention.bin,1031311cb5f27dcda4a92083cc0c214f,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.bin.zip?dl=0
data/system/prebaked_results/montlake/weekday.bin,30033ba544b2bd9810aa7278ee380ec2,https://www.dropbox.com/s/1aq7n9ow8tfqb5d/weekday.bin.zip?dl=0

View File

@ -147,6 +147,7 @@ impl State for EditMode {
let id = match edits.commands.pop().unwrap() {
EditCmd::ChangeLaneType { id, .. } => ID::Lane(id),
EditCmd::ReverseLane { l, .. } => ID::Lane(l),
EditCmd::ChangeSpeedLimit { id, .. } => ID::Road(id),
EditCmd::ChangeIntersection { i, .. } => ID::Intersection(i),
};
apply_map_edits(ctx, app, edits);

View File

@ -26,7 +26,7 @@ pub fn info(ctx: &EventCtx, app: &App, details: &mut Details, id: LaneID) -> Vec
),
));
} else {
kv.push(("Speed limit", r.get_speed_limit().to_string()));
kv.push(("Speed limit", r.speed_limit.to_string()));
}
kv.push(("Length", l.length().describe_rounded()));

View File

@ -143,6 +143,7 @@ pub fn edits(ctx: &mut EventCtx, app: &App) -> Layers {
vec![
format!("{} lane types changed", edits.original_lts.len()),
format!("{} lanes reversed", edits.reversed_lanes.len()),
format!("{} speed limits changed", edits.changed_speed_limits.len()),
format!(
"{} intersections changed",
edits.original_intersections.len()

View File

@ -170,7 +170,9 @@ impl GameplayMode {
pub fn allows(&self, edits: &MapEdits) -> bool {
for cmd in &edits.commands {
match cmd {
EditCmd::ChangeLaneType { .. } | EditCmd::ReverseLane { .. } => {
EditCmd::ChangeLaneType { .. }
| EditCmd::ReverseLane { .. }
| EditCmd::ChangeSpeedLimit { .. } => {
if !self.can_edit_lanes() {
return false;
}

View File

@ -2,7 +2,8 @@ use crate::raw::{OriginalIntersection, OriginalRoad};
use crate::{
ControlStopSign, ControlTrafficSignal, IntersectionID, LaneID, LaneType, Map, RoadID, TurnID,
};
use abstutil::{deserialize_btreemap, retain_btreemap, serialize_btreemap, Timer};
use abstutil::{deserialize_btreemap, retain_btreemap, retain_btreeset, serialize_btreemap, Timer};
use geom::Speed;
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
@ -15,6 +16,7 @@ pub struct MapEdits {
pub original_lts: BTreeMap<LaneID, LaneType>,
pub reversed_lanes: BTreeSet<LaneID>,
pub original_intersections: BTreeMap<IntersectionID, EditIntersection>,
pub changed_speed_limits: BTreeSet<RoadID>,
// Edits without these are player generated.
pub proposal_description: Vec<String>,
@ -39,6 +41,11 @@ pub enum EditCmd {
// New intended dst_i
dst_i: IntersectionID,
},
ChangeSpeedLimit {
id: RoadID,
new: Speed,
old: Speed,
},
ChangeIntersection {
i: IntersectionID,
new: EditIntersection,
@ -64,6 +71,7 @@ impl MapEdits {
original_lts: BTreeMap::new(),
reversed_lanes: BTreeSet::new(),
original_intersections: BTreeMap::new(),
changed_speed_limits: BTreeSet::new(),
}
}
@ -87,11 +95,11 @@ impl MapEdits {
);
}
// Original lane types, reversed lanes, and all changed intersections
pub(crate) fn update_derived(&mut self, map: &Map) {
let mut orig_lts = BTreeMap::new();
let mut reversed_lanes = BTreeSet::new();
let mut orig_intersections: BTreeMap<IntersectionID, EditIntersection> = BTreeMap::new();
let mut changed_speed_limits = BTreeSet::new();
for cmd in &self.commands {
match cmd {
@ -107,6 +115,9 @@ impl MapEdits {
reversed_lanes.insert(*l);
}
}
EditCmd::ChangeSpeedLimit { id, .. } => {
changed_speed_limits.insert(*id);
}
EditCmd::ChangeIntersection { i, ref old, .. } => {
if !orig_intersections.contains_key(i) {
orig_intersections.insert(*i, old.clone());
@ -119,10 +130,14 @@ impl MapEdits {
retain_btreemap(&mut orig_intersections, |i, orig| {
map.get_i_edit(*i) != orig.clone()
});
retain_btreeset(&mut changed_speed_limits, |r| {
map.get_r(*r).speed_limit != map.get_r(*r).speed_limit_from_osm()
});
self.original_lts = orig_lts;
self.reversed_lanes = reversed_lanes;
self.original_intersections = orig_intersections;
self.changed_speed_limits = changed_speed_limits;
}
// Assumes update_derived has been called.
@ -147,6 +162,13 @@ impl MapEdits {
new: map.get_i_edit(*i),
});
}
for r in &self.changed_speed_limits {
self.commands.push(EditCmd::ChangeSpeedLimit {
id: *r,
new: map.get_r(*r).speed_limit,
old: map.get_r(*r).speed_limit_from_osm(),
});
}
}
}
@ -214,6 +236,11 @@ enum PermanentEditCmd {
// New intended dst_i
dst_i: OriginalIntersection,
},
ChangeSpeedLimit {
id: OriginalRoad,
new: Speed,
old: Speed,
},
ChangeIntersection {
i: OriginalIntersection,
new: PermanentEditIntersection,
@ -241,6 +268,13 @@ impl PermanentMapEdits {
l: OriginalLane::to_permanent(*l, map),
dst_i: map.get_i(*dst_i).orig_id,
},
EditCmd::ChangeSpeedLimit { id, new, old } => {
PermanentEditCmd::ChangeSpeedLimit {
id: map.get_r(*id).orig_id,
new: *new,
old: *old,
}
}
EditCmd::ChangeIntersection { i, new, old } => {
PermanentEditCmd::ChangeIntersection {
i: map.get_i(*i).orig_id,
@ -273,6 +307,13 @@ impl PermanentMapEdits {
let dst_i = map.find_i_by_osm_id(dst_i.osm_node_id)?;
Ok(EditCmd::ReverseLane { l, dst_i })
}
PermanentEditCmd::ChangeSpeedLimit { id, new, old } => {
let id = map.find_r_by_osm_id(
id.osm_way_id,
(id.i1.osm_node_id, id.i2.osm_node_id),
)?;
Ok(EditCmd::ChangeSpeedLimit { id, new, old })
}
PermanentEditCmd::ChangeIntersection { i, new, old } => {
let id = map.find_i_by_osm_id(i.osm_node_id)?;
Ok(EditCmd::ChangeIntersection {
@ -291,6 +332,7 @@ impl PermanentMapEdits {
original_lts: BTreeMap::new(),
reversed_lanes: BTreeSet::new(),
original_intersections: BTreeMap::new(),
changed_speed_limits: BTreeSet::new(),
};
edits.update_derived(map);
Ok(edits)
@ -322,7 +364,8 @@ impl PermanentEditIntersection {
let mut translated_must_stop = BTreeMap::new();
for (r, stop) in must_stop {
translated_must_stop.insert(
map.find_r_by_osm_id(r.osm_way_id, (r.i1.osm_node_id, r.i2.osm_node_id))?,
map.find_r_by_osm_id(r.osm_way_id, (r.i1.osm_node_id, r.i2.osm_node_id))
.ok()?,
stop,
);
}
@ -360,13 +403,10 @@ impl OriginalLane {
}
fn from_permanent(self, map: &Map) -> Result<LaneID, String> {
let r = map.get_r(
map.find_r_by_osm_id(
self.parent.osm_way_id,
(self.parent.i1.osm_node_id, self.parent.i2.osm_node_id),
)
.ok_or_else(|| format!("can't find {:?}", self))?,
);
let r = map.get_r(map.find_r_by_osm_id(
self.parent.osm_way_id,
(self.parent.i1.osm_node_id, self.parent.i2.osm_node_id),
)?);
if r.children_forwards.len() != self.num_fwd || r.children_backwards.len() != self.num_back
{
return Err(format!("number of lanes has changed in {:?}", self));

View File

@ -8,7 +8,7 @@ use crate::{
NORMAL_LANE_THICKNESS, SIDEWALK_THICKNESS,
};
use abstutil::{deserialize_btreemap, serialize_btreemap, Error, Timer, Warn};
use geom::{Angle, Bounds, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D};
use geom::{Angle, Bounds, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D, Speed};
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
@ -643,16 +643,23 @@ impl Map {
None
}
pub fn find_r_by_osm_id(&self, osm_way_id: i64, osm_node_ids: (i64, i64)) -> Option<RoadID> {
pub fn find_r_by_osm_id(
&self,
osm_way_id: i64,
osm_node_ids: (i64, i64),
) -> Result<RoadID, String> {
for r in self.all_roads() {
if r.orig_id.osm_way_id == osm_way_id
&& r.orig_id.i1.osm_node_id == osm_node_ids.0
&& r.orig_id.i2.osm_node_id == osm_node_ids.1
{
return Some(r.id);
return Ok(r.id);
}
}
None
Err(format!(
"Can't find osm_way_id {} between nodes {} and {}",
osm_way_id, osm_node_ids.0, osm_node_ids.1
))
}
pub fn find_i_by_osm_id(&self, osm_node_id: i64) -> Result<IntersectionID, String> {
@ -933,7 +940,9 @@ fn make_half_map(
center_pts: r.trimmed_center_pts.clone(),
src_i: i1,
dst_i: i2,
speed_limit: Speed::ZERO,
};
road.speed_limit = road.speed_limit_from_osm();
for lane in &r.lane_specs {
let id = LaneID(map.lanes.len());
@ -1150,6 +1159,15 @@ impl EditCmd {
recalculate_turns(dst_i, map, effects, timer);
true
}
EditCmd::ChangeSpeedLimit { id, new, .. } => {
if map.roads[id.0].speed_limit != *new {
map.roads[id.0].speed_limit = *new;
effects.changed_roads.insert(*id);
true
} else {
false
}
}
EditCmd::ChangeIntersection {
i,
ref new,
@ -1206,6 +1224,15 @@ impl EditCmd {
}
.apply(effects, map, timer)
}
EditCmd::ChangeSpeedLimit { id, old, .. } => {
if map.roads[id.0].speed_limit != *old {
map.roads[id.0].speed_limit = *old;
effects.changed_roads.insert(*id);
true
} else {
false
}
}
EditCmd::ChangeIntersection {
i,
ref old,

View File

@ -128,8 +128,8 @@ pub fn cost(lane: &Lane, turn: &Turn, constraints: PathConstraints, map: &Map) -
match constraints {
PathConstraints::Car => {
// Prefer slightly longer route on faster roads
let t1 = lane.length() / map.get_r(lane.parent).get_speed_limit();
let t2 = turn.geom.length() / map.get_parent(turn.id.dst).get_speed_limit();
let t1 = lane.length() / map.get_r(lane.parent).speed_limit;
let t2 = turn.geom.length() / map.get_parent(turn.id.dst).speed_limit;
(t1 + t2).inner_seconds().round() as usize
}
PathConstraints::Bike => {
@ -155,8 +155,8 @@ pub fn cost(lane: &Lane, turn: &Turn, constraints: PathConstraints, map: &Map) -
}
PathConstraints::Bus => {
// Like Car, but prefer bus lanes.
let t1 = lane.length() / map.get_r(lane.parent).get_speed_limit();
let t2 = turn.geom.length() / map.get_parent(turn.id.dst).get_speed_limit();
let t1 = lane.length() / map.get_r(lane.parent).speed_limit;
let t2 = turn.geom.length() / map.get_parent(turn.id.dst).speed_limit;
let lt_penalty = if lane.is_bus() {
1.0
} else {

View File

@ -97,6 +97,7 @@ pub struct Road {
// self is 'from'. (via, to). Only BanTurns.
pub complicated_turn_restrictions: Vec<(RoadID, RoadID)>,
pub orig_id: OriginalRoad,
pub speed_limit: Speed,
// Invariant: A road must contain at least one child
// These are ordered from closest to center lane (left-most when driving on the right) to
@ -205,8 +206,7 @@ impl Road {
}
}
pub fn get_speed_limit(&self) -> Speed {
// TODO Should probably cache this
pub(crate) fn speed_limit_from_osm(&self) -> Speed {
if let Some(limit) = self.osm_tags.get(osm::MAXSPEED) {
// TODO handle other units
if limit.ends_with(" mph") {

View File

@ -734,7 +734,9 @@ fn import_turn_group(id: seattle_traffic_signals::Turn, map: &Map) -> Option<Tur
fn find_r(id: seattle_traffic_signals::DirectedRoad, map: &Map) -> Option<DirectedRoadID> {
Some(DirectedRoadID {
id: map.find_r_by_osm_id(id.osm_way_id, (id.osm_node1, id.osm_node2))?,
id: map
.find_r_by_osm_id(id.osm_way_id, (id.osm_node1, id.osm_node2))
.ok()?,
forwards: id.is_forwards,
})
}

View File

@ -167,8 +167,8 @@ impl Traversable {
pub fn speed_limit(&self, map: &Map) -> Speed {
match *self {
Traversable::Lane(id) => map.get_parent(id).get_speed_limit(),
Traversable::Turn(id) => map.get_parent(id.dst).get_speed_limit(),
Traversable::Lane(id) => map.get_parent(id).speed_limit,
Traversable::Turn(id) => map.get_parent(id.dst).speed_limit,
}
}