mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 01:15:12 +03:00
more fixes for left-hand maps (#27):
- avoid a crash by deduping intersection polygon points - make shared sidewalk corners saner by flipping order of points - improve crosswalk determination
This commit is contained in:
parent
812c7fa640
commit
be9671a51f
@ -6,6 +6,7 @@ use crate::render::{
|
||||
use abstutil::Timer;
|
||||
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, Text};
|
||||
use geom::{Angle, Distance, Line, PolyLine, Polygon, Pt2D, Time, EPSILON_DIST};
|
||||
use map_model::raw::DrivingSide;
|
||||
use map_model::{
|
||||
Intersection, IntersectionID, IntersectionType, Map, Road, RoadWithStopSign, Turn, TurnType,
|
||||
};
|
||||
@ -205,8 +206,12 @@ pub fn calculate_corners(i: &Intersection, map: &Map, timer: &mut Timer) -> Vec<
|
||||
// Intersection polygons are constructed in clockwise order, so do corner2 to corner1.
|
||||
// TODO This threshold is higher than the 0.1 intersection polygons use to dedupe
|
||||
// because of jagged lane teeth from bad polyline shifting. Seemingly.
|
||||
let mut i_pts = i.polygon.points().clone();
|
||||
if map.get_driving_side() == DrivingSide::Left {
|
||||
i_pts.reverse();
|
||||
}
|
||||
if let Some(mut pts_between) =
|
||||
Pt2D::find_pts_between(&i.polygon.points(), corner2, corner1, Distance::meters(0.5))
|
||||
Pt2D::find_pts_between(&i_pts, corner2, corner1, Distance::meters(0.5))
|
||||
{
|
||||
pts_between.push(src_line.pt2());
|
||||
// If the intersection of the two lines isn't actually inside, then just exclude
|
||||
|
@ -149,6 +149,7 @@ impl Pt2D {
|
||||
result
|
||||
}
|
||||
|
||||
// TODO Try to deprecate in favor of Ring::get_shorter_slice_btwn
|
||||
pub fn find_pts_between(
|
||||
pts: &Vec<Pt2D>,
|
||||
start: Pt2D,
|
||||
|
@ -327,6 +327,7 @@ fn generalized_trim_back(
|
||||
deduped = Pt2D::approx_dedupe(deduped, Distance::meters(0.1));
|
||||
let center = Pt2D::center(&deduped);
|
||||
deduped.sort_by_key(|pt| pt.angle_to(center).normalized_degrees() as i64);
|
||||
deduped = Pt2D::approx_dedupe(deduped, Distance::meters(0.1));
|
||||
deduped = close_off_polygon(deduped);
|
||||
if main_result.len() == deduped.len() {
|
||||
(main_result, debug)
|
||||
|
@ -304,6 +304,14 @@ fn make_walking_turns(
|
||||
.collect();
|
||||
let mut result: Vec<Turn> = Vec::new();
|
||||
|
||||
// I'm a bit confused when to do -1 and +1 honestly, but this works in practice. Angle sorting
|
||||
// may be a little backwards.
|
||||
let idx_offset = if driving_side == DrivingSide::Right {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
if roads.len() == 2 {
|
||||
if let Some(turns) = make_degenerate_crosswalks(i.id, lanes, roads[0], roads[1]) {
|
||||
result.extend(turns);
|
||||
@ -313,7 +321,8 @@ fn make_walking_turns(
|
||||
if let Some(l1) = get_sidewalk(lanes, roads[idx1].incoming_lanes(i.id)) {
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 1).outgoing_lanes(i.id),
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) + idx_offset)
|
||||
.outgoing_lanes(i.id),
|
||||
) {
|
||||
if l1.last_pt() != l2.first_pt() {
|
||||
let geom = make_shared_sidewalk_corner(driving_side, i, l1, l2, timer);
|
||||
@ -360,14 +369,6 @@ fn make_walking_turns(
|
||||
return result;
|
||||
}
|
||||
|
||||
// I'm a bit confused when to do -1 and +1 honestly, but this works in practice. Angle sorting
|
||||
// may be a little backwards.
|
||||
let idx_offset = if driving_side == DrivingSide::Right {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
for idx1 in 0..roads.len() {
|
||||
if let Some(l1) = get_sidewalk(lanes, roads[idx1].incoming_lanes(i.id)) {
|
||||
// Make the crosswalk to the other side
|
||||
@ -399,7 +400,7 @@ fn make_walking_turns(
|
||||
}
|
||||
} else if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 1).incoming_lanes(i.id),
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) + idx_offset).incoming_lanes(i.id),
|
||||
) {
|
||||
// Adjacent road is missing a sidewalk on the near side, but has one on the far
|
||||
// side
|
||||
@ -410,18 +411,21 @@ fn make_walking_turns(
|
||||
// TODO Refactor and loop until we find something to connect it to?
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 2).outgoing_lanes(i.id),
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) + 2 * idx_offset)
|
||||
.outgoing_lanes(i.id),
|
||||
) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
} else if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 2).incoming_lanes(i.id),
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) + 2 * idx_offset)
|
||||
.incoming_lanes(i.id),
|
||||
) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
} else if roads.len() > 3 {
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 3).outgoing_lanes(i.id),
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) + 3 * idx_offset)
|
||||
.outgoing_lanes(i.id),
|
||||
) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
}
|
||||
@ -560,9 +564,11 @@ fn make_shared_sidewalk_corner(
|
||||
// to corner1 below.
|
||||
let mut pts_between = vec![l2.first_pt()];
|
||||
// Intersection polygons are constructed in clockwise order, so do corner2 to corner1.
|
||||
if let Some(pts) =
|
||||
Pt2D::find_pts_between(&i.polygon.points(), corner2, corner1, Distance::meters(0.5))
|
||||
{
|
||||
let mut i_pts = i.polygon.points().clone();
|
||||
if driving_side == DrivingSide::Left {
|
||||
i_pts.reverse();
|
||||
}
|
||||
if let Some(pts) = Pt2D::find_pts_between(&i_pts, corner2, corner1, Distance::meters(0.5)) {
|
||||
let mut deduped = pts.clone();
|
||||
deduped.dedup();
|
||||
if deduped.len() >= 2 {
|
||||
|
@ -672,6 +672,10 @@ impl Map {
|
||||
pub fn left_shift_line(&self, line: Line, width: Distance) -> Line {
|
||||
self.driving_side.left_shift_line(line, width)
|
||||
}
|
||||
// Last resort
|
||||
pub fn get_driving_side(&self) -> DrivingSide {
|
||||
self.driving_side
|
||||
}
|
||||
}
|
||||
|
||||
impl Map {
|
||||
|
Loading…
Reference in New Issue
Block a user