Skip to content

Commit

Permalink
Rip out all old broken code for importing OSM bus stops and routes. #372
Browse files Browse the repository at this point in the history


This code stopped working around July 2020 when I attempted to tackle #190. It's sat dormant since then, with most bus and light rail routes not imported correctly at all. I'm going to (eventually) start another attempt at public transit in A/B Street by treating GTFS as the main source of truth, not trying to understand route relations mapped in OSM. It's simplest to just rip out all this old code first. Some of it may be useful later, but version control preserves it.

Regenerating everything; this is a binary format change.
  • Loading branch information
dabreegster committed Nov 18, 2021
1 parent 68d9616 commit 94fe2bf
Show file tree
Hide file tree
Showing 11 changed files with 13 additions and 957 deletions.
70 changes: 1 addition & 69 deletions convert_osm/src/clip.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::BTreeMap;

use abstutil::Timer;
use geom::{Distance, PolyLine, Ring};
use geom::{PolyLine, Ring};
use map_model::raw::{OriginalRoad, RawMap};
use map_model::{osm, IntersectionType};

Expand Down Expand Up @@ -165,73 +165,5 @@ pub fn clip_map(map: &mut RawMap, timer: &mut Timer) {
panic!("There are no roads inside the clipping polygon");
}

let all_routes = map.bus_routes.drain(..).collect::<Vec<_>>();
for mut r in all_routes {
if r.stops[0].vehicle_pos == r.stops.last().unwrap().vehicle_pos {
// A loop?
map.bus_routes.push(r);
continue;
}

let mut borders: Vec<osm::NodeID> = Vec::new();
for (node, _) in &r.all_pts {
if let Some(i) = map.intersections.get(node) {
if i.intersection_type == IntersectionType::Border {
borders.push(*node);
}
}
if let Some(i) = extra_borders.get(node) {
borders.push(*i);
}
}

// Guess which border is for the beginning and end of the route.
let start_i = map.closest_intersection(r.stops[0].vehicle_pos.1);
let end_i = map.closest_intersection(r.stops.last().unwrap().vehicle_pos.1);
let mut best_start: Option<(osm::NodeID, Distance)> = None;
let mut best_end: Option<(osm::NodeID, Distance)> = None;
for i in borders {
// closest_intersection might snap to the wrong end, so try both directions
if let Some(d1) = map
.path_dist_to(i, start_i)
.or_else(|| map.path_dist_to(start_i, i))
{
if best_start.map(|(_, d2)| d1 < d2).unwrap_or(true) {
best_start = Some((i, d1));
}
}
if let Some(d1) = map.path_dist_to(end_i, i) {
if best_end.map(|(_, d2)| d1 < d2).unwrap_or(true) {
best_end = Some((i, d1));
}
}
}

// If both matched to the same border, probably the route properly starts or ends inside
// the map. (If it was both, then we shouldn't have even had any borders at all.)
match (best_start, best_end) {
(Some((i1, d1)), Some((i2, d2))) => {
if i1 == i2 {
if d1 < d2 {
r.border_start = Some(i1);
} else {
r.border_end = Some(i2);
}
} else {
r.border_start = Some(i1);
r.border_end = Some(i2);
}
}
(Some((i1, _)), None) => {
r.border_start = Some(i1);
}
(None, Some((i2, _))) => {
r.border_end = Some(i2);
}
(None, None) => {}
}
map.bus_routes.push(r);
}

timer.stop("clipping map to boundary");
}
41 changes: 1 addition & 40 deletions convert_osm/src/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use map_model::raw::{RawArea, RawBuilding, RawMap, RawParkingLot, RawRoad, Restr
use map_model::{osm, Amenity, AreaType, Direction, DrivingSide, NamePerLanguage};

use crate::osm_geom::{get_multipolygon_members, glue_multipolygon, multipoly_geometry};
use crate::{transit, Options};
use crate::Options;

pub struct OsmExtract {
/// Unsplit roads
Expand Down Expand Up @@ -186,8 +186,6 @@ pub fn extract_osm(
let boundary = map.boundary_polygon.clone().into_ring();

let mut amenity_areas: Vec<(Polygon, Amenity)> = Vec::new();
// Vehicle position (stop) -> pedestrian position (platform)
let mut stop_areas: Vec<((osm::NodeID, Pt2D), Pt2D)> = Vec::new();

// TODO Fill this out in a separate loop to keep a mutable borrow short. Maybe do this in
// reader, or stop doing this entirely.
Expand Down Expand Up @@ -285,9 +283,6 @@ pub fn extract_osm(
osm_tags: rel.tags.clone(),
});
}
} else if rel.tags.is("type", "route") {
map.bus_routes
.extend(transit::extract_route(id, rel, &doc, &map.boundary_polygon));
} else if rel.tags.is("type", "multipolygon") && rel.tags.contains_key("amenity") {
let amenity = Amenity {
names: NamePerLanguage::new(&rel.tags).unwrap_or_else(NamePerLanguage::unnamed),
Expand All @@ -304,28 +299,6 @@ pub fn extract_osm(
}
}
}
} else if rel.tags.is("public_transport", "stop_area") {
let mut stops = Vec::new();
let mut platform: Option<Pt2D> = None;
for (role, member) in &rel.members {
if let OsmID::Node(n) = member {
let pt = doc.nodes[n].pt;
if role == "stop" {
stops.push((*n, pt));
} else if role == "platform" {
platform = Some(pt);
}
} else if let OsmID::Way(w) = member {
if role == "platform" {
platform = Some(Pt2D::center(&doc.ways[w].pts));
}
}
}
if let Some(ped_pos) = platform {
for vehicle_pos in stops {
stop_areas.push((vehicle_pos, ped_pos));
}
}
}
}

Expand Down Expand Up @@ -364,18 +337,6 @@ pub fn extract_osm(
}
}

// Match platforms from stop_areas. Not sure what order routes and stop_areas will appear in
// relations, so do this after reading all of them.
for (vehicle_pos, ped_pos) in stop_areas {
for route in &mut map.bus_routes {
for stop in &mut route.stops {
if stop.vehicle_pos == vehicle_pos {
stop.ped_pos = Some(ped_pos);
}
}
}
}

// Hack to fix z-ordering for Green Lake (and probably other places). Put water and islands
// last. I think the more proper fix is interpreting "inner" roles in relations.
map.areas.sort_by_key(|a| match a.area_type {
Expand Down
18 changes: 1 addition & 17 deletions convert_osm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ pub mod osm_geom;
mod parking;
pub mod reader;
mod split_ways;
mod transit;

/// Configures the creation of a RawMap from OSM and other input data.
pub struct Options {
Expand Down Expand Up @@ -93,28 +92,13 @@ pub fn convert(
}

let extract = extract::extract_osm(&mut map, &osm_input_path, clip_path, &opts, timer);
let (amenities, crosswalks, pt_to_road) = split_ways::split_up_roads(&mut map, extract, timer);
let (amenities, crosswalks) = split_ways::split_up_roads(&mut map, extract, timer);
clip::clip_map(&mut map, timer);

// Need to do a first pass of removing cul-de-sacs here, or we wind up with loop PolyLines when
// doing the parking hint matching.
map.roads.retain(|r, _| r.i1 != r.i2);

let all_routes = map.bus_routes.drain(..).collect::<Vec<_>>();
let mut routes = Vec::new();
for route in all_routes {
let name = format!("{} ({})", route.osm_rel_id, route.full_name);
match transit::snap_bus_stops(route, &mut map, &pt_to_road) {
Ok(r) => {
routes.push(r);
}
Err(err) => {
error!("Skipping {}: {}", name, err);
}
}
}
map.bus_routes = routes;

use_amenities(&mut map, amenities, timer);

parking::apply_parking(&mut map, &opts, timer);
Expand Down
22 changes: 3 additions & 19 deletions convert_osm/src/split_ways.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@ use map_model::{osm, Amenity, Direction, IntersectionType};

use crate::extract::OsmExtract;

/// Returns amenities, a set of crosswalk locations, and a mapping of all points to split road.
/// (Some internal points on roads get removed in this call, so this mapping isn't redundant.)
/// Returns amenities and a set of crosswalk locations.
pub fn split_up_roads(
map: &mut RawMap,
mut input: OsmExtract,
timer: &mut Timer,
) -> (
Vec<(Pt2D, Amenity)>,
HashSet<HashablePt2D>,
HashMap<HashablePt2D, OriginalRoad>,
) {
) -> (Vec<(Pt2D, Amenity)>, HashSet<HashablePt2D>) {
timer.start("splitting up roads");

let mut roundabout_centers: HashMap<osm::NodeID, Pt2D> = HashMap::new();
Expand Down Expand Up @@ -227,19 +222,8 @@ pub fn split_up_roads(
}
timer.stop("match traffic signals to intersections");

// For the transit snapping that later uses this, we have to make pt_to_road only refer to
// points currently on the roads, not any deduped internal points.
pt_to_road.clear();
for (id, r) in &map.roads {
for (idx, pt) in r.center_points.iter().enumerate() {
if idx != 0 && idx != r.center_points.len() - 1 {
pt_to_road.insert(pt.to_hashable(), *id);
}
}
}

timer.stop("splitting up roads");
(input.amenities, input.crosswalks, pt_to_road)
(input.amenities, input.crosswalks)
}

// TODO Consider doing this in PolyLine::new always. extend() there does this too.
Expand Down
Loading

0 comments on commit 94fe2bf

Please sign in to comment.