mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 23:15:24 +03:00
Refine high_stress_for_bikes to take direction into account. Northbound bike lanes on Roosevelt don't really matter when going southbound.
Regenerate all maps, since this maybe affects edge weights. And try some ideas for understanding why files change.
This commit is contained in:
parent
7d57deb8ae
commit
a85915f647
@ -220,18 +220,23 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
fn dump_json(path: String) {
|
||||
if path.contains("/maps/") {
|
||||
let map = map_model::Map::load_synchronously(path, &mut Timer::throwaway());
|
||||
// Just try to deserialize as different formats
|
||||
if let Ok(map) =
|
||||
abstio::maybe_read_binary::<map_model::Map>(path.clone(), &mut Timer::throwaway())
|
||||
{
|
||||
println!("{}", abstutil::to_json(&map));
|
||||
} else if path.contains("/scenarios/") {
|
||||
let scenario: sim::Scenario = abstio::read_binary(path, &mut Timer::throwaway());
|
||||
println!("{}", abstutil::to_json(&scenario));
|
||||
} else {
|
||||
panic!(
|
||||
"Don't know how to dump JSON for {}. Only maps and scenarios are supported.",
|
||||
path
|
||||
);
|
||||
return;
|
||||
}
|
||||
if let Ok(scenario) =
|
||||
abstio::maybe_read_binary::<sim::Scenario>(path.clone(), &mut Timer::throwaway())
|
||||
{
|
||||
println!("{}", abstutil::to_json(&scenario));
|
||||
return;
|
||||
}
|
||||
panic!(
|
||||
"Don't know how to dump JSON for {}. Only maps and scenarios are supported.",
|
||||
path
|
||||
);
|
||||
}
|
||||
|
||||
fn random_scenario(rng_seed: u64, map: String, scenario_name: String) {
|
||||
|
20
data/diff_changed_files.sh
Executable file
20
data/diff_changed_files.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
# TODO describe
|
||||
|
||||
set -e
|
||||
|
||||
FILE=$1
|
||||
if [ "$FILE" == "" ]; then
|
||||
echo Missing args;
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
cp ~/s3_abst_data/dev/${FILE}.gz old.bin.gz
|
||||
gunzip old.bin.gz
|
||||
./target/release/cli dump-json old.bin > old.json
|
||||
rm -f old.bin
|
||||
|
||||
./target/release/cli dump-json $FILE > new.json
|
||||
|
||||
echo "diff old.json new.json"
|
||||
echo "mold old.json new.json # slower"
|
@ -4,7 +4,7 @@ use abstutil::{prettyprint_usize, Counter};
|
||||
use geom::{Distance, Time};
|
||||
use map_gui::tools::{ColorDiscrete, ColorLegend, ColorNetwork};
|
||||
use map_gui::ID;
|
||||
use map_model::{AmenityType, LaneType};
|
||||
use map_model::{AmenityType, Direction, LaneType};
|
||||
use sim::AgentType;
|
||||
use widgetry::mapspace::ToggleZoomed;
|
||||
use widgetry::{Color, EventCtx, GfxCtx, Line, Panel, Text, Widget};
|
||||
@ -326,7 +326,9 @@ impl Static {
|
||||
let mut colorer = ColorDiscrete::new(app, vec![("high stress", app.cs.edits_layer)]);
|
||||
|
||||
for r in app.primary.map.all_roads() {
|
||||
if r.high_stress_for_bikes(&app.primary.map) {
|
||||
if r.high_stress_for_bikes(&app.primary.map, Direction::Fwd)
|
||||
|| r.high_stress_for_bikes(&app.primary.map, Direction::Back)
|
||||
{
|
||||
colorer.add_r(r.id, "high stress");
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use std::collections::HashSet;
|
||||
use abstutil::Counter;
|
||||
use geom::{Distance, Duration};
|
||||
use map_gui::tools::ColorNetwork;
|
||||
use map_model::{PathStepV2, RoadID};
|
||||
use map_model::PathStepV2;
|
||||
use sim::{TripEndpoint, TripID, TripMode};
|
||||
use widgetry::table::{Col, Filter, Table};
|
||||
use widgetry::{
|
||||
@ -293,17 +293,14 @@ fn show_route_gaps(ctx: &mut EventCtx, app: &App, table: &Table<App, Entry, Filt
|
||||
let sim = &app.primary.sim;
|
||||
|
||||
// Find all high-stress roads, since we'll filter by them next
|
||||
let high_stress: HashSet<RoadID> = map
|
||||
.all_roads()
|
||||
.iter()
|
||||
.filter_map(|r| {
|
||||
if r.high_stress_for_bikes(map) {
|
||||
Some(r.id)
|
||||
} else {
|
||||
None
|
||||
let mut high_stress = HashSet::new();
|
||||
for r in map.all_roads() {
|
||||
for dr in r.id.both_directions() {
|
||||
if r.high_stress_for_bikes(map, dr.dir) {
|
||||
high_stress.insert(dr);
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
let mut road_counter = Counter::new();
|
||||
for path in timer
|
||||
@ -318,7 +315,7 @@ fn show_route_gaps(ctx: &mut EventCtx, app: &App, table: &Table<App, Entry, Filt
|
||||
for step in path.get_steps() {
|
||||
// No Contraflow steps for bike paths
|
||||
if let PathStepV2::Along(dr) = step {
|
||||
if high_stress.contains(&dr.id) {
|
||||
if high_stress.contains(&dr) {
|
||||
road_counter.inc(dr.id);
|
||||
}
|
||||
}
|
||||
|
@ -413,17 +413,14 @@ impl ModeShiftData {
|
||||
.unwrap_or(&app.primary.map);
|
||||
|
||||
// Find all high-stress roads, since we'll filter by them next
|
||||
let high_stress: HashSet<RoadID> = unedited_map
|
||||
.all_roads()
|
||||
.iter()
|
||||
.filter_map(|r| {
|
||||
if r.high_stress_for_bikes(unedited_map) {
|
||||
Some(r.id)
|
||||
} else {
|
||||
None
|
||||
let mut high_stress = HashSet::new();
|
||||
for r in unedited_map.all_roads() {
|
||||
for dr in r.id.both_directions() {
|
||||
if r.high_stress_for_bikes(unedited_map, dr.dir) {
|
||||
high_stress.insert(dr);
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
self.filtered_trips.clear();
|
||||
let mut filtered_requests = Vec::new();
|
||||
@ -448,7 +445,7 @@ impl ModeShiftData {
|
||||
for step in path.get_steps() {
|
||||
// No Contraflow steps for bike paths
|
||||
if let PathStepV2::Along(dr) = step {
|
||||
if high_stress.contains(&dr.id) {
|
||||
if high_stress.contains(&dr) {
|
||||
count_per_road.inc(dr.id);
|
||||
|
||||
// TODO Assumes the edits have made the road stop being high stress!
|
||||
|
@ -128,7 +128,8 @@ impl RouteDetails {
|
||||
let this_pl = step.as_traversable().get_polyline(map);
|
||||
match step {
|
||||
PathStep::Lane(l) | PathStep::ContraflowLane(l) => {
|
||||
if map.get_parent(*l).high_stress_for_bikes(map) {
|
||||
let road = map.get_parent(*l);
|
||||
if road.high_stress_for_bikes(map, road.lanes[l.offset].dir) {
|
||||
dist_along_high_stress_roads += this_pl.length();
|
||||
|
||||
// TODO It'd be nicer to build up contiguous subsets of the path
|
||||
|
@ -578,19 +578,18 @@ impl Road {
|
||||
panic!("{} doesn't contain both {} and {}", self.id, l1, l2);
|
||||
}
|
||||
|
||||
/// A simple classification of if the road is stressful or not for cycling. Arterial roads
|
||||
/// without a bike lane match this. Why arterial, instead of looking at speed limits? Even on
|
||||
/// arterial roads with official speed limits lowered, in practice vehicles still travel at the
|
||||
/// speed suggested by the design of the road.
|
||||
// TODO No treatment of direction
|
||||
/// A simple classification of if the directed road is stressful or not for cycling. Arterial
|
||||
/// roads without a bike lane match this. Why arterial, instead of looking at speed limits?
|
||||
/// Even on arterial roads with official speed limits lowered, in practice vehicles still
|
||||
/// travel at the speed suggested by the design of the road.
|
||||
// TODO Should elevation matter or not? Flat high-speed roads are still terrifying, but there's
|
||||
// something about slogging up (or flying down!) a pothole-filled road inches from cars.
|
||||
pub fn high_stress_for_bikes(&self, map: &Map) -> bool {
|
||||
pub fn high_stress_for_bikes(&self, map: &Map, dir: Direction) -> bool {
|
||||
let mut bike_lanes = false;
|
||||
let mut can_use = false;
|
||||
// Can a bike even use it, or is it a highway?
|
||||
for l in &self.lanes {
|
||||
if l.lane_type == LaneType::Biking {
|
||||
if l.lane_type == LaneType::Biking && l.dir == dir {
|
||||
bike_lanes = true;
|
||||
}
|
||||
if PathConstraints::Bike.can_use(l, map) {
|
||||
|
@ -337,8 +337,7 @@ pub fn vehicle_cost(
|
||||
|
||||
if constraints == PathConstraints::Bike && (params.avoid_high_stress - 1.0).abs() > f64::EPSILON
|
||||
{
|
||||
let road = map.get_r(dr.id);
|
||||
if road.high_stress_for_bikes(map) {
|
||||
if map.get_r(dr.id).high_stress_for_bikes(map, dr.dir) {
|
||||
multiplier *= params.avoid_high_stress;
|
||||
}
|
||||
}
|
||||
|
@ -2,30 +2,16 @@
|
||||
{
|
||||
"map": "arboretum (in seattle (us))",
|
||||
"scenario": "weekday",
|
||||
"finished_trips": 76618,
|
||||
"finished_trips": 76640,
|
||||
"cancelled_trips": 0,
|
||||
"total_trip_duration_seconds": 51747112.72399941
|
||||
"total_trip_duration_seconds": 48024585.70720022
|
||||
},
|
||||
{
|
||||
"map": "montlake (in seattle (us))",
|
||||
"scenario": "weekday",
|
||||
"finished_trips": 36706,
|
||||
"cancelled_trips": 90,
|
||||
"total_trip_duration_seconds": 22717800.186400127
|
||||
},
|
||||
{
|
||||
"map": "lakeslice (in seattle (us))",
|
||||
"scenario": "weekday",
|
||||
"finished_trips": 260914,
|
||||
"cancelled_trips": 4902,
|
||||
"total_trip_duration_seconds": 201405693.34539455
|
||||
},
|
||||
{
|
||||
"map": "wallingford (in seattle (us))",
|
||||
"scenario": "weekday",
|
||||
"finished_trips": 133431,
|
||||
"cancelled_trips": 0,
|
||||
"total_trip_duration_seconds": 69231506.80130064
|
||||
"finished_trips": 36691,
|
||||
"cancelled_trips": 105,
|
||||
"total_trip_duration_seconds": 20310765.155799977
|
||||
},
|
||||
{
|
||||
"map": "center (in poundbury (gb))",
|
||||
|
@ -137,7 +137,19 @@ fn just_compare() {
|
||||
// Anything missing or needing updating?
|
||||
for (path, entry) in truth.entries {
|
||||
if local.entries.get(&path).map(|x| &x.checksum) != Some(&entry.checksum) {
|
||||
println!("- Update {}", path);
|
||||
if let Some(old_bytes) = local.entries.get(&path).map(|x| x.uncompressed_size_bytes) {
|
||||
if old_bytes == entry.uncompressed_size_bytes {
|
||||
println!("- Update {}. Same size, md5sum changed", path);
|
||||
} else {
|
||||
println!(
|
||||
"- Update {}. {} bytes difference",
|
||||
path,
|
||||
(old_bytes as isize) - (entry.uncompressed_size_bytes as isize)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
println!("- Add {}", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user