mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 16:02:23 +03:00
make peds use front paths for parking lots too
This commit is contained in:
parent
a643f039ad
commit
65b500509e
@ -374,9 +374,9 @@ data/system/maps/montlake.bin,d58d14b9fbae8cfdf6c547fe140ff3fe,https://www.dropb
|
||||
data/system/maps/mt_baker.bin,09dd0d4220e1ebbed4fc730ed2081933,https://www.dropbox.com/s/cetje663p04cbgp/mt_baker.bin.zip?dl=0
|
||||
data/system/maps/udistrict.bin,4de690facca9297f148396f3f09c3a6a,https://www.dropbox.com/s/zqt2je8fadssz5j/udistrict.bin.zip?dl=0
|
||||
data/system/maps/west_seattle.bin,867b16afdf12c484d680bfbc73cbd919,https://www.dropbox.com/s/5pp1ik9l40yj3wh/west_seattle.bin.zip?dl=0
|
||||
data/system/prebaked_results/lakeslice/weekday.bin,cbd73a7a14a8406a99cafac4e2eedf5b,https://www.dropbox.com/s/1c1sohvy50263wg/weekday.bin.zip?dl=0
|
||||
data/system/prebaked_results/lakeslice/weekday.bin,5402db739bd44a5f763f64fa14887733,https://www.dropbox.com/s/1c1sohvy50263wg/weekday.bin.zip?dl=0
|
||||
data/system/prebaked_results/montlake/car vs bike contention.bin,ac46a6b81a65431209075a7de5ed9227,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.bin.zip?dl=0
|
||||
data/system/prebaked_results/montlake/weekday.bin,cd953900d32389809fb2dda206789528,https://www.dropbox.com/s/1aq7n9ow8tfqb5d/weekday.bin.zip?dl=0
|
||||
data/system/prebaked_results/montlake/weekday.bin,0a06da39f1f76199744d27b137bc1bc0,https://www.dropbox.com/s/1aq7n9ow8tfqb5d/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/ballard/weekday.bin,60d3eb1cdb8672e2d29cf3acf23ccabe,https://www.dropbox.com/s/67hys1v7m7oe979/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/downtown/weekday.bin,8821147124da650f975483ed1e5bbb69,https://www.dropbox.com/s/pstvu4p7xj3gaoi/weekday.bin.zip?dl=0
|
||||
data/system/scenarios/huge_seattle/weekday.bin,31bfc23f39bb54bef939119f6cfbd2e2,https://www.dropbox.com/s/u3pmsshwnf13g83/weekday.bin.zip?dl=0
|
||||
|
@ -212,12 +212,17 @@ impl DrawPedCrowd {
|
||||
map.right_shift(pl_slice, SIDEWALK_THICKNESS / 4.0).unwrap()
|
||||
}
|
||||
}
|
||||
PedCrowdLocation::FrontPath(b) => map
|
||||
PedCrowdLocation::BldgFrontPath(b) => map
|
||||
.get_b(b)
|
||||
.front_path
|
||||
.line
|
||||
.to_polyline()
|
||||
.exact_slice(input.low, input.high),
|
||||
PedCrowdLocation::LotFrontPath(pl) => map
|
||||
.get_pl(pl)
|
||||
.sidewalk_line
|
||||
.to_polyline()
|
||||
.exact_slice(input.low, input.high),
|
||||
};
|
||||
let blob = pl_shifted.make_polygons(SIDEWALK_THICKNESS / 2.0);
|
||||
let mut batch = GeomBatch::new();
|
||||
@ -235,7 +240,8 @@ impl DrawPedCrowd {
|
||||
blob,
|
||||
zorder: match input.location {
|
||||
PedCrowdLocation::Sidewalk(on, _) => on.get_zorder(map),
|
||||
PedCrowdLocation::FrontPath(_) => 0,
|
||||
PedCrowdLocation::BldgFrontPath(_) => 0,
|
||||
PedCrowdLocation::LotFrontPath(_) => 0,
|
||||
},
|
||||
draw_default: prerender.upload(batch),
|
||||
}
|
||||
|
@ -6,6 +6,12 @@ use std::fmt;
|
||||
// TODO For now, ignore the mapped roads linking things and just use the same driveway approach
|
||||
// that buildings use.
|
||||
|
||||
// TODO Nits:
|
||||
// - handle relations with individual slots, like https://www.openstreetmap.org/relation/2580595?
|
||||
// - Northlake: onstreet or a lot?
|
||||
// - E1 at UW filtered out
|
||||
// - aisle clipping isnt perfect (23rd and rainier, pepsi)
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct ParkingLotID(pub usize);
|
||||
|
||||
|
@ -6,7 +6,9 @@ use crate::{
|
||||
};
|
||||
use abstutil::{deserialize_multimap, serialize_multimap, MultiMap};
|
||||
use geom::{Distance, Duration, Line, PolyLine, Speed, Time};
|
||||
use map_model::{BuildingID, BusRouteID, Map, Path, PathStep, Traversable, SIDEWALK_THICKNESS};
|
||||
use map_model::{
|
||||
BuildingID, BusRouteID, Map, ParkingLotID, Path, PathStep, Traversable, SIDEWALK_THICKNESS,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
@ -73,6 +75,10 @@ impl WalkingSimState {
|
||||
TimeInterval::new(now, now + map.get_b(b).front_path.line.length() / ped.speed),
|
||||
)
|
||||
}
|
||||
SidewalkPOI::ParkingSpot(ParkingSpot::Lot(pl, _)) => PedState::LeavingParkingLot(
|
||||
pl,
|
||||
TimeInterval::new(now, now + map.get_pl(pl).sidewalk_line.length() / ped.speed),
|
||||
),
|
||||
SidewalkPOI::BikeRack(driving_pos) => PedState::FinishingBiking(
|
||||
params.start.clone(),
|
||||
Line::new(driving_pos.pt(map), params.start.sidewalk_pos.pt(map)),
|
||||
@ -122,18 +128,30 @@ impl WalkingSimState {
|
||||
if ped.path.is_last_step() {
|
||||
match ped.goal.connection {
|
||||
SidewalkPOI::ParkingSpot(spot) => {
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
trips.ped_reached_parking_spot(
|
||||
now,
|
||||
ped.id,
|
||||
spot,
|
||||
ped.total_blocked_time,
|
||||
map,
|
||||
parking,
|
||||
scheduler,
|
||||
);
|
||||
self.peds.remove(&id);
|
||||
if let ParkingSpot::Lot(pl, _) = spot {
|
||||
ped.state = PedState::EnteringParkingLot(
|
||||
pl,
|
||||
TimeInterval::new(
|
||||
now,
|
||||
now + map.get_pl(pl).sidewalk_line.length() / ped.speed,
|
||||
),
|
||||
);
|
||||
scheduler
|
||||
.push(ped.state.get_end_time(), Command::UpdatePed(ped.id));
|
||||
} else {
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
trips.ped_reached_parking_spot(
|
||||
now,
|
||||
ped.id,
|
||||
spot,
|
||||
ped.total_blocked_time,
|
||||
map,
|
||||
parking,
|
||||
scheduler,
|
||||
);
|
||||
self.peds.remove(&id);
|
||||
}
|
||||
}
|
||||
SidewalkPOI::Building(b) => {
|
||||
ped.state = PedState::EnteringBuilding(
|
||||
@ -247,6 +265,27 @@ impl WalkingSimState {
|
||||
);
|
||||
self.peds.remove(&id);
|
||||
}
|
||||
PedState::LeavingParkingLot(pl, _) => {
|
||||
ped.state = ped.crossing_state(map.get_pl(pl).sidewalk_pos.dist_along(), now, map);
|
||||
scheduler.push(ped.state.get_end_time(), Command::UpdatePed(ped.id));
|
||||
}
|
||||
PedState::EnteringParkingLot(_, _) => {
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
trips.ped_reached_parking_spot(
|
||||
now,
|
||||
ped.id,
|
||||
match ped.goal.connection {
|
||||
SidewalkPOI::ParkingSpot(spot) => spot,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
ped.total_blocked_time,
|
||||
map,
|
||||
parking,
|
||||
scheduler,
|
||||
);
|
||||
self.peds.remove(&id);
|
||||
}
|
||||
PedState::StartingToBike(ref spot, _, _) => {
|
||||
self.peds_per_traversable
|
||||
.remove(ped.path.current_step().as_traversable(), ped.id);
|
||||
@ -364,10 +403,11 @@ impl WalkingSimState {
|
||||
on: Traversable,
|
||||
map: &Map,
|
||||
) -> (Vec<DrawPedestrianInput>, Vec<DrawPedCrowdInput>) {
|
||||
// Classify into direction-based groups or by building front path.
|
||||
// Classify into direction-based groups or by building/parking lot front path.
|
||||
let mut forwards: Vec<(PedestrianID, Distance)> = Vec::new();
|
||||
let mut backwards: Vec<(PedestrianID, Distance)> = Vec::new();
|
||||
let mut front_path: MultiMap<BuildingID, (PedestrianID, Distance)> = MultiMap::new();
|
||||
let mut bldg_front_path: MultiMap<BuildingID, (PedestrianID, Distance)> = MultiMap::new();
|
||||
let mut lot_front_path: MultiMap<ParkingLotID, (PedestrianID, Distance)> = MultiMap::new();
|
||||
|
||||
for id in self.peds_per_traversable.get(on) {
|
||||
let ped = &self.peds[id];
|
||||
@ -390,11 +430,19 @@ impl WalkingSimState {
|
||||
}
|
||||
PedState::LeavingBuilding(b, ref int) => {
|
||||
let len = map.get_b(b).front_path.line.length();
|
||||
front_path.insert(b, (*id, int.percent(now) * len));
|
||||
bldg_front_path.insert(b, (*id, int.percent(now) * len));
|
||||
}
|
||||
PedState::EnteringBuilding(b, ref int) => {
|
||||
let len = map.get_b(b).front_path.line.length();
|
||||
front_path.insert(b, (*id, (1.0 - int.percent(now)) * len));
|
||||
bldg_front_path.insert(b, (*id, (1.0 - int.percent(now)) * len));
|
||||
}
|
||||
PedState::LeavingParkingLot(pl, ref int) => {
|
||||
let len = map.get_pl(pl).sidewalk_line.length();
|
||||
lot_front_path.insert(pl, (*id, int.percent(now) * len));
|
||||
}
|
||||
PedState::EnteringParkingLot(pl, ref int) => {
|
||||
let len = map.get_pl(pl).sidewalk_line.length();
|
||||
lot_front_path.insert(pl, (*id, (1.0 - int.percent(now)) * len));
|
||||
}
|
||||
PedState::StartingToBike(_, _, _)
|
||||
| PedState::FinishingBiking(_, _, _)
|
||||
@ -422,12 +470,19 @@ impl WalkingSimState {
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.chain(front_path.consume().into_iter().map(|(b, set)| {
|
||||
.chain(bldg_front_path.consume().into_iter().map(|(b, set)| {
|
||||
(
|
||||
set.into_iter().collect::<Vec<_>>(),
|
||||
PedCrowdLocation::FrontPath(b),
|
||||
PedCrowdLocation::BldgFrontPath(b),
|
||||
map.get_b(b).front_path.line.length(),
|
||||
)
|
||||
}))
|
||||
.chain(lot_front_path.consume().into_iter().map(|(pl, set)| {
|
||||
(
|
||||
set.into_iter().collect::<Vec<_>>(),
|
||||
PedCrowdLocation::LotFrontPath(pl),
|
||||
map.get_pl(pl).sidewalk_line.length(),
|
||||
)
|
||||
})) {
|
||||
if group.is_empty() {
|
||||
continue;
|
||||
@ -493,8 +548,12 @@ impl Pedestrian {
|
||||
match self.state {
|
||||
PedState::Crossing(ref dist_int, ref time_int) => dist_int.lerp(time_int.percent(now)),
|
||||
PedState::WaitingToTurn(dist, _) => dist,
|
||||
PedState::LeavingBuilding(b, _) => map.get_b(b).front_path.sidewalk.dist_along(),
|
||||
PedState::EnteringBuilding(b, _) => map.get_b(b).front_path.sidewalk.dist_along(),
|
||||
PedState::LeavingBuilding(b, _) | PedState::EnteringBuilding(b, _) => {
|
||||
map.get_b(b).front_path.sidewalk.dist_along()
|
||||
}
|
||||
PedState::LeavingParkingLot(pl, _) | PedState::EnteringParkingLot(pl, _) => {
|
||||
map.get_pl(pl).sidewalk_pos.dist_along()
|
||||
}
|
||||
PedState::StartingToBike(ref spot, _, _) => spot.sidewalk_pos.dist_along(),
|
||||
PedState::FinishingBiking(ref spot, _, _) => spot.sidewalk_pos.dist_along(),
|
||||
PedState::WaitingForBus(_, _) => self.goal.sidewalk_pos.dist_along(),
|
||||
@ -540,22 +599,33 @@ impl Pedestrian {
|
||||
)
|
||||
}
|
||||
PedState::LeavingBuilding(b, ref time_int) => {
|
||||
let front_path = &map.get_b(b).front_path;
|
||||
let line = &map.get_b(b).front_path.line;
|
||||
(
|
||||
front_path
|
||||
.line
|
||||
.dist_along(time_int.percent(now) * front_path.line.length()),
|
||||
front_path.line.angle(),
|
||||
line.dist_along(time_int.percent(now) * line.length()),
|
||||
line.angle(),
|
||||
)
|
||||
}
|
||||
PedState::EnteringBuilding(b, ref time_int) => {
|
||||
let front_path = &map.get_b(b).front_path;
|
||||
let line = &map.get_b(b).front_path.line;
|
||||
(
|
||||
front_path
|
||||
.line
|
||||
.reverse()
|
||||
.dist_along(time_int.percent(now) * front_path.line.length()),
|
||||
front_path.line.angle().opposite(),
|
||||
line.reverse()
|
||||
.dist_along(time_int.percent(now) * line.length()),
|
||||
line.angle().opposite(),
|
||||
)
|
||||
}
|
||||
PedState::LeavingParkingLot(pl, ref time_int) => {
|
||||
let line = &map.get_pl(pl).sidewalk_line;
|
||||
(
|
||||
line.dist_along(time_int.percent(now) * line.length()),
|
||||
line.angle(),
|
||||
)
|
||||
}
|
||||
PedState::EnteringParkingLot(pl, ref time_int) => {
|
||||
let line = &map.get_pl(pl).sidewalk_line;
|
||||
(
|
||||
line.reverse()
|
||||
.dist_along(time_int.percent(now) * line.length()),
|
||||
line.angle().opposite(),
|
||||
)
|
||||
}
|
||||
PedState::StartingToBike(_, ref line, ref time_int) => {
|
||||
@ -639,6 +709,8 @@ enum PedState {
|
||||
WaitingToTurn(Distance, Time),
|
||||
LeavingBuilding(BuildingID, TimeInterval),
|
||||
EnteringBuilding(BuildingID, TimeInterval),
|
||||
LeavingParkingLot(ParkingLotID, TimeInterval),
|
||||
EnteringParkingLot(ParkingLotID, TimeInterval),
|
||||
StartingToBike(SidewalkSpot, Line, TimeInterval),
|
||||
FinishingBiking(SidewalkSpot, Line, TimeInterval),
|
||||
WaitingForBus(BusRouteID, Time),
|
||||
@ -651,6 +723,8 @@ impl PedState {
|
||||
PedState::WaitingToTurn(_, _) => unreachable!(),
|
||||
PedState::LeavingBuilding(_, ref time_int) => time_int.end,
|
||||
PedState::EnteringBuilding(_, ref time_int) => time_int.end,
|
||||
PedState::LeavingParkingLot(_, ref time_int) => time_int.end,
|
||||
PedState::EnteringParkingLot(_, ref time_int) => time_int.end,
|
||||
PedState::StartingToBike(_, _, ref time_int) => time_int.end,
|
||||
PedState::FinishingBiking(_, _, ref time_int) => time_int.end,
|
||||
PedState::WaitingForBus(_, _) => unreachable!(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{CarID, PedestrianID, PersonID, VehicleType};
|
||||
use geom::{Angle, Distance, PolyLine, Pt2D, Time};
|
||||
use map_model::{BuildingID, Map, Traversable, TurnID};
|
||||
use map_model::{BuildingID, Map, ParkingLotID, Traversable, TurnID};
|
||||
|
||||
// Intermediate structures so that sim and game crates don't have a cyclic dependency.
|
||||
#[derive(Clone)]
|
||||
@ -25,7 +25,8 @@ pub struct DrawPedCrowdInput {
|
||||
pub enum PedCrowdLocation {
|
||||
// bool is contraflow
|
||||
Sidewalk(Traversable, bool),
|
||||
FrontPath(BuildingID),
|
||||
BldgFrontPath(BuildingID),
|
||||
LotFrontPath(ParkingLotID),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
Loading…
Reference in New Issue
Block a user