diff --git a/convert_osm/src/osm_reader.rs b/convert_osm/src/osm_reader.rs index 934cfa8689..518d1b916c 100644 --- a/convert_osm/src/osm_reader.rs +++ b/convert_osm/src/osm_reader.rs @@ -423,6 +423,7 @@ fn is_road(tags: &mut Tags) -> bool { "razed", "corridor", "junction", + "bus_stop", ], ) { return false; diff --git a/map_model/src/make/transit.rs b/map_model/src/make/transit.rs index 36b45485a7..95097ffd58 100644 --- a/map_model/src/make/transit.rs +++ b/map_model/src/make/transit.rs @@ -18,39 +18,43 @@ pub fn make_stops_and_routes(map: &mut Map, raw_routes: &Vec, 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> { 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)) } }