better errors when matching stops/platforms fails. need to use stop_area

in convert_osm layer.
This commit is contained in:
Dustin Carlino 2020-07-15 13:51:16 -07:00
parent 91a9a9a1bc
commit b626eb12ad
2 changed files with 71 additions and 47 deletions

View File

@ -423,6 +423,7 @@ fn is_road(tags: &mut Tags) -> bool {
"razed",
"corridor",
"junction",
"bus_stop",
],
) {
return false;

View File

@ -18,39 +18,43 @@ pub fn make_stops_and_routes(map: &mut Map, raw_routes: &Vec<RawBusRoute>, timer
let mut stops = Vec::new();
let mut ok = true;
for stop in &r.stops {
if let Some((sidewalk_pos, driving_pos)) = matcher.lookup(r.is_bus, stop, map) {
// Create a new bus stop if needed.
let stop_id = if let Some(id) = pt_to_stop.get(&(sidewalk_pos, driving_pos)) {
*id
} else {
let id = BusStopID {
sidewalk: sidewalk_pos.lane(),
idx: map.get_l(sidewalk_pos.lane()).bus_stops.len(),
};
pt_to_stop.insert((sidewalk_pos, driving_pos), id);
map.lanes[sidewalk_pos.lane().0].bus_stops.insert(id);
map.bus_stops.insert(
id,
BusStop {
match matcher.lookup(r.is_bus, stop, map) {
Ok((sidewalk_pos, driving_pos)) => {
// Create a new bus stop if needed.
let stop_id = if let Some(id) = pt_to_stop.get(&(sidewalk_pos, driving_pos)) {
*id
} else {
let id = BusStopID {
sidewalk: sidewalk_pos.lane(),
idx: map.get_l(sidewalk_pos.lane()).bus_stops.len(),
};
pt_to_stop.insert((sidewalk_pos, driving_pos), id);
map.lanes[sidewalk_pos.lane().0].bus_stops.insert(id);
map.bus_stops.insert(
id,
name: stop.name.clone(),
driving_pos,
sidewalk_pos,
is_train_stop: !r.is_bus,
},
);
id
};
stops.push(stop_id);
} else {
timer.warn(format!(
"Couldn't match stop {} for route {} ({})",
stop.name,
r.full_name,
rel_url(r.osm_rel_id)
));
ok = false;
break;
BusStop {
id,
name: stop.name.clone(),
driving_pos,
sidewalk_pos,
is_train_stop: !r.is_bus,
},
);
id
};
stops.push(stop_id);
}
Err(err) => {
timer.warn(format!(
"Couldn't match stop {} for route {} ({}): {}",
stop.name,
r.full_name,
rel_url(r.osm_rel_id),
err,
));
ok = false;
break;
}
}
}
if !ok {
@ -132,7 +136,7 @@ impl Matcher {
map.all_lanes(),
|l| l.is_sidewalk(),
Distance::ZERO,
Distance::meters(10.0),
Distance::meters(30.0),
timer,
);
let bus_pts = match_points_to_lanes(
@ -164,41 +168,60 @@ impl Matcher {
}
// returns (sidewalk, driving)
fn lookup(&self, is_bus: bool, stop: &RawBusStop, map: &Map) -> Option<(Position, Position)> {
fn lookup(
&self,
is_bus: bool,
stop: &RawBusStop,
map: &Map,
) -> Result<(Position, Position), Box<dyn Error>> {
if !is_bus {
// Light rail needs explicit platforms.
let sidewalk_pos = *self.sidewalk_pts.get(&stop.ped_pos?.to_hashable())?;
let driving_pos = *self.light_rail_pts.get(&stop.vehicle_pos.to_hashable())?;
return Some((sidewalk_pos, driving_pos));
let sidewalk_pos = *self
.sidewalk_pts
.get(
&stop
.ped_pos
.ok_or("light rail missing platform")?
.to_hashable(),
)
.ok_or("sidewalk didnt match")?;
let driving_pos = *self
.light_rail_pts
.get(&stop.vehicle_pos.to_hashable())
.ok_or("driving didnt match")?;
return Ok((sidewalk_pos, driving_pos));
}
// Because the stop is usually mapped on the road center-line, the matched side-of-the-road
// is often wrong. If we have the bus stop, actually use that and get the equivalent
// position on the closest driving/bus lane.
if let Some(pt) = stop.ped_pos {
let sidewalk_pos = *self.sidewalk_pts.get(&pt.to_hashable())?;
let sidewalk_pos = *self
.sidewalk_pts
.get(&pt.to_hashable())
.ok_or("sidewalk didnt match")?;
let lane = map
.get_parent(sidewalk_pos.lane())
.find_closest_lane(sidewalk_pos.lane(), vec![LaneType::Bus, LaneType::Driving])
.ok()?;
.find_closest_lane(sidewalk_pos.lane(), vec![LaneType::Bus, LaneType::Driving])?;
let driving_pos = sidewalk_pos.equiv_pos(lane, Distance::ZERO, map);
return Some((sidewalk_pos, driving_pos));
return Ok((sidewalk_pos, driving_pos));
}
// We only have the driving position. First find the sidewalk, then snap it to the
// rightmost driving/bus lane.
let orig_driving_pos = *self.bus_pts.get(&stop.vehicle_pos.to_hashable())?;
let orig_driving_pos = *self
.bus_pts
.get(&stop.vehicle_pos.to_hashable())
.ok_or("driving didnt match")?;
let sidewalk = map
.get_parent(orig_driving_pos.lane())
.find_closest_lane(orig_driving_pos.lane(), vec![LaneType::Sidewalk])
.ok()?;
.find_closest_lane(orig_driving_pos.lane(), vec![LaneType::Sidewalk])?;
let sidewalk_pos = orig_driving_pos.equiv_pos(sidewalk, Distance::ZERO, map);
let lane = map
.get_parent(sidewalk_pos.lane())
.find_closest_lane(sidewalk_pos.lane(), vec![LaneType::Bus, LaneType::Driving])
.ok()?;
.find_closest_lane(sidewalk_pos.lane(), vec![LaneType::Bus, LaneType::Driving])?;
let driving_pos = sidewalk_pos.equiv_pos(lane, Distance::ZERO, map);
Some((sidewalk_pos, driving_pos))
Ok((sidewalk_pos, driving_pos))
}
}