mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
Remove the weird shifting/angle inversions from DrivingSide. First step
of #311. Tested to not break righthand maps.
This commit is contained in:
parent
9be79f6e2d
commit
f610c66572
@ -60,17 +60,11 @@ fn use_parking_hints(map: &mut RawMap, path: String, timer: &mut Timer) {
|
|||||||
let center = PolyLine::must_new(r.center_points.clone());
|
let center = PolyLine::must_new(r.center_points.clone());
|
||||||
closest.add(
|
closest.add(
|
||||||
(*id, true),
|
(*id, true),
|
||||||
map.config
|
center.must_shift_right(DIRECTED_ROAD_THICKNESS).points(),
|
||||||
.driving_side
|
|
||||||
.must_right_shift(center.clone(), DIRECTED_ROAD_THICKNESS)
|
|
||||||
.points(),
|
|
||||||
);
|
);
|
||||||
closest.add(
|
closest.add(
|
||||||
(*id, false),
|
(*id, false),
|
||||||
map.config
|
center.must_shift_left(DIRECTED_ROAD_THICKNESS).points(),
|
||||||
.driving_side
|
|
||||||
.must_left_shift(center, DIRECTED_ROAD_THICKNESS)
|
|
||||||
.points(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,12 +417,14 @@ impl ChangeWay {
|
|||||||
let r = map.get_r(*id);
|
let r = map.get_r(*id);
|
||||||
batch.push(
|
batch.push(
|
||||||
Color::GREEN,
|
Color::GREEN,
|
||||||
map.must_right_shift(r.center_pts.clone(), r.get_half_width(map))
|
r.center_pts
|
||||||
|
.must_shift_right(r.get_half_width(map))
|
||||||
.make_polygons(thickness),
|
.make_polygons(thickness),
|
||||||
);
|
);
|
||||||
batch.push(
|
batch.push(
|
||||||
Color::BLUE,
|
Color::BLUE,
|
||||||
map.must_left_shift(r.center_pts.clone(), r.get_half_width(map))
|
r.center_pts
|
||||||
|
.must_shift_left(r.get_half_width(map))
|
||||||
.make_polygons(thickness),
|
.make_polygons(thickness),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -101,13 +101,11 @@ impl DrawIntersection {
|
|||||||
// TODO warn
|
// TODO warn
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let last_line = map.right_shift_line(
|
let last_line = rightmost
|
||||||
rightmost
|
.lane_center_pts
|
||||||
.lane_center_pts
|
.exact_slice(Distance::ZERO, rightmost.length() - trim_back)
|
||||||
.exact_slice(Distance::ZERO, rightmost.length() - trim_back)
|
.last_line()
|
||||||
.last_line(),
|
.shift_right(rightmost.width);
|
||||||
rightmost.width,
|
|
||||||
);
|
|
||||||
|
|
||||||
let octagon = make_octagon(last_line.pt2(), Distance::meters(1.0), last_line.angle());
|
let octagon = make_octagon(last_line.pt2(), Distance::meters(1.0), last_line.angle());
|
||||||
let pole = Line::must_new(
|
let pole = Line::must_new(
|
||||||
@ -214,20 +212,18 @@ pub fn calculate_corners(i: &Intersection, map: &Map) -> Vec<Polygon> {
|
|||||||
let l2 = map.get_l(turn.id.dst);
|
let l2 = map.get_l(turn.id.dst);
|
||||||
|
|
||||||
if let Some(poly) = (|| {
|
if let Some(poly) = (|| {
|
||||||
let mut pts = map
|
let mut pts = turn.geom.shift_left(width / 2.0).ok()?.into_points();
|
||||||
.left_shift(turn.geom.clone(), width / 2.0)
|
pts.push(l2.first_line().shift_left(width / 2.0).pt1());
|
||||||
.ok()?
|
pts.push(l2.first_line().shift_right(width / 2.0).pt1());
|
||||||
.into_points();
|
|
||||||
pts.push(map.left_shift_line(l2.first_line(), width / 2.0).pt1());
|
|
||||||
pts.push(map.right_shift_line(l2.first_line(), width / 2.0).pt1());
|
|
||||||
pts.extend(
|
pts.extend(
|
||||||
map.right_shift(turn.geom.clone(), width / 2.0)
|
turn.geom
|
||||||
|
.shift_right(width / 2.0)
|
||||||
.ok()?
|
.ok()?
|
||||||
.reversed()
|
.reversed()
|
||||||
.into_points(),
|
.into_points(),
|
||||||
);
|
);
|
||||||
pts.push(map.right_shift_line(l1.last_line(), width / 2.0).pt2());
|
pts.push(l1.last_line().shift_right(width / 2.0).pt2());
|
||||||
pts.push(map.left_shift_line(l1.last_line(), width / 2.0).pt2());
|
pts.push(l1.last_line().shift_left(width / 2.0).pt2());
|
||||||
pts.push(pts[0]);
|
pts.push(pts[0]);
|
||||||
Some(Polygon::buggy_new(pts))
|
Some(Polygon::buggy_new(pts))
|
||||||
})() {
|
})() {
|
||||||
@ -259,15 +255,11 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, map: &Map) -> Vec<Polygon
|
|||||||
if !i.outgoing_lanes.is_empty() {
|
if !i.outgoing_lanes.is_empty() {
|
||||||
let (line, width) = if r.dst_i == i.id {
|
let (line, width) = if r.dst_i == i.id {
|
||||||
(
|
(
|
||||||
map.left_shift_line(center.last_line(), width_back / 2.0)
|
center.last_line().shift_left(width_back / 2.0).reverse(),
|
||||||
.reverse(),
|
|
||||||
width_back,
|
width_back,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(center.first_line().shift_right(width_fwd / 2.0), width_fwd)
|
||||||
map.right_shift_line(center.first_line(), width_fwd / 2.0),
|
|
||||||
width_fwd,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
result.push(
|
result.push(
|
||||||
// DEGENERATE_INTERSECTION_HALF_LENGTH is 2.5m...
|
// DEGENERATE_INTERSECTION_HALF_LENGTH is 2.5m...
|
||||||
@ -283,15 +275,11 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, map: &Map) -> Vec<Polygon
|
|||||||
if !i.incoming_lanes.is_empty() {
|
if !i.incoming_lanes.is_empty() {
|
||||||
let (line, width) = if r.dst_i == i.id {
|
let (line, width) = if r.dst_i == i.id {
|
||||||
(
|
(
|
||||||
map.right_shift_line(center.last_line(), width_fwd / 2.0)
|
center.last_line().shift_right(width_fwd / 2.0).reverse(),
|
||||||
.reverse(),
|
|
||||||
width_fwd,
|
width_fwd,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(center.first_line().shift_left(width_back / 2.0), width_back)
|
||||||
map.left_shift_line(center.first_line(), width_back / 2.0),
|
|
||||||
width_back,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
result.push(
|
result.push(
|
||||||
PolyLine::must_new(vec![
|
PolyLine::must_new(vec![
|
||||||
|
@ -58,15 +58,12 @@ impl DrawLane {
|
|||||||
}
|
}
|
||||||
LaneType::Shoulder => {}
|
LaneType::Shoulder => {}
|
||||||
LaneType::Parking => {
|
LaneType::Parking => {
|
||||||
draw.extend(
|
draw.extend(app.cs.general_road_marking, calculate_parking_lines(lane));
|
||||||
app.cs.general_road_marking,
|
|
||||||
calculate_parking_lines(map, lane),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
LaneType::Driving | LaneType::Bus => {
|
LaneType::Driving | LaneType::Bus => {
|
||||||
draw.extend(
|
draw.extend(
|
||||||
app.cs.general_road_marking,
|
app.cs.general_road_marking,
|
||||||
calculate_driving_lines(map, lane, road),
|
calculate_driving_lines(lane, road),
|
||||||
);
|
);
|
||||||
draw.extend(
|
draw.extend(
|
||||||
app.cs.general_road_marking,
|
app.cs.general_road_marking,
|
||||||
@ -249,7 +246,7 @@ fn calculate_sidewalk_lines(lane: &Lane) -> Vec<Polygon> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_parking_lines(map: &Map, lane: &Lane) -> Vec<Polygon> {
|
fn calculate_parking_lines(lane: &Lane) -> Vec<Polygon> {
|
||||||
// meters, but the dims get annoying below to remove
|
// meters, but the dims get annoying below to remove
|
||||||
let leg_length = Distance::meters(1.0);
|
let leg_length = Distance::meters(1.0);
|
||||||
|
|
||||||
@ -260,7 +257,7 @@ fn calculate_parking_lines(map: &Map, lane: &Lane) -> Vec<Polygon> {
|
|||||||
let (pt, lane_angle) = lane
|
let (pt, lane_angle) = lane
|
||||||
.lane_center_pts
|
.lane_center_pts
|
||||||
.must_dist_along(PARKING_SPOT_LENGTH * (1.0 + idx as f64));
|
.must_dist_along(PARKING_SPOT_LENGTH * (1.0 + idx as f64));
|
||||||
let perp_angle = map.driving_side_angle(lane_angle.rotate_degs(270.0));
|
let perp_angle = lane_angle.rotate_degs(270.0);
|
||||||
// Find the outside of the lane. Actually, shift inside a little bit, since the line
|
// Find the outside of the lane. Actually, shift inside a little bit, since the line
|
||||||
// will have thickness, but shouldn't really intersect the adjacent line
|
// will have thickness, but shouldn't really intersect the adjacent line
|
||||||
// when drawn.
|
// when drawn.
|
||||||
@ -283,7 +280,7 @@ fn calculate_parking_lines(map: &Map, lane: &Lane) -> Vec<Polygon> {
|
|||||||
// Because the stripe straddles two lanes, it'll be partly hidden on one side. There are a bunch of
|
// Because the stripe straddles two lanes, it'll be partly hidden on one side. There are a bunch of
|
||||||
// ways to work around this z-order issue. The current approach is to rely on the fact that
|
// ways to work around this z-order issue. The current approach is to rely on the fact that
|
||||||
// quadtrees return LaneIDs in order, and lanes are always created from left->right.
|
// quadtrees return LaneIDs in order, and lanes are always created from left->right.
|
||||||
fn calculate_driving_lines(map: &Map, lane: &Lane, parent: &Road) -> Vec<Polygon> {
|
fn calculate_driving_lines(lane: &Lane, parent: &Road) -> Vec<Polygon> {
|
||||||
let lanes = parent.lanes_ltr();
|
let lanes = parent.lanes_ltr();
|
||||||
let idx = parent.offset(lane.id);
|
let idx = parent.offset(lane.id);
|
||||||
|
|
||||||
@ -294,9 +291,9 @@ fn calculate_driving_lines(map: &Map, lane: &Lane, parent: &Road) -> Vec<Polygon
|
|||||||
}
|
}
|
||||||
|
|
||||||
let lane_edge_pts = if lanes[idx].1 == Direction::Fwd {
|
let lane_edge_pts = if lanes[idx].1 == Direction::Fwd {
|
||||||
map.must_left_shift(lane.lane_center_pts.clone(), lane.width / 2.0)
|
lane.lane_center_pts.must_shift_left(lane.width / 2.0)
|
||||||
} else {
|
} else {
|
||||||
map.must_right_shift(lane.lane_center_pts.clone(), lane.width / 2.0)
|
lane.lane_center_pts.must_shift_right(lane.width / 2.0)
|
||||||
};
|
};
|
||||||
lane_edge_pts.dashed_lines(
|
lane_edge_pts.dashed_lines(
|
||||||
Distance::meters(0.25),
|
Distance::meters(0.25),
|
||||||
|
@ -206,9 +206,9 @@ impl DrawPedCrowd {
|
|||||||
PedCrowdLocation::Sidewalk(on, contraflow) => {
|
PedCrowdLocation::Sidewalk(on, contraflow) => {
|
||||||
let pl_slice = on.exact_slice(input.low, input.high, map);
|
let pl_slice = on.exact_slice(input.low, input.high, map);
|
||||||
if contraflow {
|
if contraflow {
|
||||||
map.left_shift(pl_slice, SIDEWALK_THICKNESS / 4.0)
|
pl_slice.shift_left(SIDEWALK_THICKNESS / 4.0)
|
||||||
} else {
|
} else {
|
||||||
map.right_shift(pl_slice, SIDEWALK_THICKNESS / 4.0)
|
pl_slice.shift_right(SIDEWALK_THICKNESS / 4.0)
|
||||||
}
|
}
|
||||||
.unwrap_or_else(|_| on.exact_slice(input.low, input.high, map))
|
.unwrap_or_else(|_| on.exact_slice(input.low, input.high, map))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::make::initial::{Intersection, Road};
|
use crate::make::initial::{Intersection, Road};
|
||||||
use crate::osm;
|
use crate::osm;
|
||||||
use crate::raw::{DrivingSide, OriginalRoad};
|
use crate::raw::OriginalRoad;
|
||||||
use abstutil::{wraparound_get, Timer};
|
use abstutil::{wraparound_get, Timer};
|
||||||
use geom::{Circle, Distance, Line, PolyLine, Polygon, Pt2D, Ring, EPSILON_DIST};
|
use geom::{Circle, Distance, Line, PolyLine, Polygon, Pt2D, Ring, EPSILON_DIST};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
@ -11,7 +11,6 @@ const DEGENERATE_INTERSECTION_HALF_LENGTH: Distance = Distance::const_meters(2.5
|
|||||||
// carves up part of that space, doesn't reach past it.
|
// carves up part of that space, doesn't reach past it.
|
||||||
// Also returns a list of labeled polygons for debugging.
|
// Also returns a list of labeled polygons for debugging.
|
||||||
pub fn intersection_polygon(
|
pub fn intersection_polygon(
|
||||||
driving_side: DrivingSide,
|
|
||||||
i: &Intersection,
|
i: &Intersection,
|
||||||
roads: &mut BTreeMap<OriginalRoad, Road>,
|
roads: &mut BTreeMap<OriginalRoad, Road>,
|
||||||
timer: &mut Timer,
|
timer: &mut Timer,
|
||||||
@ -35,8 +34,8 @@ pub fn intersection_polygon(
|
|||||||
} else {
|
} else {
|
||||||
panic!("Incident road {} doesn't have an endpoint at {}", id, i.id);
|
panic!("Incident road {} doesn't have an endpoint at {}", id, i.id);
|
||||||
};
|
};
|
||||||
let pl_normal = driving_side.right_shift(pl.clone(), r.half_width)?;
|
let pl_normal = pl.shift_right(r.half_width)?;
|
||||||
let pl_reverse = driving_side.left_shift(pl.clone(), r.half_width)?;
|
let pl_reverse = pl.shift_left(r.half_width)?;
|
||||||
lines.push((*id, pl.last_line(), pl_normal, pl_reverse));
|
lines.push((*id, pl.last_line(), pl_normal, pl_reverse));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,24 +46,23 @@ pub fn intersection_polygon(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if lines.len() == 1 {
|
if lines.len() == 1 {
|
||||||
return deadend(driving_side, roads, i.id, &lines);
|
return deadend(roads, i.id, &lines);
|
||||||
}
|
}
|
||||||
let rollback = lines
|
let rollback = lines
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(r, _, _, _)| (*r, roads[r].trimmed_center_pts.clone()))
|
.map(|(r, _, _, _)| (*r, roads[r].trimmed_center_pts.clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if let Some(result) = on_off_ramp(driving_side, roads, i.id, lines.clone()) {
|
if let Some(result) = on_off_ramp(roads, i.id, lines.clone()) {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
} else {
|
} else {
|
||||||
for (r, trimmed_center_pts) in rollback {
|
for (r, trimmed_center_pts) in rollback {
|
||||||
roads.get_mut(&r).unwrap().trimmed_center_pts = trimmed_center_pts;
|
roads.get_mut(&r).unwrap().trimmed_center_pts = trimmed_center_pts;
|
||||||
}
|
}
|
||||||
generalized_trim_back(driving_side, roads, i.id, &lines, timer)
|
generalized_trim_back(roads, i.id, &lines, timer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generalized_trim_back(
|
fn generalized_trim_back(
|
||||||
driving_side: DrivingSide,
|
|
||||||
roads: &mut BTreeMap<OriginalRoad, Road>,
|
roads: &mut BTreeMap<OriginalRoad, Road>,
|
||||||
i: osm::NodeID,
|
i: osm::NodeID,
|
||||||
lines: &Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
|
lines: &Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
|
||||||
@ -221,27 +219,11 @@ fn generalized_trim_back(
|
|||||||
|
|
||||||
// Shift those final centers out again to find the main endpoints for the polygon.
|
// Shift those final centers out again to find the main endpoints for the polygon.
|
||||||
if r.dst_i == i {
|
if r.dst_i == i {
|
||||||
endpoints.push(
|
endpoints.push(r.trimmed_center_pts.shift_right(r.half_width)?.last_pt());
|
||||||
driving_side
|
endpoints.push(r.trimmed_center_pts.shift_left(r.half_width)?.last_pt());
|
||||||
.right_shift(r.trimmed_center_pts.clone(), r.half_width)?
|
|
||||||
.last_pt(),
|
|
||||||
);
|
|
||||||
endpoints.push(
|
|
||||||
driving_side
|
|
||||||
.left_shift(r.trimmed_center_pts.clone(), r.half_width)?
|
|
||||||
.last_pt(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
endpoints.push(
|
endpoints.push(r.trimmed_center_pts.shift_left(r.half_width)?.first_pt());
|
||||||
driving_side
|
endpoints.push(r.trimmed_center_pts.shift_right(r.half_width)?.first_pt());
|
||||||
.left_shift(r.trimmed_center_pts.clone(), r.half_width)?
|
|
||||||
.first_pt(),
|
|
||||||
);
|
|
||||||
endpoints.push(
|
|
||||||
driving_side
|
|
||||||
.right_shift(r.trimmed_center_pts.clone(), r.half_width)?
|
|
||||||
.first_pt(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if back_pl.length() >= EPSILON_DIST * 3.0 && adj_back_pl.length() >= EPSILON_DIST * 3.0 {
|
if back_pl.length() >= EPSILON_DIST * 3.0 && adj_back_pl.length() >= EPSILON_DIST * 3.0 {
|
||||||
@ -291,7 +273,6 @@ fn generalized_trim_back(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deadend(
|
fn deadend(
|
||||||
driving_side: DrivingSide,
|
|
||||||
roads: &mut BTreeMap<OriginalRoad, Road>,
|
roads: &mut BTreeMap<OriginalRoad, Road>,
|
||||||
i: osm::NodeID,
|
i: osm::NodeID,
|
||||||
lines: &Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
|
lines: &Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
|
||||||
@ -335,23 +316,11 @@ fn deadend(
|
|||||||
// TODO Refactor with generalized_trim_back.
|
// TODO Refactor with generalized_trim_back.
|
||||||
let mut endpts = vec![pl_b.last_pt(), pl_a.last_pt()];
|
let mut endpts = vec![pl_b.last_pt(), pl_a.last_pt()];
|
||||||
if r.dst_i == i {
|
if r.dst_i == i {
|
||||||
endpts.push(
|
endpts.push(trimmed.shift_right(r.half_width)?.last_pt());
|
||||||
driving_side
|
endpts.push(trimmed.shift_left(r.half_width)?.last_pt());
|
||||||
.right_shift(trimmed.clone(), r.half_width)?
|
|
||||||
.last_pt(),
|
|
||||||
);
|
|
||||||
endpts.push(
|
|
||||||
driving_side
|
|
||||||
.left_shift(trimmed.clone(), r.half_width)?
|
|
||||||
.last_pt(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
endpts.push(
|
endpts.push(trimmed.shift_left(r.half_width)?.first_pt());
|
||||||
driving_side
|
endpts.push(trimmed.shift_right(r.half_width)?.first_pt());
|
||||||
.left_shift(trimmed.clone(), r.half_width)?
|
|
||||||
.first_pt(),
|
|
||||||
);
|
|
||||||
endpts.push(driving_side.right_shift(trimmed, r.half_width)?.first_pt());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
endpts.dedup();
|
endpts.dedup();
|
||||||
@ -379,7 +348,6 @@ struct Piece {
|
|||||||
|
|
||||||
// Try to apply to any 3-way. Might fail for many reasons.
|
// Try to apply to any 3-way. Might fail for many reasons.
|
||||||
fn on_off_ramp(
|
fn on_off_ramp(
|
||||||
driving_side: DrivingSide,
|
|
||||||
roads: &mut BTreeMap<OriginalRoad, Road>,
|
roads: &mut BTreeMap<OriginalRoad, Road>,
|
||||||
i: osm::NodeID,
|
i: osm::NodeID,
|
||||||
lines: Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
|
lines: Vec<(OriginalRoad, Line, PolyLine, PolyLine)>,
|
||||||
@ -556,27 +524,27 @@ fn on_off_ramp(
|
|||||||
// Shift those final centers out again to find the main endpoints for the polygon.
|
// Shift those final centers out again to find the main endpoints for the polygon.
|
||||||
if r.dst_i == i {
|
if r.dst_i == i {
|
||||||
endpoints.push(
|
endpoints.push(
|
||||||
driving_side
|
r.trimmed_center_pts
|
||||||
.right_shift(r.trimmed_center_pts.clone(), r.half_width)
|
.shift_right(r.half_width)
|
||||||
.ok()?
|
.ok()?
|
||||||
.last_pt(),
|
.last_pt(),
|
||||||
);
|
);
|
||||||
endpoints.push(
|
endpoints.push(
|
||||||
driving_side
|
r.trimmed_center_pts
|
||||||
.left_shift(r.trimmed_center_pts.clone(), r.half_width)
|
.shift_left(r.half_width)
|
||||||
.ok()?
|
.ok()?
|
||||||
.last_pt(),
|
.last_pt(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
endpoints.push(
|
endpoints.push(
|
||||||
driving_side
|
r.trimmed_center_pts
|
||||||
.left_shift(r.trimmed_center_pts.clone(), r.half_width)
|
.shift_left(r.half_width)
|
||||||
.ok()?
|
.ok()?
|
||||||
.first_pt(),
|
.first_pt(),
|
||||||
);
|
);
|
||||||
endpoints.push(
|
endpoints.push(
|
||||||
driving_side
|
r.trimmed_center_pts
|
||||||
.right_shift(r.trimmed_center_pts.clone(), r.half_width)
|
.shift_right(r.half_width)
|
||||||
.ok()?
|
.ok()?
|
||||||
.first_pt(),
|
.first_pt(),
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@ mod geometry;
|
|||||||
pub mod lane_specs;
|
pub mod lane_specs;
|
||||||
|
|
||||||
pub use self::geometry::intersection_polygon;
|
pub use self::geometry::intersection_polygon;
|
||||||
use crate::raw::{DrivingSide, OriginalRoad, RawMap, RawRoad};
|
use crate::raw::{OriginalRoad, RawMap, RawRoad};
|
||||||
use crate::{osm, IntersectionType};
|
use crate::{osm, IntersectionType};
|
||||||
use abstutil::{Tags, Timer};
|
use abstutil::{Tags, Timer};
|
||||||
use geom::{Bounds, Circle, Distance, PolyLine, Polygon, Pt2D};
|
use geom::{Bounds, Circle, Distance, PolyLine, Polygon, Pt2D};
|
||||||
@ -29,9 +29,9 @@ pub struct Road {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Road {
|
impl Road {
|
||||||
pub fn new(id: OriginalRoad, r: &RawRoad, driving_side: DrivingSide) -> Road {
|
pub fn new(id: OriginalRoad, r: &RawRoad) -> Road {
|
||||||
let lane_specs_ltr = lane_specs::get_lane_specs_ltr(&r.osm_tags);
|
let lane_specs_ltr = lane_specs::get_lane_specs_ltr(&r.osm_tags);
|
||||||
let (trimmed_center_pts, total_width) = r.get_geometry(id, driving_side);
|
let (trimmed_center_pts, total_width) = r.get_geometry(id);
|
||||||
|
|
||||||
Road {
|
Road {
|
||||||
id,
|
id,
|
||||||
@ -89,14 +89,13 @@ impl InitialMap {
|
|||||||
m.intersections.get_mut(&id.i1).unwrap().roads.insert(*id);
|
m.intersections.get_mut(&id.i1).unwrap().roads.insert(*id);
|
||||||
m.intersections.get_mut(&id.i2).unwrap().roads.insert(*id);
|
m.intersections.get_mut(&id.i2).unwrap().roads.insert(*id);
|
||||||
|
|
||||||
m.roads
|
m.roads.insert(*id, Road::new(*id, r));
|
||||||
.insert(*id, Road::new(*id, r, raw.config.driving_side));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.start_iter("find each intersection polygon", m.intersections.len());
|
timer.start_iter("find each intersection polygon", m.intersections.len());
|
||||||
for i in m.intersections.values_mut() {
|
for i in m.intersections.values_mut() {
|
||||||
timer.next();
|
timer.next();
|
||||||
match intersection_polygon(raw.config.driving_side, i, &mut m.roads, timer) {
|
match intersection_polygon(i, &mut m.roads, timer) {
|
||||||
Ok((poly, _)) => {
|
Ok((poly, _)) => {
|
||||||
i.polygon = poly;
|
i.polygon = poly;
|
||||||
}
|
}
|
||||||
@ -142,9 +141,7 @@ impl InitialMap {
|
|||||||
.extend_to_length(min_len)
|
.extend_to_length(min_len)
|
||||||
.reversed();
|
.reversed();
|
||||||
}
|
}
|
||||||
i.polygon = intersection_polygon(raw.config.driving_side, i, &mut m.roads, timer)
|
i.polygon = intersection_polygon(i, &mut m.roads, timer).unwrap().0;
|
||||||
.unwrap()
|
|
||||||
.0;
|
|
||||||
timer.note(format!(
|
timer.note(format!(
|
||||||
"Shifted border {} out a bit to make the road a reasonable length",
|
"Shifted border {} out a bit to make the road a reasonable length",
|
||||||
i.id
|
i.id
|
||||||
|
@ -138,8 +138,9 @@ impl Map {
|
|||||||
}
|
}
|
||||||
// TODO Maybe easier to use the road's "yellow center line" and shift left/right from
|
// TODO Maybe easier to use the road's "yellow center line" and shift left/right from
|
||||||
// there.
|
// there.
|
||||||
let road_left_pts = map
|
let road_left_pts = road
|
||||||
.left_shift(road.center_pts.clone(), r.half_width)
|
.center_pts
|
||||||
|
.shift_left(r.half_width)
|
||||||
.unwrap_or_else(|_| road.center_pts.clone());
|
.unwrap_or_else(|_| road.center_pts.clone());
|
||||||
|
|
||||||
let mut width_so_far = Distance::ZERO;
|
let mut width_so_far = Distance::ZERO;
|
||||||
@ -156,14 +157,13 @@ impl Map {
|
|||||||
|
|
||||||
road.lanes_ltr.push((id, lane.dir, lane.lt));
|
road.lanes_ltr.push((id, lane.dir, lane.lt));
|
||||||
|
|
||||||
let pl = if let Ok(pl) =
|
let pl =
|
||||||
map.right_shift(road_left_pts.clone(), width_so_far + (lane.width / 2.0))
|
if let Ok(pl) = road_left_pts.shift_right(width_so_far + (lane.width / 2.0)) {
|
||||||
{
|
pl
|
||||||
pl
|
} else {
|
||||||
} else {
|
timer.error(format!("{} geometry broken; lane not shifted!", id));
|
||||||
timer.error(format!("{} geometry broken; lane not shifted!", id));
|
road_left_pts.clone()
|
||||||
road_left_pts.clone()
|
};
|
||||||
};
|
|
||||||
let lane_center_pts = if lane.dir == Direction::Fwd {
|
let lane_center_pts = if lane.dir == Direction::Fwd {
|
||||||
pl
|
pl
|
||||||
} else {
|
} else {
|
||||||
|
@ -359,12 +359,8 @@ fn make_shared_sidewalk_corner(
|
|||||||
|
|
||||||
// Find all of the points on the intersection polygon between the two sidewalks. Assumes
|
// Find all of the points on the intersection polygon between the two sidewalks. Assumes
|
||||||
// sidewalks are the same length.
|
// sidewalks are the same length.
|
||||||
let corner1 = driving_side
|
let corner1 = l1.last_line().shift_right(l1.width / 2.0).pt2();
|
||||||
.right_shift_line(l1.last_line(), l1.width / 2.0)
|
let corner2 = l2.first_line().shift_right(l2.width / 2.0).pt1();
|
||||||
.pt2();
|
|
||||||
let corner2 = driving_side
|
|
||||||
.right_shift_line(l2.first_line(), l2.width / 2.0)
|
|
||||||
.pt1();
|
|
||||||
|
|
||||||
// TODO Something like this will be MUCH simpler and avoid going around the long way sometimes.
|
// TODO Something like this will be MUCH simpler and avoid going around the long way sometimes.
|
||||||
if false {
|
if false {
|
||||||
@ -393,8 +389,8 @@ fn make_shared_sidewalk_corner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pts_between.extend(
|
pts_between.extend(
|
||||||
driving_side
|
PolyLine::must_new(deduped)
|
||||||
.must_right_shift(PolyLine::must_new(deduped), l1.width.min(l2.width) / 2.0)
|
.must_shift_right(l1.width.min(l2.width) / 2.0)
|
||||||
.points(),
|
.points(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
PathConstraints, PathRequest, Pathfinder, Position, Road, RoadID, Turn, TurnID, TurnType, Zone,
|
PathConstraints, PathRequest, Pathfinder, Position, Road, RoadID, Turn, TurnID, TurnType, Zone,
|
||||||
};
|
};
|
||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
use geom::{Angle, Bounds, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D, Ring, Time};
|
use geom::{Bounds, GPSBounds, Polygon, Pt2D, Ring, Time};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
|
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
|
||||||
|
|
||||||
@ -585,32 +585,6 @@ impl Map {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn right_shift(&self, pl: PolyLine, width: Distance) -> Result<PolyLine, String> {
|
|
||||||
self.config.driving_side.right_shift(pl, width)
|
|
||||||
}
|
|
||||||
pub fn must_right_shift(&self, pl: PolyLine, width: Distance) -> PolyLine {
|
|
||||||
self.right_shift(pl, width).unwrap()
|
|
||||||
}
|
|
||||||
pub fn left_shift(&self, pl: PolyLine, width: Distance) -> Result<PolyLine, String> {
|
|
||||||
self.config.driving_side.left_shift(pl, width)
|
|
||||||
}
|
|
||||||
pub fn must_left_shift(&self, pl: PolyLine, width: Distance) -> PolyLine {
|
|
||||||
self.left_shift(pl, width).unwrap()
|
|
||||||
}
|
|
||||||
pub fn right_shift_line(&self, line: Line, width: Distance) -> Line {
|
|
||||||
self.config.driving_side.right_shift_line(line, width)
|
|
||||||
}
|
|
||||||
pub fn left_shift_line(&self, line: Line, width: Distance) -> Line {
|
|
||||||
self.config.driving_side.left_shift_line(line, width)
|
|
||||||
}
|
|
||||||
pub fn driving_side_angle(&self, a: Angle) -> Angle {
|
|
||||||
self.config.driving_side.angle_offset(a)
|
|
||||||
}
|
|
||||||
// Last resort
|
|
||||||
pub fn get_driving_side(&self) -> DrivingSide {
|
|
||||||
self.config.driving_side
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Sort of a temporary hack
|
// TODO Sort of a temporary hack
|
||||||
pub fn hack_override_offstreet_spots(&mut self, spots_per_bldg: usize) {
|
pub fn hack_override_offstreet_spots(&mut self, spots_per_bldg: usize) {
|
||||||
for b in &mut self.buildings {
|
for b in &mut self.buildings {
|
||||||
|
@ -297,7 +297,9 @@ impl Movement {
|
|||||||
left = right;
|
left = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pl = map.must_right_shift(r.get_left_side(map), (leftmost + rightmost) / 2.0);
|
let mut pl = r
|
||||||
|
.get_left_side(map)
|
||||||
|
.must_shift_right((leftmost + rightmost) / 2.0);
|
||||||
if self.id.from.dir == Direction::Back {
|
if self.id.from.dir == Direction::Back {
|
||||||
pl = pl.reversed();
|
pl = pl.reversed();
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,9 @@ impl UberTurnGroup {
|
|||||||
left = right;
|
left = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pl = map.must_right_shift(r.get_left_side(map), (leftmost + rightmost) / 2.0);
|
let mut pl = r
|
||||||
|
.get_left_side(map)
|
||||||
|
.must_shift_right((leftmost + rightmost) / 2.0);
|
||||||
// Point towards the intersection
|
// Point towards the intersection
|
||||||
if self.from.dir == Direction::Back {
|
if self.from.dir == Direction::Back {
|
||||||
pl = pl.reversed();
|
pl = pl.reversed();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::make::initial::lane_specs::get_lane_specs_ltr;
|
use crate::make::initial::lane_specs::get_lane_specs_ltr;
|
||||||
use crate::{osm, AreaType, Direction, IntersectionType, LaneType, MapConfig, NamePerLanguage};
|
use crate::{osm, AreaType, Direction, IntersectionType, LaneType, MapConfig, NamePerLanguage};
|
||||||
use abstutil::{deserialize_btreemap, serialize_btreemap, Tags, Timer};
|
use abstutil::{deserialize_btreemap, serialize_btreemap, Tags, Timer};
|
||||||
use geom::{Angle, Circle, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D};
|
use geom::{Circle, Distance, GPSBounds, PolyLine, Polygon, Pt2D};
|
||||||
use petgraph::graphmap::DiGraphMap;
|
use petgraph::graphmap::DiGraphMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
@ -153,14 +153,10 @@ impl RawMap {
|
|||||||
};
|
};
|
||||||
let mut roads = BTreeMap::new();
|
let mut roads = BTreeMap::new();
|
||||||
for r in &i.roads {
|
for r in &i.roads {
|
||||||
roads.insert(
|
roads.insert(*r, initial::Road::new(*r, &self.roads[r]));
|
||||||
*r,
|
|
||||||
initial::Road::new(*r, &self.roads[r], self.config.driving_side),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (poly, debug) =
|
let (poly, debug) = initial::intersection_polygon(&i, &mut roads, timer).unwrap();
|
||||||
initial::intersection_polygon(self.config.driving_side, &i, &mut roads, timer).unwrap();
|
|
||||||
(
|
(
|
||||||
poly,
|
poly,
|
||||||
roads
|
roads
|
||||||
@ -246,11 +242,7 @@ pub struct RawRoad {
|
|||||||
|
|
||||||
impl RawRoad {
|
impl RawRoad {
|
||||||
// Returns the corrected center and half width
|
// Returns the corrected center and half width
|
||||||
pub fn get_geometry(
|
pub fn get_geometry(&self, id: OriginalRoad) -> (PolyLine, Distance) {
|
||||||
&self,
|
|
||||||
id: OriginalRoad,
|
|
||||||
driving_side: DrivingSide,
|
|
||||||
) -> (PolyLine, Distance) {
|
|
||||||
let lane_specs = get_lane_specs_ltr(&self.osm_tags);
|
let lane_specs = get_lane_specs_ltr(&self.osm_tags);
|
||||||
let mut total_width = Distance::ZERO;
|
let mut total_width = Distance::ZERO;
|
||||||
let mut sidewalk_right = None;
|
let mut sidewalk_right = None;
|
||||||
@ -270,10 +262,10 @@ impl RawRoad {
|
|||||||
let mut true_center = PolyLine::new(self.center_points.clone()).expect(&id.to_string());
|
let mut true_center = PolyLine::new(self.center_points.clone()).expect(&id.to_string());
|
||||||
match (sidewalk_right, sidewalk_left) {
|
match (sidewalk_right, sidewalk_left) {
|
||||||
(Some(w), None) => {
|
(Some(w), None) => {
|
||||||
true_center = driving_side.must_right_shift(true_center, w / 2.0);
|
true_center = true_center.must_shift_right(w / 2.0);
|
||||||
}
|
}
|
||||||
(None, Some(w)) => {
|
(None, Some(w)) => {
|
||||||
true_center = driving_side.must_left_shift(true_center, w / 2.0);
|
true_center = true_center.must_shift_right(w / 2.0);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -358,51 +350,6 @@ pub enum DrivingSide {
|
|||||||
Left,
|
Left,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrivingSide {
|
|
||||||
// "right" and "left" here are in terms of DrivingSide::Right, what I'm used to reasoning about
|
|
||||||
// in the USA. They invert appropriately for DrivingSide::Left.
|
|
||||||
pub fn right_shift(self, pl: PolyLine, width: Distance) -> Result<PolyLine, String> {
|
|
||||||
match self {
|
|
||||||
DrivingSide::Right => pl.shift_right(width),
|
|
||||||
DrivingSide::Left => pl.shift_left(width),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn must_right_shift(self, pl: PolyLine, width: Distance) -> PolyLine {
|
|
||||||
self.right_shift(pl, width).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn left_shift(self, pl: PolyLine, width: Distance) -> Result<PolyLine, String> {
|
|
||||||
match self {
|
|
||||||
DrivingSide::Right => pl.shift_left(width),
|
|
||||||
DrivingSide::Left => pl.shift_right(width),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn must_left_shift(self, pl: PolyLine, width: Distance) -> PolyLine {
|
|
||||||
self.left_shift(pl, width).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn right_shift_line(self, line: Line, width: Distance) -> Line {
|
|
||||||
match self {
|
|
||||||
DrivingSide::Right => line.shift_right(width),
|
|
||||||
DrivingSide::Left => line.shift_left(width),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn left_shift_line(self, line: Line, width: Distance) -> Line {
|
|
||||||
match self {
|
|
||||||
DrivingSide::Right => line.shift_left(width),
|
|
||||||
DrivingSide::Left => line.shift_right(width),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn angle_offset(self, a: Angle) -> Angle {
|
|
||||||
match self {
|
|
||||||
DrivingSide::Right => a,
|
|
||||||
DrivingSide::Left => a.opposite(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct RawBusRoute {
|
pub struct RawBusRoute {
|
||||||
pub full_name: String,
|
pub full_name: String,
|
||||||
|
@ -548,10 +548,7 @@ impl Pedestrian {
|
|||||||
orig_angle.opposite()
|
orig_angle.opposite()
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
pos.project_away(
|
pos.project_away(SIDEWALK_THICKNESS / 4.0, facing.rotate_degs(90.0)),
|
||||||
SIDEWALK_THICKNESS / 4.0,
|
|
||||||
map.driving_side_angle(facing.rotate_degs(90.0)),
|
|
||||||
),
|
|
||||||
facing,
|
facing,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -563,10 +560,7 @@ impl Pedestrian {
|
|||||||
orig_angle
|
orig_angle
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
pos.project_away(
|
pos.project_away(SIDEWALK_THICKNESS / 4.0, facing.rotate_degs(90.0)),
|
||||||
SIDEWALK_THICKNESS / 4.0,
|
|
||||||
map.driving_side_angle(facing.rotate_degs(90.0)),
|
|
||||||
),
|
|
||||||
facing,
|
facing,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -620,11 +614,8 @@ impl Pedestrian {
|
|||||||
let (pt, angle) = self.goal.sidewalk_pos.pt_and_angle(map);
|
let (pt, angle) = self.goal.sidewalk_pos.pt_and_angle(map);
|
||||||
// Stand on the far side of the sidewalk (by the bus stop), facing the road
|
// Stand on the far side of the sidewalk (by the bus stop), facing the road
|
||||||
(
|
(
|
||||||
pt.project_away(
|
pt.project_away(SIDEWALK_THICKNESS / 4.0, angle.rotate_degs(90.0)),
|
||||||
SIDEWALK_THICKNESS / 4.0,
|
angle.rotate_degs(-90.0),
|
||||||
map.driving_side_angle(angle.rotate_degs(90.0)),
|
|
||||||
),
|
|
||||||
map.driving_side_angle(angle.rotate_degs(-90.0)),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user