handle bus stops right at intersections

This commit is contained in:
Dustin Carlino 2020-08-08 19:32:18 -07:00
parent 52e89315d7
commit ecd5d86009
4 changed files with 46 additions and 24 deletions

View File

@ -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);
}
}

View File

@ -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,

View File

@ -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)

View File

@ -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)]