mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-29 04:35:51 +03:00
handle bus stops right at intersections
This commit is contained in:
parent
52e89315d7
commit
ecd5d86009
@ -177,13 +177,13 @@ pub fn clip_map(map: &mut RawMap, timer: &mut Timer) {
|
||||
}
|
||||
|
||||
let mut borders: Vec<OriginalIntersection> = Vec::new();
|
||||
for pt in &r.all_pts {
|
||||
if let Some(i) = map.intersections.get(pt) {
|
||||
for (node, _) in &r.all_pts {
|
||||
if let Some(i) = map.intersections.get(node) {
|
||||
if i.intersection_type == IntersectionType::Border {
|
||||
borders.push(*pt);
|
||||
borders.push(*node);
|
||||
}
|
||||
}
|
||||
if let Some(i) = extra_borders.get(pt) {
|
||||
if let Some(i) = extra_borders.get(node) {
|
||||
borders.push(*i);
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +88,15 @@ pub fn extract_route(
|
||||
}
|
||||
}
|
||||
|
||||
let all_pts: Vec<OriginalIntersection> = match glue_route(all_ways, doc) {
|
||||
let all_pts: Vec<(OriginalIntersection, Pt2D)> = match glue_route(all_ways, doc) {
|
||||
Ok(nodes) => nodes
|
||||
.into_iter()
|
||||
.map(|osm_node_id| OriginalIntersection { osm_node_id })
|
||||
.map(|osm_node_id| {
|
||||
(
|
||||
OriginalIntersection { osm_node_id },
|
||||
doc.nodes[&osm_node_id].pt,
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
Err(err) => {
|
||||
timer.error(format!(
|
||||
@ -202,39 +207,55 @@ pub fn snap_bus_stops(
|
||||
) -> Result<RawBusRoute, String> {
|
||||
// For every stop, figure out what road segment and direction it matches up to.
|
||||
for stop in &mut route.stops {
|
||||
// TODO Handle this, example https://www.openstreetmap.org/node/4560936658
|
||||
if raw.intersections.contains_key(&stop.vehicle_pos.0) {
|
||||
return Err(format!(
|
||||
"stop {} right at an intersection",
|
||||
stop.vehicle_pos.0.osm_node_id
|
||||
));
|
||||
}
|
||||
|
||||
let idx_in_route = route
|
||||
.all_pts
|
||||
.iter()
|
||||
.position(|pt| stop.vehicle_pos.0 == *pt)
|
||||
.position(|(node, _)| stop.vehicle_pos.0 == *node)
|
||||
.unwrap();
|
||||
|
||||
let road = if raw.intersections.contains_key(&stop.vehicle_pos.0) {
|
||||
// Prefer to match just before an intersection, instead of just after
|
||||
let mut found = None;
|
||||
for idx in (0..idx_in_route).rev() {
|
||||
let (i, pt) = route.all_pts[idx];
|
||||
if !raw.intersections.contains_key(&i) {
|
||||
found = Some(pt_to_road[&pt.to_hashable()]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(r) = found {
|
||||
r
|
||||
} else {
|
||||
return Err(format!(
|
||||
"stop {} right at an intersection near the beginning of the route",
|
||||
stop.vehicle_pos.0.osm_node_id
|
||||
));
|
||||
}
|
||||
} else {
|
||||
pt_to_road[&stop.vehicle_pos.1.to_hashable()]
|
||||
};
|
||||
|
||||
// Scan backwards and forwards in the route for the nearest intersections.
|
||||
// TODO Express better with iterators
|
||||
let mut i1 = None;
|
||||
for idx in (0..=idx_in_route).rev() {
|
||||
let i = route.all_pts[idx];
|
||||
for idx in (0..idx_in_route).rev() {
|
||||
let i = route.all_pts[idx].0;
|
||||
if raw.intersections.contains_key(&i) {
|
||||
i1 = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let mut i2 = None;
|
||||
// If we're at an intersection, i2 should be the intersection, because earlier we preferred
|
||||
// a road starting before it.
|
||||
for idx in idx_in_route..route.all_pts.len() {
|
||||
let i = route.all_pts[idx];
|
||||
let i = route.all_pts[idx].0;
|
||||
if raw.intersections.contains_key(&i) {
|
||||
i2 = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let road = pt_to_road[&stop.vehicle_pos.1.to_hashable()];
|
||||
let i1 = i1.unwrap();
|
||||
let i2 = i2.unwrap();
|
||||
let fwds = if road.i1 == i1 && road.i2 == i2 {
|
||||
@ -243,8 +264,9 @@ pub fn snap_bus_stops(
|
||||
false
|
||||
} else {
|
||||
return Err(format!(
|
||||
"Can't figure out where {} is along route. {:?}, {:?}. {} of {}",
|
||||
"Can't figure out where {} is along route. At {}, between {:?} and {:?}. {} of {}",
|
||||
stop.vehicle_pos.0.osm_node_id,
|
||||
road,
|
||||
i1,
|
||||
i2,
|
||||
idx_in_route,
|
||||
|
@ -319,16 +319,16 @@ pub fn route(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusRouteI
|
||||
);
|
||||
}
|
||||
|
||||
for bs in &route.stops {
|
||||
for (idx, bs) in route.stops.iter().enumerate() {
|
||||
let bs = map.get_bs(*bs);
|
||||
details.unzoomed.append(
|
||||
Text::from(Line(&bs.name))
|
||||
Text::from(Line(format!("{}) {}", idx + 1, bs.name)))
|
||||
.with_bg()
|
||||
.render_to_batch(ctx.prerender)
|
||||
.centered_on(bs.sidewalk_pos.pt(map)),
|
||||
);
|
||||
details.zoomed.append(
|
||||
Text::from(Line(&bs.name))
|
||||
Text::from(Line(format!("{}) {}", idx + 1, bs.name)))
|
||||
.with_bg()
|
||||
.render_to_batch(ctx.prerender)
|
||||
.scale(0.1)
|
||||
|
@ -465,7 +465,7 @@ pub struct RawBusRoute {
|
||||
pub border_end: Option<OriginalIntersection>,
|
||||
// This is guaranteed to be in order and contiguous. These're ALL nodes, not just
|
||||
// intersections.
|
||||
pub all_pts: Vec<OriginalIntersection>,
|
||||
pub all_pts: Vec<(OriginalIntersection, Pt2D)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
Loading…
Reference in New Issue
Block a user