Merge pull request #5131 from themylogin/master

Fix turn.roads_on_the_left and turn.roads_on_the right for two-way roads
This commit is contained in:
Richard Fairhurst 2021-01-28 14:00:17 +00:00 committed by GitHub
commit 960269f95a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 128 additions and 36 deletions

View File

@ -10,6 +10,7 @@
- Misc: - Misc:
- CHANGED: Cleanup NodeJS dependencies [#5945](https://github.com/Project-OSRM/osrm-backend/pull/5945) - CHANGED: Cleanup NodeJS dependencies [#5945](https://github.com/Project-OSRM/osrm-backend/pull/5945)
- CHANGED: Unify `.osrm.turn_penalites_index` dump processing same with `.osrm.turn_weight_penalties` and `.osrm.turn_duration_penalties` [#5868](https://github.com/Project-OSRM/osrm-backend/pull/5868) - CHANGED: Unify `.osrm.turn_penalites_index` dump processing same with `.osrm.turn_weight_penalties` and `.osrm.turn_duration_penalties` [#5868](https://github.com/Project-OSRM/osrm-backend/pull/5868)
- FIXED: turn.roads_on_the_left not containing incoming roads and turn.roads_on_the_right not containing outgoing roads on two-way roads [#5128](https://github.com/Project-OSRM/osrm-backend/issues/5128)
- Profile: - Profile:
- ADDED: Profile debug script which fetches a way from OSM then outputs the result of the profile. [#5908](https://github.com/Project-OSRM/osrm-backend/pull/5908) - ADDED: Profile debug script which fetches a way from OSM then outputs the result of the profile. [#5908](https://github.com/Project-OSRM/osrm-backend/pull/5908)
- Infrastructure - Infrastructure

View File

@ -180,3 +180,30 @@ Feature: Turn Function Information
And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0/ And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0/
# turning abc, give information about about db # turning abc, give information about about db
And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1/ And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1/
Scenario: Turns should have correct information of two-way roads at intersection
Given the node map
"""
b
|
a-c-d
|
e
"""
And the ways
| nodes | highway | oneway |
| ac | motorway | yes |
| cd | motorway_link | yes |
| bc | trunk | yes |
| cb | trunk_link | yes |
| ce | primary | yes |
| ec | primary_link | yes |
And the data has been saved to disk
When I run "osrm-extract --profile {profile_file} {osm_file}"
Then it should exit successfully
# Turn acd
# on the left there should be cb (and bc)
And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: true, highway_turn_classification: [0-9]+, access_turn_classification: 0, priority_class: 3/
# on the right there should be ce and ec
And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: true, highway_turn_classification: [0-9]+, access_turn_classification: 0, priority_class: 4/

View File

@ -70,6 +70,16 @@ IntersectionView getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
const TurnLanesIndexedArray &turn_lanes_data, const TurnLanesIndexedArray &turn_lanes_data,
const IntersectionEdge &incoming_edge); const IntersectionEdge &incoming_edge);
IntersectionView
getConnectedRoadsForEdgeGeometries(const util::NodeBasedDynamicGraph &graph,
const EdgeBasedNodeDataContainer &node_data_container,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const TurnLanesIndexedArray &turn_lanes_data,
const IntersectionEdge &incoming_edge,
const IntersectionEdgeGeometries &edge_geometries,
const std::unordered_set<EdgeID> &merged_edge_ids);
// Graph Compression cannot compress every setting. For example any barrier/traffic light cannot // Graph Compression cannot compress every setting. For example any barrier/traffic light cannot
// be compressed. As a result, a simple road of the form `a ----- b` might end up as having an // be compressed. As a result, a simple road of the form `a ----- b` might end up as having an
// intermediate intersection, if there is a traffic light in between. If we want to look farther // intermediate intersection, if there is a traffic light in between. If we want to look farther

View File

@ -714,16 +714,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
{ {
++node_based_edge_counter; ++node_based_edge_counter;
const auto intersection_view = const auto connected_roads =
convertToIntersectionView(m_node_based_graph, extractor::intersection::getConnectedRoadsForEdgeGeometries(
m_edge_based_node_container, m_node_based_graph,
unconditional_node_restriction_map, m_edge_based_node_container,
m_barrier_nodes, unconditional_node_restriction_map,
edge_geometries, m_barrier_nodes,
turn_lanes_data, turn_lanes_data,
incoming_edge, incoming_edge,
outgoing_edges, edge_geometries,
merged_edge_ids); merged_edge_ids);
// check if this edge is part of a restriction via-way // check if this edge is part of a restriction via-way
const auto is_restriction_via_edge = const auto is_restriction_via_edge =
@ -746,12 +746,12 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
continue; continue;
const auto turn = const auto turn =
std::find_if(intersection_view.begin(), std::find_if(connected_roads.begin(),
intersection_view.end(), connected_roads.end(),
[edge = outgoing_edge.edge](const auto &road) { [edge = outgoing_edge.edge](const auto &road) {
return road.eid == edge; return road.eid == edge;
}); });
OSRM_ASSERT(turn != intersection_view.end(), OSRM_ASSERT(turn != connected_roads.end(),
m_coordinates[intersection_node]); m_coordinates[intersection_node]);
std::vector<ExtractionTurnLeg> road_legs_on_the_right; std::vector<ExtractionTurnLeg> road_legs_on_the_right;
@ -760,6 +760,37 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
auto get_connected_road_info = [&](const auto &connected_edge) { auto get_connected_road_info = [&](const auto &connected_edge) {
const auto &edge_data = const auto &edge_data =
m_node_based_graph.GetEdgeData(connected_edge.eid); m_node_based_graph.GetEdgeData(connected_edge.eid);
bool is_incoming, is_outgoing;
if (edge_data.reversed)
{
// If getConnectedRoads adds reversed edge it means
// this edge is incoming-only
is_incoming = true;
is_outgoing = false;
}
else
{
// It does not add incoming edge if there is outgoing so we
// should find it ourselves
is_incoming = false;
auto reversed_edge = m_node_based_graph.FindEdge(
m_node_based_graph.GetTarget(connected_edge.eid),
intersection_node);
if (reversed_edge != SPECIAL_EDGEID)
{
const auto &reversed_edge_data =
m_node_based_graph.GetEdgeData(reversed_edge);
if (!reversed_edge_data.reversed)
{
is_incoming = true;
}
}
is_outgoing = true;
}
return ExtractionTurnLeg( return ExtractionTurnLeg(
edge_data.flags.restricted, edge_data.flags.restricted,
edge_data.flags.road_classification.IsMotorwayClass(), edge_data.flags.road_classification.IsMotorwayClass(),
@ -772,10 +803,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
edge_data.duration) * edge_data.duration) *
36, 36,
edge_data.flags.road_classification.GetPriority(), edge_data.flags.road_classification.GetPriority(),
!connected_edge.entry_allowed || is_incoming,
(edge_data.flags.forward && is_outgoing);
edge_data.flags.backward), // is incoming
connected_edge.entry_allowed);
}; };
// all connected roads on the right of a u turn // all connected roads on the right of a u turn
@ -783,35 +812,35 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
guidance::DirectionModifier::UTurn; guidance::DirectionModifier::UTurn;
if (is_uturn) if (is_uturn)
{ {
if (turn != intersection_view.begin()) if (turn != connected_roads.begin())
{ {
std::transform(intersection_view.begin() + 1, std::transform(connected_roads.begin() + 1,
turn, turn,
std::back_inserter(road_legs_on_the_right), std::back_inserter(road_legs_on_the_right),
get_connected_road_info); get_connected_road_info);
} }
std::transform(turn + 1, std::transform(turn + 1,
intersection_view.end(), connected_roads.end(),
std::back_inserter(road_legs_on_the_right), std::back_inserter(road_legs_on_the_right),
get_connected_road_info); get_connected_road_info);
} }
else else
{ {
if (intersection_view.begin() != turn) if (connected_roads.begin() != turn)
{ {
std::transform(intersection_view.begin() + 1, std::transform(connected_roads.begin() + 1,
turn, turn,
std::back_inserter(road_legs_on_the_right), std::back_inserter(road_legs_on_the_right),
get_connected_road_info); get_connected_road_info);
} }
std::transform(turn + 1, std::transform(turn + 1,
intersection_view.end(), connected_roads.end(),
std::back_inserter(road_legs_on_the_left), std::back_inserter(road_legs_on_the_left),
get_connected_road_info); get_connected_road_info);
} }
if (is_uturn && turn != intersection_view.begin()) if (is_uturn && turn != connected_roads.begin())
{ {
util::Log(logWARNING) util::Log(logWARNING)
<< "Turn is a u turn but not turning to the first connected " << "Turn is a u turn but not turning to the first connected "
@ -819,7 +848,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
<< intersection_node << ", OSM link: " << intersection_node << ", OSM link: "
<< toOSMLink(m_coordinates[intersection_node]); << toOSMLink(m_coordinates[intersection_node]);
} }
else if (turn == intersection_view.begin() && !is_uturn) else if (turn == connected_roads.begin() && !is_uturn)
{ {
util::Log(logWARNING) util::Log(logWARNING)
<< "Turn is a u turn but not classified as a u turn. Node ID: " << "Turn is a u turn but not classified as a u turn. Node ID: "

View File

@ -741,36 +741,61 @@ IntersectionView getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
const IntersectionEdge &incoming_edge) const IntersectionEdge &incoming_edge)
{ {
const auto intersection_node = graph.GetTarget(incoming_edge.edge); const auto intersection_node = graph.GetTarget(incoming_edge.edge);
const auto &outgoing_edges = intersection::getOutgoingEdges(graph, intersection_node);
auto edge_geometries = getIntersectionOutgoingGeometries<USE_CLOSE_COORDINATE>( auto edge_geometries = getIntersectionOutgoingGeometries<USE_CLOSE_COORDINATE>(
graph, compressed_geometries, node_coordinates, intersection_node); graph, compressed_geometries, node_coordinates, intersection_node);
auto merged_edge_ids = std::unordered_set<EdgeID>();
return getConnectedRoadsForEdgeGeometries(graph,
node_data_container,
node_restriction_map,
barrier_nodes,
turn_lanes_data,
incoming_edge,
edge_geometries,
merged_edge_ids);
}
IntersectionView
getConnectedRoadsForEdgeGeometries(const util::NodeBasedDynamicGraph &graph,
const EdgeBasedNodeDataContainer &node_data_container,
const RestrictionMap &node_restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const TurnLanesIndexedArray &turn_lanes_data,
const IntersectionEdge &incoming_edge,
const IntersectionEdgeGeometries &edge_geometries,
const std::unordered_set<EdgeID> &merged_edge_ids)
{
const auto intersection_node = graph.GetTarget(incoming_edge.edge);
const auto &outgoing_edges = intersection::getOutgoingEdges(graph, intersection_node);
// Add incoming edges with reversed bearings // Add incoming edges with reversed bearings
const auto edges_number = edge_geometries.size(); auto processed_edge_geometries = IntersectionEdgeGeometries(edge_geometries);
edge_geometries.resize(2 * edges_number); const auto edges_number = processed_edge_geometries.size();
processed_edge_geometries.resize(2 * edges_number);
for (std::size_t index = 0; index < edges_number; ++index) for (std::size_t index = 0; index < edges_number; ++index)
{ {
const auto &geometry = edge_geometries[index]; const auto &geometry = processed_edge_geometries[index];
const auto remote_node = graph.GetTarget(geometry.eid); const auto remote_node = graph.GetTarget(geometry.eid);
const auto incoming_edge = graph.FindEdge(remote_node, intersection_node); const auto incoming_edge = graph.FindEdge(remote_node, intersection_node);
edge_geometries[edges_number + index] = {incoming_edge, processed_edge_geometries[edges_number + index] = {
util::bearing::reverse(geometry.initial_bearing), incoming_edge,
util::bearing::reverse(geometry.perceived_bearing), util::bearing::reverse(geometry.initial_bearing),
geometry.segment_length}; util::bearing::reverse(geometry.perceived_bearing),
geometry.segment_length};
} }
// Enforce ordering of edges by IDs // Enforce ordering of edges by IDs
std::sort(edge_geometries.begin(), edge_geometries.end()); std::sort(processed_edge_geometries.begin(), processed_edge_geometries.end());
return convertToIntersectionView(graph, return convertToIntersectionView(graph,
node_data_container, node_data_container,
node_restriction_map, node_restriction_map,
barrier_nodes, barrier_nodes,
edge_geometries, processed_edge_geometries,
turn_lanes_data, turn_lanes_data,
incoming_edge, incoming_edge,
outgoing_edges, outgoing_edges,
std::unordered_set<EdgeID>()); merged_edge_ids);
} }
template IntersectionView template IntersectionView