scrape bus info from OSM into the RawMap layer. don't use it yet.

This commit is contained in:
Dustin Carlino 2020-07-03 12:00:42 -07:00
parent 315ab5c8e6
commit 1175826f3d
3 changed files with 149 additions and 26 deletions

View File

@ -1,10 +1,10 @@
use abstutil::{FileWithProgress, Timer}; use abstutil::{FileWithProgress, Timer};
use geom::{GPSBounds, HashablePt2D, LonLat, PolyLine, Polygon, Pt2D, Ring}; use geom::{GPSBounds, HashablePt2D, LonLat, PolyLine, Polygon, Pt2D, Ring};
use map_model::raw::{ use map_model::raw::{
OriginalBuilding, RawArea, RawBuilding, RawMap, RawParkingLot, RawRoad, RestrictionType, OriginalBuilding, RawArea, RawBuilding, RawBusRoute, RawBusStop, RawMap, RawParkingLot,
RawRoad, RestrictionType,
}; };
use map_model::{osm, AreaType}; use map_model::{osm, AreaType};
use osm_xml;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
pub fn extract_osm( pub fn extract_osm(
@ -276,20 +276,9 @@ pub fn extract_osm(
}, },
); );
} }
/*} else if tags.get("type") == Some(&"route_master".to_string()) { } else if tags.get("type") == Some(&"route_master".to_string()) {
let name = tags.get("name").unwrap(); map.new_bus_routes
//let mut fwd_stops = Vec::new(); .extend(extract_route(&tags, rel, &doc, &id_to_way, &map.gps_bounds));
//let mut back_stops = Vec::new();
for member in &rel.members {
if let osm_xml::Member::Relation(rel_ref, _) = member {
if let osm_xml::Reference::Relation(inner_rel) = doc.resolve_reference(&rel_ref) {
let inner_tags = tags_to_map(&inner_rel.tags);
assert_eq!(inner_tags.get("type"), Some(&"route".to_string()));
for member in &inner_rel.members {
}
}
}
}*/
} }
} }
@ -605,3 +594,117 @@ fn glue_to_boundary(result_pl: PolyLine, boundary: &Ring) -> Option<Polygon> {
assert_eq!(trimmed_pts[0], *trimmed_pts.last().unwrap()); assert_eq!(trimmed_pts[0], *trimmed_pts.last().unwrap());
Some(Polygon::new(&trimmed_pts)) Some(Polygon::new(&trimmed_pts))
} }
fn extract_route(
master_tags: &BTreeMap<String, String>,
master_rel: &osm_xml::Relation,
doc: &osm_xml::OSM,
id_to_way: &HashMap<i64, Vec<Pt2D>>,
gps_bounds: &GPSBounds,
) -> Option<RawBusRoute> {
let route_name = master_tags.get("name")?.clone();
let is_bus = match master_tags.get("route_master")?.as_ref() {
"bus" => true,
"light_rail" => false,
x => {
println!("Skipping route {} of unknown type {}", route_name, x);
return None;
}
};
let mut directions = Vec::new();
for (_, route_member) in get_members(master_rel, doc) {
if let osm_xml::Reference::Relation(route_rel) = route_member {
let route_tags = tags_to_map(&route_rel.tags);
assert_eq!(route_tags.get("type"), Some(&"route".to_string()));
// Gather stops in order. Platforms may exist or not; match them up by name.
let mut stops = Vec::new();
let mut platforms = HashMap::new();
for (role, member) in get_members(&route_rel, doc) {
if role == "stop" {
if let osm_xml::Reference::Node(node) = member {
stops.push(RawBusStop {
name: tags_to_map(&node.tags)
.get("name")
.cloned()
.unwrap_or_else(|| format!("stop #{}", stops.len() + 1)),
vehicle_pos: Pt2D::forcibly_from_gps(
LonLat::new(node.lon, node.lat),
gps_bounds,
),
ped_pos: None,
});
}
} else if role == "platform" {
let (platform_name, pt) = match member {
osm_xml::Reference::Node(node) => (
tags_to_map(&node.tags)
.get("name")
.cloned()
.unwrap_or_else(|| format!("stop #{}", platforms.len() + 1)),
Pt2D::forcibly_from_gps(LonLat::new(node.lon, node.lat), gps_bounds),
),
osm_xml::Reference::Way(way) => (
tags_to_map(&way.tags)
.get("name")
.cloned()
.unwrap_or_else(|| format!("stop #{}", platforms.len() + 1)),
if let Some(ref pts) = id_to_way.get(&way.id) {
Pt2D::center(pts)
} else {
continue;
},
),
_ => continue,
};
platforms.insert(platform_name, pt);
}
}
for stop in &mut stops {
if let Some(pt) = platforms.remove(&stop.name) {
stop.ped_pos = Some(pt);
}
}
if stops.len() >= 2 {
directions.push(stops);
}
}
}
if directions.len() == 2 {
Some(RawBusRoute {
name: route_name,
is_bus,
osm_rel_id: master_rel.id,
// The direction is arbitrary right now
fwd_stops: directions.pop().unwrap(),
back_stops: directions.pop().unwrap(),
})
} else {
println!(
"Skipping route {} with {} sub-routes",
route_name,
directions.len()
);
None
}
}
// Work around osm_xml's API, which shows the node/way/relation distinction twice. This returns
// (role, resolved node/way/relation)
fn get_members<'a>(
rel: &'a osm_xml::Relation,
doc: &'a osm_xml::OSM,
) -> Vec<(&'a String, osm_xml::Reference<'a>)> {
rel.members
.iter()
.map(|member| {
let (id_ref, role) = match member {
osm_xml::Member::Node(id, role)
| osm_xml::Member::Way(id, role)
| osm_xml::Member::Relation(id, role) => (id, role),
};
(role, doc.resolve_reference(id_ref))
})
.collect()
}

View File

@ -1,16 +1,16 @@
data/input/austin/osm/Austin.osm,7c8d72cf97072af34cee665006b1e9e6,https://www.dropbox.com/s/8bedio4fpt6yvhg/Austin.osm.zip?dl=0 data/input/austin/osm/Austin.osm,7c8d72cf97072af34cee665006b1e9e6,https://www.dropbox.com/s/8bedio4fpt6yvhg/Austin.osm.zip?dl=0
data/input/austin/osm/downtown_atx.osm,a30b0f460a481598e494f16a9d07a822,https://www.dropbox.com/s/tbadw3f0ex2zzx7/downtown_atx.osm.zip?dl=0 data/input/austin/osm/downtown_atx.osm,a30b0f460a481598e494f16a9d07a822,https://www.dropbox.com/s/tbadw3f0ex2zzx7/downtown_atx.osm.zip?dl=0
data/input/austin/osm/huge_austin.osm,fb166029fc8006bd20dc959fbbbde3b6,https://www.dropbox.com/s/4x421o9o8px0m6o/huge_austin.osm.zip?dl=0 data/input/austin/osm/huge_austin.osm,fb166029fc8006bd20dc959fbbbde3b6,https://www.dropbox.com/s/4x421o9o8px0m6o/huge_austin.osm.zip?dl=0
data/input/raw_maps/ballard.bin,fe5f56a77d784e1604a7062805e6eed8,https://www.dropbox.com/s/urt8jms4st0nodt/ballard.bin.zip?dl=0 data/input/raw_maps/ballard.bin,e86dc091224aebad6e87c374cfdc0ae7,https://www.dropbox.com/s/aqrjfur2d7bqb2o/ballard.bin.zip?dl=0
data/input/raw_maps/downtown.bin,d1817deb55761f7cc10f8550850762c9,https://www.dropbox.com/s/qj927riunhv9ygv/downtown.bin.zip?dl=0 data/input/raw_maps/downtown.bin,23a8f0e8d0adf61f1bede08f9e05c755,https://www.dropbox.com/s/wq2wm0gb62diz4x/downtown.bin.zip?dl=0
data/input/raw_maps/downtown_atx.bin,0cd7ecaf548124710936a173ef617e0a,https://www.dropbox.com/s/0qiji6lmwmkpt6y/downtown_atx.bin.zip?dl=0 data/input/raw_maps/downtown_atx.bin,10952f03672526eab180c724af188809,https://www.dropbox.com/s/37jx8htloc5j5rr/downtown_atx.bin.zip?dl=0
data/input/raw_maps/huge_austin.bin,5d0fdca0eb9bae5cd5e0955442972bd4,https://www.dropbox.com/s/zs6te7tq7vgjicc/huge_austin.bin.zip?dl=0 data/input/raw_maps/huge_austin.bin,201d0aff6c9dde9c6f60a2af727d1b32,https://www.dropbox.com/s/jv8dhiebx35n0kg/huge_austin.bin.zip?dl=0
data/input/raw_maps/huge_seattle.bin,22f323f1ce1917df9e261f24f557780f,https://www.dropbox.com/s/r6cj78jq3z7s5bs/huge_seattle.bin.zip?dl=0 data/input/raw_maps/huge_seattle.bin,c497258745e278ad7d30b5801a66aaeb,https://www.dropbox.com/s/oikef0juh0iqmw3/huge_seattle.bin.zip?dl=0
data/input/raw_maps/lakeslice.bin,c346ac30ad726456802937729af76af4,https://www.dropbox.com/s/uh4oacev5raty9z/lakeslice.bin.zip?dl=0 data/input/raw_maps/lakeslice.bin,7ec24ec2860b91a7616cb8fe55afb3b8,https://www.dropbox.com/s/5tkypxuarkr65cd/lakeslice.bin.zip?dl=0
data/input/raw_maps/montlake.bin,b17d1f76d6c5dd4a3af07343ca52590d,https://www.dropbox.com/s/dfcoo90hpwa8osj/montlake.bin.zip?dl=0 data/input/raw_maps/montlake.bin,e18c8a7f5992cb4af39843275f42125a,https://www.dropbox.com/s/2bn4k7axosjig4u/montlake.bin.zip?dl=0
data/input/raw_maps/south_seattle.bin,a8ded05512d20fac14cdb8e605c14995,https://www.dropbox.com/s/1m7fkvuyhyev3cw/south_seattle.bin.zip?dl=0 data/input/raw_maps/south_seattle.bin,96303da5abeea874585e789eaaf4be51,https://www.dropbox.com/s/ql70xxsjgyuypd8/south_seattle.bin.zip?dl=0
data/input/raw_maps/udistrict.bin,eba1715dd8a66ff3fb0a39aa92419d93,https://www.dropbox.com/s/wbudupyrqd1aqg6/udistrict.bin.zip?dl=0 data/input/raw_maps/udistrict.bin,0f876dc016f2f032c4b85395a1d73fa2,https://www.dropbox.com/s/bq38e79k7md98z5/udistrict.bin.zip?dl=0
data/input/raw_maps/west_seattle.bin,04c347cc62a3c2f078190b98af04c10f,https://www.dropbox.com/s/350gq0dtgvw2lrg/west_seattle.bin.zip?dl=0 data/input/raw_maps/west_seattle.bin,91b3ac23ceb67c81f8fc0ced172f915c,https://www.dropbox.com/s/vtdnt5zpchmdh0s/west_seattle.bin.zip?dl=0
data/input/screenshots/downtown/01x01.gif,873df007edd02e5967f3917cbe8f342f,https://www.dropbox.com/s/4209gvxkypinlqs/01x01.gif.zip?dl=0 data/input/screenshots/downtown/01x01.gif,873df007edd02e5967f3917cbe8f342f,https://www.dropbox.com/s/4209gvxkypinlqs/01x01.gif.zip?dl=0
data/input/screenshots/downtown/01x02.gif,ec8b579d6cb498a2a85bc2af8b51f390,https://www.dropbox.com/s/9x5qtp86h3uemzm/01x02.gif.zip?dl=0 data/input/screenshots/downtown/01x02.gif,ec8b579d6cb498a2a85bc2af8b51f390,https://www.dropbox.com/s/9x5qtp86h3uemzm/01x02.gif.zip?dl=0
data/input/screenshots/downtown/01x03.gif,c126afdf55a94993e6c9a909eb685f8c,https://www.dropbox.com/s/4ev4pepyvrl6bs4/01x03.gif.zip?dl=0 data/input/screenshots/downtown/01x03.gif,c126afdf55a94993e6c9a909eb685f8c,https://www.dropbox.com/s/4ev4pepyvrl6bs4/01x03.gif.zip?dl=0

View File

@ -27,6 +27,7 @@ pub struct RawMap {
)] )]
pub buildings: BTreeMap<OriginalBuilding, RawBuilding>, pub buildings: BTreeMap<OriginalBuilding, RawBuilding>,
pub bus_routes: Vec<Route>, pub bus_routes: Vec<Route>,
pub new_bus_routes: Vec<RawBusRoute>,
pub areas: Vec<RawArea>, pub areas: Vec<RawArea>,
pub parking_lots: Vec<RawParkingLot>, pub parking_lots: Vec<RawParkingLot>,
pub parking_aisles: Vec<Vec<Pt2D>>, pub parking_aisles: Vec<Vec<Pt2D>>,
@ -94,6 +95,7 @@ impl RawMap {
intersections: BTreeMap::new(), intersections: BTreeMap::new(),
buildings: BTreeMap::new(), buildings: BTreeMap::new(),
bus_routes: Vec::new(), bus_routes: Vec::new(),
new_bus_routes: Vec::new(),
areas: Vec::new(), areas: Vec::new(),
parking_lots: Vec::new(), parking_lots: Vec::new(),
parking_aisles: Vec::new(), parking_aisles: Vec::new(),
@ -421,3 +423,21 @@ impl DrivingSide {
} }
} }
} }
#[derive(Debug, Serialize, Deserialize)]
pub struct RawBusRoute {
pub name: String,
pub osm_rel_id: i64,
// If not, light rail
pub is_bus: bool,
pub fwd_stops: Vec<RawBusStop>,
pub back_stops: Vec<RawBusStop>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct RawBusStop {
pub name: String,
pub vehicle_pos: Pt2D,
// If it's not explicitly mapped, we'll do equiv_pos.
pub ped_pos: Option<Pt2D>,
}