mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
making small_seattle fully convert, with some less messy hacks. added it
as a test!
This commit is contained in:
parent
a3b03952cf
commit
6da48c28c1
@ -43,6 +43,10 @@ pub fn make_all_buildings(
|
||||
let sidewalk_pt = lanes[sidewalk_pos.lane().0]
|
||||
.dist_along(sidewalk_pos.dist_along())
|
||||
.0;
|
||||
if sidewalk_pt.epsilon_eq(bldg_center.into()) {
|
||||
warn!("Skipping a building because front path has 0 length");
|
||||
continue;
|
||||
}
|
||||
let line = trim_front_path(&points, Line::new(bldg_center.into(), sidewalk_pt));
|
||||
|
||||
let id = BuildingID(results.len());
|
||||
|
@ -4,6 +4,11 @@ use abstutil::Timer;
|
||||
use std::collections::{BTreeSet, HashSet};
|
||||
|
||||
pub fn fix_ramps(m: &mut InitialMap, timer: &mut Timer) {
|
||||
if m.roads.len() > 15_000 {
|
||||
error!("Skipping fix_ramps because map is too big! TODO: Optimize me!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Look for road center lines that hit an intersection polygon that isn't one of their
|
||||
// endpoints.
|
||||
timer.start_iter(
|
||||
|
@ -139,11 +139,17 @@ fn generalized_trim_back(
|
||||
// How could something perpendicular to a shifted polyline never hit the original
|
||||
// polyline? Also, find the hit closest to the intersection -- this matters for
|
||||
// very curvy roads, like highway ramps.
|
||||
let trim_to = road_center.reversed().intersection_infinite(&perp).unwrap();
|
||||
let trimmed = road_center.get_slice_ending_at(trim_to).unwrap();
|
||||
if let Some(trimmed) = road_center
|
||||
.reversed()
|
||||
.intersection_infinite(&perp)
|
||||
.and_then(|trim_to| road_center.get_slice_ending_at(trim_to))
|
||||
{
|
||||
if trimmed.length() < shortest_center.length() {
|
||||
shortest_center = trimmed;
|
||||
}
|
||||
} else {
|
||||
warn!("{} and {} hit, but the perpendicular never hit the original center line, or the trimmed thing is empty", r1, r2);
|
||||
}
|
||||
|
||||
// We could also do the update for r2, but we'll just get to it later.
|
||||
}
|
||||
@ -199,6 +205,9 @@ fn generalized_trim_back(
|
||||
// Include collisions between polylines of adjacent roads, so the polygon doesn't cover area
|
||||
// not originally covered by the thick road bands.
|
||||
// It's apparently safe to always take the second_half here.
|
||||
if fwd_pl.length() >= geom::EPSILON_DIST * 3.0
|
||||
&& adj_fwd_pl.length() >= geom::EPSILON_DIST * 3.0
|
||||
{
|
||||
if let Some((hit, _)) = fwd_pl.second_half().intersection(&adj_fwd_pl.second_half()) {
|
||||
endpoints.push(hit);
|
||||
} else if r.original_endpoint(i) != roads[&adj_fwd_id].original_endpoint(i) {
|
||||
@ -206,12 +215,16 @@ fn generalized_trim_back(
|
||||
// TODO This cuts some corners nicely, but also causes lots of problems.
|
||||
// If the original roads didn't end at the same intersection (due to intersection
|
||||
// merging), then use infinite lines.
|
||||
if let Some((hit, _)) = fwd_pl.second_half().intersection(&adj_fwd_pl.second_half())
|
||||
if let Some((hit, _)) =
|
||||
fwd_pl.second_half().intersection(&adj_fwd_pl.second_half())
|
||||
{
|
||||
endpoints.push(hit);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("Excluding collision between original polylines of {} and something, because stuff's too short", id);
|
||||
}
|
||||
|
||||
// Shift those final centers out again to find the main endpoints for the polygon.
|
||||
if r.dst_i == i {
|
||||
@ -222,6 +235,9 @@ fn generalized_trim_back(
|
||||
endpoints.push(r.trimmed_center_pts.shift_right(r.fwd_width).first_pt());
|
||||
}
|
||||
|
||||
if back_pl.length() >= geom::EPSILON_DIST * 3.0
|
||||
&& adj_back_pl.length() >= geom::EPSILON_DIST * 3.0
|
||||
{
|
||||
if let Some((hit, _)) = back_pl
|
||||
.second_half()
|
||||
.intersection(&adj_back_pl.second_half())
|
||||
@ -238,6 +254,9 @@ fn generalized_trim_back(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("Excluding collision between original polylines of {} and something, because stuff's too short", id);
|
||||
}
|
||||
}
|
||||
// TODO Caller will close off the polygon. Does that affect our dedupe?
|
||||
Pt2D::approx_dedupe(endpoints, Distance::meters(0.1))
|
||||
|
@ -8,6 +8,8 @@ use nbez::{Bez3o, BezCurve, Point2d};
|
||||
use std::collections::{BTreeSet, HashSet};
|
||||
use std::iter;
|
||||
|
||||
// TODO Add proper warnings when the geometry is too small to handle.
|
||||
|
||||
pub fn make_all_turns(i: &Intersection, roads: &Vec<Road>, lanes: &Vec<Lane>) -> Vec<Turn> {
|
||||
if i.intersection_type == IntersectionType::Border {
|
||||
return Vec::new();
|
||||
@ -73,7 +75,7 @@ fn make_vehicle_turns(i: &Intersection, all_roads: &Vec<Road>, lanes: &Vec<Lane>
|
||||
lane_types.remove(&LaneType::Parking);
|
||||
lane_types.remove(&LaneType::Sidewalk);
|
||||
|
||||
let mut result = Vec::new();
|
||||
let mut result: Vec<Option<Turn>> = Vec::new();
|
||||
|
||||
for lane_type in lane_types.into_iter() {
|
||||
if i.is_dead_end() {
|
||||
@ -139,7 +141,7 @@ fn make_vehicle_turns(i: &Intersection, all_roads: &Vec<Road>, lanes: &Vec<Lane>
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
result.into_iter().filter_map(|x| x).collect()
|
||||
}
|
||||
|
||||
fn match_up_lanes(
|
||||
@ -147,7 +149,7 @@ fn match_up_lanes(
|
||||
i: IntersectionID,
|
||||
incoming: &Vec<LaneID>,
|
||||
outgoing: &Vec<LaneID>,
|
||||
) -> Vec<Turn> {
|
||||
) -> Vec<Option<Turn>> {
|
||||
let mut result = Vec::new();
|
||||
if incoming.len() < outgoing.len() {
|
||||
// Arbitrarily use the leftmost incoming lane to handle the excess.
|
||||
@ -185,7 +187,7 @@ fn make_vehicle_turns_for_dead_end(
|
||||
roads: &Vec<Road>,
|
||||
lanes: &Vec<Lane>,
|
||||
lane_type: LaneType,
|
||||
) -> Vec<Turn> {
|
||||
) -> Vec<Option<Turn>> {
|
||||
let road = &roads[i.roads.iter().next().unwrap().0];
|
||||
let incoming = filter_vehicle_lanes(road.incoming_lanes(i.id), lane_type);
|
||||
let outgoing = filter_vehicle_lanes(road.outgoing_lanes(i.id), lane_type);
|
||||
@ -219,18 +221,22 @@ fn make_walking_turns(i: &Intersection, all_roads: &Vec<Road>, lanes: &Vec<Lane>
|
||||
lanes,
|
||||
wraparound_get(&roads, (idx1 as isize) - 1).outgoing_lanes(i.id),
|
||||
) {
|
||||
if !l1.last_pt().epsilon_eq(l2.first_pt()) {
|
||||
result.push(Turn {
|
||||
id: turn_id(i.id, l1.id, l2.id),
|
||||
turn_type: TurnType::SharedSidewalkCorner,
|
||||
geom: PolyLine::new(vec![l1.last_pt(), l2.first_pt()]),
|
||||
lookup_idx: 0,
|
||||
});
|
||||
}
|
||||
if !l2.first_pt().epsilon_eq(l1.last_pt()) {
|
||||
result.push(Turn {
|
||||
id: turn_id(i.id, l2.id, l1.id),
|
||||
turn_type: TurnType::SharedSidewalkCorner,
|
||||
geom: PolyLine::new(vec![l2.first_pt(), l1.last_pt()]),
|
||||
lookup_idx: 0,
|
||||
});
|
||||
}
|
||||
} else if roads.len() > 2 {
|
||||
// See if we need to add a crosswalk over this adjacent road.
|
||||
// TODO This is brittle; I could imagine having to cross two adjacent highway
|
||||
@ -249,6 +255,10 @@ fn make_walking_turns(i: &Intersection, all_roads: &Vec<Road>, lanes: &Vec<Lane>
|
||||
}
|
||||
|
||||
fn make_crosswalks(i: IntersectionID, l1: &Lane, l2: &Lane) -> Vec<Turn> {
|
||||
if l1.last_pt().epsilon_eq(l2.first_pt()) {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
// Jut out a bit into the intersection, cross over, then jut back in.
|
||||
let line = Line::new(l1.last_pt(), l2.first_pt()).shift_right(LANE_THICKNESS / 2.0);
|
||||
let geom_fwds = PolyLine::new(vec![l1.last_pt(), line.pt1(), line.pt2(), l2.first_pt()]);
|
||||
@ -297,11 +307,15 @@ fn filter_lanes(lanes: &Vec<(LaneID, LaneType)>, filter: LaneType) -> Vec<LaneID
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn make_vehicle_turn(lanes: &Vec<Lane>, i: IntersectionID, l1: LaneID, l2: LaneID) -> Turn {
|
||||
fn make_vehicle_turn(lanes: &Vec<Lane>, i: IntersectionID, l1: LaneID, l2: LaneID) -> Option<Turn> {
|
||||
let src = &lanes[l1.0];
|
||||
let dst = &lanes[l2.0];
|
||||
let turn_type = TurnType::from_angles(src.last_line().angle(), dst.first_line().angle());
|
||||
|
||||
if src.last_pt().epsilon_eq(dst.first_pt()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let geom = if turn_type == TurnType::Straight {
|
||||
PolyLine::new(vec![src.last_pt(), dst.first_pt()])
|
||||
} else {
|
||||
@ -332,12 +346,12 @@ fn make_vehicle_turn(lanes: &Vec<Lane>, i: IntersectionID, l1: LaneID, l2: LaneI
|
||||
))
|
||||
};
|
||||
|
||||
Turn {
|
||||
Some(Turn {
|
||||
id: turn_id(i, l1, l2),
|
||||
turn_type,
|
||||
geom,
|
||||
lookup_idx: 0,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn to_pt(pt: Pt2D) -> Point2d<f64> {
|
||||
|
@ -85,7 +85,12 @@ impl ControlTrafficSignal {
|
||||
intersection: IntersectionID,
|
||||
) -> Option<ControlTrafficSignal> {
|
||||
if map.get_turns_in_intersection(intersection).is_empty() {
|
||||
panic!("{} has no turns", intersection);
|
||||
error!("{} has no turns", intersection);
|
||||
return Some(ControlTrafficSignal {
|
||||
id: intersection,
|
||||
cycles: Vec::new(),
|
||||
changed: false,
|
||||
});
|
||||
}
|
||||
|
||||
let mut cycles = Vec::new();
|
||||
|
@ -51,21 +51,21 @@ pub fn run(t: &mut TestRunner) {
|
||||
}
|
||||
});
|
||||
|
||||
t.run_slow("bigger_maps", |_| {
|
||||
t.run_slow("bigger_map_loads", |_| {
|
||||
map_model::Map::new(
|
||||
"../data/raw_maps/23rd.abst",
|
||||
map_model::MapEdits::new("23rd"),
|
||||
&mut abstutil::Timer::new("raw to map"),
|
||||
)
|
||||
.expect("23rd broke");
|
||||
});
|
||||
|
||||
// TODO This one has lots more problems (turns with no geometry) and even when the map is
|
||||
// made successfully, can't load it in the UI without OOMing.
|
||||
/*map_model::Map::new(
|
||||
t.run_slow("biggest_map_loads", |_| {
|
||||
map_model::Map::new(
|
||||
"../data/raw_maps/small_seattle.abst",
|
||||
map_model::MapEdits::new("small_seattle"),
|
||||
&mut abstutil::Timer::new("raw to map"),
|
||||
)
|
||||
.expect("small_seattle broke");*/
|
||||
.expect("small_seattle broke");
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user