pretty darn robust border matching: by path distance, not some VFD crow.

for #190
This commit is contained in:
Dustin Carlino 2020-07-15 19:04:24 -07:00
parent b942510f67
commit 7a1081971d
4 changed files with 119 additions and 68 deletions

View File

@ -1,5 +1,5 @@
use abstutil::{retain_btreemap, Timer};
use geom::{PolyLine, Pt2D, Ring};
use geom::{Distance, PolyLine, Ring};
use map_model::raw::{OriginalIntersection, OriginalRoad, RawMap};
use map_model::IntersectionType;
use std::collections::BTreeMap;
@ -30,8 +30,7 @@ pub fn clip_map(map: &mut RawMap, timer: &mut Timer) {
// When we split an intersection out of bounds into two, one of them gets a new ID. Remember
// that here.
let mut extra_borders: BTreeMap<OriginalIntersection, (OriginalIntersection, Pt2D)> =
BTreeMap::new();
let mut extra_borders: BTreeMap<OriginalIntersection, OriginalIntersection> = BTreeMap::new();
// First pass: Clip roads beginning out of bounds
let road_ids: Vec<OriginalRoad> = map.roads.keys().cloned().collect();
@ -60,7 +59,7 @@ pub fn clip_map(map: &mut RawMap, timer: &mut Timer) {
move_i = OriginalIntersection {
osm_node_id: map.new_osm_node_id(-1),
};
extra_borders.insert(orig_id, (move_i, copy.point));
extra_borders.insert(orig_id, move_i);
map.intersections.insert(move_i, copy);
println!("Disconnecting {} from some other stuff (starting OOB)", id);
}
@ -119,7 +118,7 @@ pub fn clip_map(map: &mut RawMap, timer: &mut Timer) {
move_i = OriginalIntersection {
osm_node_id: map.new_osm_node_id(-1),
};
extra_borders.insert(orig_id, (move_i, copy.point));
extra_borders.insert(orig_id, move_i);
map.intersections.insert(move_i, copy);
println!("Disconnecting {} from some other stuff (ending OOB)", id);
}
@ -171,52 +170,73 @@ pub fn clip_map(map: &mut RawMap, timer: &mut Timer) {
panic!("There are no roads inside the clipping polygon");
}
let mut keep_routes = Vec::new();
for mut r in map.bus_routes.drain(..) {
let mut borders: Vec<(OriginalIntersection, Pt2D)> = Vec::new();
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<OriginalIntersection> = Vec::new();
for pt in r.all_pts.drain(..) {
if let Some(i) = map.intersections.get(&pt) {
if i.intersection_type == IntersectionType::Border {
borders.push((pt, i.point));
borders.push(pt);
}
}
if let Some(pair) = extra_borders.get(&pt) {
borders.push(*pair);
if let Some(i) = extra_borders.get(&pt) {
borders.push(*i);
}
}
if !borders.is_empty() {
// Guess which border is for the beginning and end of the route. This can fail if:
// - there's just one stop
// - the border isn't actually connected to the stop by any path (roads causing copied
// intersections trigger this)
let start_pt = r.stops[0].vehicle_pos;
let closest_to_start = borders
.iter()
.min_by_key(|(_, pt)| start_pt.dist_to(*pt))
.unwrap();
let end_pt = r.stops.last().unwrap().vehicle_pos;
let closest_to_end = borders
.iter()
.min_by_key(|(_, pt)| end_pt.dist_to(*pt))
.unwrap();
// Guess which border is for the beginning and end of the route.
let start_i = map.closest_intersection(r.stops[0].vehicle_pos);
let end_i = map.closest_intersection(r.stops.last().unwrap().vehicle_pos);
let mut best_start: Option<(OriginalIntersection, Distance)> = None;
let mut best_end: Option<(OriginalIntersection, 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 closest_to_start.0 != closest_to_end.0 {
r.border_start = Some(closest_to_start.0);
r.border_end = Some(closest_to_end.0);
// 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 {
// Break the tie...
if closest_to_start.1.dist_to(start_pt) < closest_to_end.1.dist_to(end_pt) {
r.border_start = Some(closest_to_start.0);
r.border_end = Some(i2);
}
} else {
r.border_end = Some(closest_to_end.0);
r.border_start = Some(i1);
r.border_end = Some(i2);
}
}
(Some((i1, _)), None) => {
r.border_start = Some(i1);
}
// TODO Warn for some of these weird things and maybe skip
keep_routes.push(r);
(None, Some((i2, _))) => {
r.border_end = Some(i2);
}
(None, None) => {}
}
map.bus_routes.push(r);
}
map.bus_routes = keep_routes;
timer.stop("clipping map to boundary");
}

View File

@ -727,7 +727,9 @@ fn extract_route(
stop.ped_pos = Some(pt);
}
}
if stops.is_empty() {
if stops.len() < 2 {
// Routes with only 1 stop are pretty much useless, and it makes border matching quite
// confusing.
return None;
}

View File

@ -2,16 +2,16 @@ data/input/berlin/osm/berlin-latest.osm.pbf,52bbd0527d89827ddeb84eaff742ac5b,htt
data/input/berlin/osm/berlin_center.osm,5b777f293e8639af583eb5a6b4ce9e8f,https://www.dropbox.com/s/uo6qwure2ntll9h/berlin_center.osm.zip?dl=0
data/input/krakow/osm/huge_krakow.osm,03bae13bcf9461236b81dd1f0a74696d,https://www.dropbox.com/s/ooqaw4z5yfwucql/huge_krakow.osm.zip?dl=0
data/input/krakow/osm/malopolskie-latest.osm.pbf,36071de68f68c516fe81300c2d1940a9,https://www.dropbox.com/s/4718vobelcz32id/malopolskie-latest.osm.pbf.zip?dl=0
data/input/raw_maps/ballard.bin,c448d7d00a45eff40191deecaadaf2f3,https://www.dropbox.com/s/wf5q4j9zqydhr1g/ballard.bin.zip?dl=0
data/input/raw_maps/berlin_center.bin,3f38be020458996446d3a0f5643f6ba9,https://www.dropbox.com/s/htpuq3gqqxxlsap/berlin_center.bin.zip?dl=0
data/input/raw_maps/downtown.bin,8e655b3a726852f4ea91b2a73902b4b1,https://www.dropbox.com/s/ybyub6l35cqwh0t/downtown.bin.zip?dl=0
data/input/raw_maps/huge_krakow.bin,d429b09fadcb9580bd213522ef532c13,https://www.dropbox.com/s/fqan6lv8nmbnqwv/huge_krakow.bin.zip?dl=0
data/input/raw_maps/huge_seattle.bin,956ffe5cbdf1b3c69a45e4ff53be0e05,https://www.dropbox.com/s/m09awr37m1vkvn8/huge_seattle.bin.zip?dl=0
data/input/raw_maps/lakeslice.bin,5a8b331acdd6f58032e2578e16583686,https://www.dropbox.com/s/4addh02y0sgqz1p/lakeslice.bin.zip?dl=0
data/input/raw_maps/montlake.bin,e3e3c9781117c14bd6136db5204514df,https://www.dropbox.com/s/zq5i01zwul9qbxf/montlake.bin.zip?dl=0
data/input/raw_maps/south_seattle.bin,6bf114c062676000e942e821aa0da6e2,https://www.dropbox.com/s/k0u2ealcnu3esi6/south_seattle.bin.zip?dl=0
data/input/raw_maps/udistrict.bin,2f5f5d7e6c7ebe78b8cac365c4a0472d,https://www.dropbox.com/s/cezoqr5f2nb45oe/udistrict.bin.zip?dl=0
data/input/raw_maps/west_seattle.bin,1f94956b9ae9155faa8511be81313c3f,https://www.dropbox.com/s/w2bb42rbnmx7q8v/west_seattle.bin.zip?dl=0
data/input/raw_maps/ballard.bin,cd05c655dfd110b0a0c3c7b9c4ad8bbf,https://www.dropbox.com/s/fu805zdm6zess3i/ballard.bin.zip?dl=0
data/input/raw_maps/berlin_center.bin,93349f06e6e2a61acffdd065ed1a6065,https://www.dropbox.com/s/99yja0bvm93ifos/berlin_center.bin.zip?dl=0
data/input/raw_maps/downtown.bin,86a926f8ea132b73f5a59612d1354395,https://www.dropbox.com/s/9gwnlz41k5318ze/downtown.bin.zip?dl=0
data/input/raw_maps/huge_krakow.bin,9ddbabd8867132135ac8184cbe0d7de4,https://www.dropbox.com/s/azge718t65k3re9/huge_krakow.bin.zip?dl=0
data/input/raw_maps/huge_seattle.bin,8458be93892a24b0678ca39cdc8ad89e,https://www.dropbox.com/s/ghyht8fb1k26t4s/huge_seattle.bin.zip?dl=0
data/input/raw_maps/lakeslice.bin,413929903e2a95fe902699da2c4359fe,https://www.dropbox.com/s/y84lhubvo7h5bk1/lakeslice.bin.zip?dl=0
data/input/raw_maps/montlake.bin,991942b5bfb05cc69025038161a8ff6e,https://www.dropbox.com/s/qkrz0e77m3nb1a7/montlake.bin.zip?dl=0
data/input/raw_maps/south_seattle.bin,5e1ad0518f58c28eb0f97e1c84790671,https://www.dropbox.com/s/4mw5tmgm55qzu41/south_seattle.bin.zip?dl=0
data/input/raw_maps/udistrict.bin,cc93e1a6fe3b8601fc29434027a4401c,https://www.dropbox.com/s/z2085f1gqk6pfsy/udistrict.bin.zip?dl=0
data/input/raw_maps/west_seattle.bin,2e1546fdac82b37d48704c6451dc955f,https://www.dropbox.com/s/p8tkxd8snpgpsyq/west_seattle.bin.zip?dl=0
data/input/screenshots/downtown.zip,a7aae6ad193aed9e324225b2e7f76751,https://www.dropbox.com/s/qawd35wz62m2acl/downtown.zip.zip?dl=0
data/input/screenshots/huge_krakow.zip,6f91dcc1643d213bd035297f15c15891,https://www.dropbox.com/s/dbzon7k5ukndtza/huge_krakow.zip.zip?dl=0
data/input/screenshots/lakeslice.zip,308e6094fbc85de79fdb08686b088289,https://www.dropbox.com/s/z0z96lsn7bunqfy/lakeslice.zip.zip?dl=0
@ -31,29 +31,29 @@ data/input/seattle/osm/south_seattle.osm,86e589eaf7cd4f32db88ea9218e795d4,https:
data/input/seattle/osm/udistrict.osm,8eff2a0ded7eda9abfe469ac7a5c7b2d,https://www.dropbox.com/s/s3yb9xqbjuntu3v/udistrict.osm.zip?dl=0
data/input/seattle/osm/washington-latest.osm.pbf,05c7409a81df5b0d0bc058ebd619fbb5,https://www.dropbox.com/s/a6dax5p59ltjetm/washington-latest.osm.pbf.zip?dl=0
data/input/seattle/osm/west_seattle.osm,20109b038a36b527fe68bd4aa58baa92,https://www.dropbox.com/s/gsvwkd854wvyz5d/west_seattle.osm.zip?dl=0
data/input/seattle/parcels.bin,0abc62f44ced1b1148b1fc9ad9e6d79c,https://www.dropbox.com/s/q5qatuajnxtzngp/parcels.bin.zip?dl=0
data/input/seattle/parcels.bin,271c3f046f326a830922ef172a0a9032,https://www.dropbox.com/s/v156wvxvyshg5da/parcels.bin.zip?dl=0
data/input/seattle/parcels_urbansim.txt,db63d7d606e8702d12f9399e87e6a00f,https://www.dropbox.com/s/6g8rbsf200dssj3/parcels_urbansim.txt.zip?dl=0
data/input/seattle/popdat.bin,1aa2569c7e5a5a4773d7ca706d60432d,https://www.dropbox.com/s/p0g5cohy3p40p71/popdat.bin.zip?dl=0
data/input/seattle/trips_2014.csv,d4a8e733045b28c0385fb81359d6df03,https://www.dropbox.com/s/5ppravwmk6bf20d/trips_2014.csv.zip?dl=0
data/system/cities/seattle.bin,7019f93dac8ba704566049f6d253e533,https://www.dropbox.com/s/1k23g2q1nrmbh1m/seattle.bin.zip?dl=0
data/system/maps/ballard.bin,d8c2be061dae9c4bec61408cc3646fdc,https://www.dropbox.com/s/1tqo26tyd2majef/ballard.bin.zip?dl=0
data/system/maps/berlin_center.bin,2972ff520a96d81a1f7aaf13d8e9241a,https://www.dropbox.com/s/xsu3379pwtj15xl/berlin_center.bin.zip?dl=0
data/system/maps/downtown.bin,06d61ee2d6352d3185c0dfc82ad4ca97,https://www.dropbox.com/s/mv6ifaudt9b0cc4/downtown.bin.zip?dl=0
data/system/maps/huge_krakow.bin,18ef7041bf54bde528c2346fcf3b4343,https://www.dropbox.com/s/7173959flvgorlc/huge_krakow.bin.zip?dl=0
data/system/maps/huge_seattle.bin,9671446c215009ae3545d981b5989830,https://www.dropbox.com/s/qg0yuv4x2adi59d/huge_seattle.bin.zip?dl=0
data/system/maps/lakeslice.bin,d7eafeeec38b986d089eae58bd971506,https://www.dropbox.com/s/8pg2kl66sju75r6/lakeslice.bin.zip?dl=0
data/system/maps/montlake.bin,3b870d3908e2b74f644022d242c013b5,https://www.dropbox.com/s/oq52md1s79d46w3/montlake.bin.zip?dl=0
data/system/maps/south_seattle.bin,a033fd8d466ef6f2b1115172a7ab7a36,https://www.dropbox.com/s/oriqmqudc4tjrv3/south_seattle.bin.zip?dl=0
data/system/maps/udistrict.bin,7ba6c035badfd5fdba49355cae855ba8,https://www.dropbox.com/s/ey71ao48xyp56wg/udistrict.bin.zip?dl=0
data/system/maps/west_seattle.bin,e12eccf0cbae9cc1f867e75040221aec,https://www.dropbox.com/s/vinfk5qpgnffexh/west_seattle.bin.zip?dl=0
data/system/prebaked_results/lakeslice/weekday.bin,f417f9b365f1e70e92a2936f8f6e6900,https://www.dropbox.com/s/hh4viz3h995igy7/weekday.bin.zip?dl=0
data/system/maps/ballard.bin,4bc7f1aafaab6733aed1f0dc85e0b639,https://www.dropbox.com/s/hka1mhkbrleiedn/ballard.bin.zip?dl=0
data/system/maps/berlin_center.bin,caa6aec59ed67d5b6195ec39830841d4,https://www.dropbox.com/s/9m3gov3tcb4ssp4/berlin_center.bin.zip?dl=0
data/system/maps/downtown.bin,a54d3aa4300b3a4785fa7f859c97f1c9,https://www.dropbox.com/s/6zbsu37wrik39w0/downtown.bin.zip?dl=0
data/system/maps/huge_krakow.bin,615b8011b600ba9c2dc79ddb5be331b3,https://www.dropbox.com/s/chdn637l6xehy1a/huge_krakow.bin.zip?dl=0
data/system/maps/huge_seattle.bin,939d01b81ba988ba63cea52f2d58561d,https://www.dropbox.com/s/ctcwtlsymatabrf/huge_seattle.bin.zip?dl=0
data/system/maps/lakeslice.bin,05d343edafdce9a3bb0924c5bf080ef7,https://www.dropbox.com/s/8lehosjik3wjzad/lakeslice.bin.zip?dl=0
data/system/maps/montlake.bin,7a22621737d7f654339aef8fce3dabed,https://www.dropbox.com/s/wygfpgxpkytbc2i/montlake.bin.zip?dl=0
data/system/maps/south_seattle.bin,5ce769c4c63b06be6a3d717bc0c74dc9,https://www.dropbox.com/s/fer8t9r2nclx10e/south_seattle.bin.zip?dl=0
data/system/maps/udistrict.bin,1261c56226881db2b25770a819436c28,https://www.dropbox.com/s/xfr42op8d1hfvcp/udistrict.bin.zip?dl=0
data/system/maps/west_seattle.bin,6f442a9953eaa988f2cf3cab831f6d3a,https://www.dropbox.com/s/uo2vcor4u632yah/west_seattle.bin.zip?dl=0
data/system/prebaked_results/lakeslice/weekday.bin,cccb410e168988124699cc780f628a9b,https://www.dropbox.com/s/8s3it8uf3zeak6z/weekday.bin.zip?dl=0
data/system/prebaked_results/montlake/car vs bike contention.bin,1fac82d6dcd567874fd6e0b106956dd9,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.bin.zip?dl=0
data/system/prebaked_results/montlake/weekday.bin,d9d0f312ab3b4aed95584d182958a59f,https://www.dropbox.com/s/x48bf62i0f3y6ln/weekday.bin.zip?dl=0
data/system/scenarios/ballard/weekday.bin,b643ac85bdb1a0d2067b7f0ca08f9248,https://www.dropbox.com/s/i8l5i9q2evz4kzy/weekday.bin.zip?dl=0
data/system/scenarios/downtown/weekday.bin,0ce7e00c4a32fa20e91dd8049e83288d,https://www.dropbox.com/s/2jnwmkb0z9d3pqw/weekday.bin.zip?dl=0
data/system/scenarios/huge_seattle/weekday.bin,0a5f101968b473dff447c9090bc9e274,https://www.dropbox.com/s/j8u7mrt1edfjgop/weekday.bin.zip?dl=0
data/system/scenarios/lakeslice/weekday.bin,e719fb37ffaecd29bb1945f669a9d212,https://www.dropbox.com/s/s9nag39x2aevkmm/weekday.bin.zip?dl=0
data/system/scenarios/montlake/weekday.bin,0e39abde9289d4ab82f530ad9367bb15,https://www.dropbox.com/s/kjy9prda31i5xgq/weekday.bin.zip?dl=0
data/system/scenarios/south_seattle/weekday.bin,2dad84b9213bdddbb1846ac3ecd94ab1,https://www.dropbox.com/s/geedwniehvkg2re/weekday.bin.zip?dl=0
data/system/prebaked_results/montlake/weekday.bin,10a089af778e3957ffda89151e9971fe,https://www.dropbox.com/s/d9vaadszql9gyn2/weekday.bin.zip?dl=0
data/system/scenarios/ballard/weekday.bin,64e07e8495434fde9bc99a5d481b8ead,https://www.dropbox.com/s/flh757ze5igtb5p/weekday.bin.zip?dl=0
data/system/scenarios/downtown/weekday.bin,937fe27b880d075bbc63673c6543f9b3,https://www.dropbox.com/s/6ab09pv8ndi8i5v/weekday.bin.zip?dl=0
data/system/scenarios/huge_seattle/weekday.bin,73ec916766633dfc2fcd10ac22a55df0,https://www.dropbox.com/s/8hgzab1txzkz340/weekday.bin.zip?dl=0
data/system/scenarios/lakeslice/weekday.bin,79af2b46af2cf18a24b1c53fa75864c7,https://www.dropbox.com/s/ees3fcyp1zqkfx0/weekday.bin.zip?dl=0
data/system/scenarios/montlake/weekday.bin,23bf55ed80a74f43adf7f4bbd7d8c0d4,https://www.dropbox.com/s/78msvkwuzysjer0/weekday.bin.zip?dl=0
data/system/scenarios/south_seattle/weekday.bin,cf27893bacdfa48aabd133fdb567b37c,https://www.dropbox.com/s/goa58gwa6jw9f2j/weekday.bin.zip?dl=0
data/system/scenarios/udistrict/weekday.bin,d0ec3d859a1067ef5c970b6ad2252b5f,https://www.dropbox.com/s/2y0coqhbucq4pr2/weekday.bin.zip?dl=0
data/system/scenarios/west_seattle/weekday.bin,e21aa39e89f3e08d239bed9829643988,https://www.dropbox.com/s/b1xiyu6rfobq0v7/weekday.bin.zip?dl=0
data/system/scenarios/west_seattle/weekday.bin,d2d32536ecad8e06c709838549fda225,https://www.dropbox.com/s/tf3q8asn9du2n6s/weekday.bin.zip?dl=0

View File

@ -2,6 +2,7 @@ use crate::make::initial::lane_specs::get_lane_types;
use crate::{osm, AreaType, IntersectionType, MapConfig, RoadSpec};
use abstutil::{deserialize_btreemap, serialize_btreemap, Timer};
use geom::{Angle, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D};
use petgraph::graphmap::DiGraphMap;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
use std::fmt;
@ -291,6 +292,34 @@ impl RawMap {
Some(fixed)
}
pub fn closest_intersection(&self, pt: Pt2D) -> OriginalIntersection {
self.intersections
.iter()
.min_by_key(|(_, i)| i.point.dist_to(pt))
.map(|(id, _)| *id)
.unwrap()
}
pub fn path_dist_to(
&self,
from: OriginalIntersection,
to: OriginalIntersection,
) -> Option<Distance> {
let mut graph = DiGraphMap::new();
for (id, r) in &self.roads {
graph.add_edge(id.i1, id.i2, id);
if !r.osm_tags.contains_key("oneway") {
graph.add_edge(id.i2, id.i1, id);
}
}
petgraph::algo::dijkstra(&graph, from, Some(to), |(_, _, r)| {
// TODO Expensive!
PolyLine::unchecked_new(self.roads[r].center_points.clone()).length()
})
.get(&to)
.cloned()
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]