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:
commit
960269f95a
@ -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
|
||||||
|
@ -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/
|
||||||
|
@ -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
|
||||||
|
@ -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: "
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user