Skip to content

Commit 960269f

Browse files
authored
Merge pull request #5131 from themylogin/master
Fix turn.roads_on_the_left and turn.roads_on_the right for two-way roads
2 parents ed7b1ba + b0b8069 commit 960269f

File tree

5 files changed

+128
-36
lines changed

5 files changed

+128
-36
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- Misc:
1111
- CHANGED: Cleanup NodeJS dependencies [#5945](https://github.com/Project-OSRM/osrm-backend/pull/5945)
1212
- 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)
13+
- 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)
1314
- Profile:
1415
- 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)
1516
- Infrastructure

features/options/extract/turn_function.feature

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,30 @@ Feature: Turn Function Information
180180
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/
181181
# turning abc, give information about about db
182182
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/
183+
184+
Scenario: Turns should have correct information of two-way roads at intersection
185+
Given the node map
186+
"""
187+
b
188+
|
189+
a-c-d
190+
|
191+
e
192+
"""
193+
And the ways
194+
| nodes | highway | oneway |
195+
| ac | motorway | yes |
196+
| cd | motorway_link | yes |
197+
| bc | trunk | yes |
198+
| cb | trunk_link | yes |
199+
| ce | primary | yes |
200+
| ec | primary_link | yes |
201+
And the data has been saved to disk
202+
203+
When I run "osrm-extract --profile {profile_file} {osm_file}"
204+
Then it should exit successfully
205+
# Turn acd
206+
# on the left there should be cb (and bc)
207+
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/
208+
# on the right there should be ce and ec
209+
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/

include/extractor/intersection/intersection_analysis.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ IntersectionView getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
7070
const TurnLanesIndexedArray &turn_lanes_data,
7171
const IntersectionEdge &incoming_edge);
7272

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

src/extractor/edge_based_graph_factory.cpp

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -714,16 +714,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
714714
{
715715
++node_based_edge_counter;
716716

717-
const auto intersection_view =
718-
convertToIntersectionView(m_node_based_graph,
719-
m_edge_based_node_container,
720-
unconditional_node_restriction_map,
721-
m_barrier_nodes,
722-
edge_geometries,
723-
turn_lanes_data,
724-
incoming_edge,
725-
outgoing_edges,
726-
merged_edge_ids);
717+
const auto connected_roads =
718+
extractor::intersection::getConnectedRoadsForEdgeGeometries(
719+
m_node_based_graph,
720+
m_edge_based_node_container,
721+
unconditional_node_restriction_map,
722+
m_barrier_nodes,
723+
turn_lanes_data,
724+
incoming_edge,
725+
edge_geometries,
726+
merged_edge_ids);
727727

728728
// check if this edge is part of a restriction via-way
729729
const auto is_restriction_via_edge =
@@ -746,12 +746,12 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
746746
continue;
747747

748748
const auto turn =
749-
std::find_if(intersection_view.begin(),
750-
intersection_view.end(),
749+
std::find_if(connected_roads.begin(),
750+
connected_roads.end(),
751751
[edge = outgoing_edge.edge](const auto &road) {
752752
return road.eid == edge;
753753
});
754-
OSRM_ASSERT(turn != intersection_view.end(),
754+
OSRM_ASSERT(turn != connected_roads.end(),
755755
m_coordinates[intersection_node]);
756756

757757
std::vector<ExtractionTurnLeg> road_legs_on_the_right;
@@ -760,6 +760,37 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
760760
auto get_connected_road_info = [&](const auto &connected_edge) {
761761
const auto &edge_data =
762762
m_node_based_graph.GetEdgeData(connected_edge.eid);
763+
764+
bool is_incoming, is_outgoing;
765+
if (edge_data.reversed)
766+
{
767+
// If getConnectedRoads adds reversed edge it means
768+
// this edge is incoming-only
769+
is_incoming = true;
770+
is_outgoing = false;
771+
}
772+
else
773+
{
774+
// It does not add incoming edge if there is outgoing so we
775+
// should find it ourselves
776+
is_incoming = false;
777+
auto reversed_edge = m_node_based_graph.FindEdge(
778+
m_node_based_graph.GetTarget(connected_edge.eid),
779+
intersection_node);
780+
if (reversed_edge != SPECIAL_EDGEID)
781+
{
782+
const auto &reversed_edge_data =
783+
m_node_based_graph.GetEdgeData(reversed_edge);
784+
785+
if (!reversed_edge_data.reversed)
786+
{
787+
is_incoming = true;
788+
}
789+
}
790+
791+
is_outgoing = true;
792+
}
793+
763794
return ExtractionTurnLeg(
764795
edge_data.flags.restricted,
765796
edge_data.flags.road_classification.IsMotorwayClass(),
@@ -772,54 +803,52 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
772803
edge_data.duration) *
773804
36,
774805
edge_data.flags.road_classification.GetPriority(),
775-
!connected_edge.entry_allowed ||
776-
(edge_data.flags.forward &&
777-
edge_data.flags.backward), // is incoming
778-
connected_edge.entry_allowed);
806+
is_incoming,
807+
is_outgoing);
779808
};
780809

781810
// all connected roads on the right of a u turn
782811
const auto is_uturn = guidance::getTurnDirection(turn->angle) ==
783812
guidance::DirectionModifier::UTurn;
784813
if (is_uturn)
785814
{
786-
if (turn != intersection_view.begin())
815+
if (turn != connected_roads.begin())
787816
{
788-
std::transform(intersection_view.begin() + 1,
817+
std::transform(connected_roads.begin() + 1,
789818
turn,
790819
std::back_inserter(road_legs_on_the_right),
791820
get_connected_road_info);
792821
}
793822

794823
std::transform(turn + 1,
795-
intersection_view.end(),
824+
connected_roads.end(),
796825
std::back_inserter(road_legs_on_the_right),
797826
get_connected_road_info);
798827
}
799828
else
800829
{
801-
if (intersection_view.begin() != turn)
830+
if (connected_roads.begin() != turn)
802831
{
803-
std::transform(intersection_view.begin() + 1,
832+
std::transform(connected_roads.begin() + 1,
804833
turn,
805834
std::back_inserter(road_legs_on_the_right),
806835
get_connected_road_info);
807836
}
808837
std::transform(turn + 1,
809-
intersection_view.end(),
838+
connected_roads.end(),
810839
std::back_inserter(road_legs_on_the_left),
811840
get_connected_road_info);
812841
}
813842

814-
if (is_uturn && turn != intersection_view.begin())
843+
if (is_uturn && turn != connected_roads.begin())
815844
{
816845
util::Log(logWARNING)
817846
<< "Turn is a u turn but not turning to the first connected "
818847
"edge of the intersection. Node ID: "
819848
<< intersection_node << ", OSM link: "
820849
<< toOSMLink(m_coordinates[intersection_node]);
821850
}
822-
else if (turn == intersection_view.begin() && !is_uturn)
851+
else if (turn == connected_roads.begin() && !is_uturn)
823852
{
824853
util::Log(logWARNING)
825854
<< "Turn is a u turn but not classified as a u turn. Node ID: "

src/extractor/intersection/intersection_analysis.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -741,36 +741,61 @@ IntersectionView getConnectedRoads(const util::NodeBasedDynamicGraph &graph,
741741
const IntersectionEdge &incoming_edge)
742742
{
743743
const auto intersection_node = graph.GetTarget(incoming_edge.edge);
744-
const auto &outgoing_edges = intersection::getOutgoingEdges(graph, intersection_node);
745744
auto edge_geometries = getIntersectionOutgoingGeometries<USE_CLOSE_COORDINATE>(
746745
graph, compressed_geometries, node_coordinates, intersection_node);
746+
auto merged_edge_ids = std::unordered_set<EdgeID>();
747+
748+
return getConnectedRoadsForEdgeGeometries(graph,
749+
node_data_container,
750+
node_restriction_map,
751+
barrier_nodes,
752+
turn_lanes_data,
753+
incoming_edge,
754+
edge_geometries,
755+
merged_edge_ids);
756+
}
757+
758+
IntersectionView
759+
getConnectedRoadsForEdgeGeometries(const util::NodeBasedDynamicGraph &graph,
760+
const EdgeBasedNodeDataContainer &node_data_container,
761+
const RestrictionMap &node_restriction_map,
762+
const std::unordered_set<NodeID> &barrier_nodes,
763+
const TurnLanesIndexedArray &turn_lanes_data,
764+
const IntersectionEdge &incoming_edge,
765+
const IntersectionEdgeGeometries &edge_geometries,
766+
const std::unordered_set<EdgeID> &merged_edge_ids)
767+
{
768+
const auto intersection_node = graph.GetTarget(incoming_edge.edge);
769+
const auto &outgoing_edges = intersection::getOutgoingEdges(graph, intersection_node);
747770

748771
// Add incoming edges with reversed bearings
749-
const auto edges_number = edge_geometries.size();
750-
edge_geometries.resize(2 * edges_number);
772+
auto processed_edge_geometries = IntersectionEdgeGeometries(edge_geometries);
773+
const auto edges_number = processed_edge_geometries.size();
774+
processed_edge_geometries.resize(2 * edges_number);
751775
for (std::size_t index = 0; index < edges_number; ++index)
752776
{
753-
const auto &geometry = edge_geometries[index];
777+
const auto &geometry = processed_edge_geometries[index];
754778
const auto remote_node = graph.GetTarget(geometry.eid);
755779
const auto incoming_edge = graph.FindEdge(remote_node, intersection_node);
756-
edge_geometries[edges_number + index] = {incoming_edge,
757-
util::bearing::reverse(geometry.initial_bearing),
758-
util::bearing::reverse(geometry.perceived_bearing),
759-
geometry.segment_length};
780+
processed_edge_geometries[edges_number + index] = {
781+
incoming_edge,
782+
util::bearing::reverse(geometry.initial_bearing),
783+
util::bearing::reverse(geometry.perceived_bearing),
784+
geometry.segment_length};
760785
}
761786

762787
// Enforce ordering of edges by IDs
763-
std::sort(edge_geometries.begin(), edge_geometries.end());
788+
std::sort(processed_edge_geometries.begin(), processed_edge_geometries.end());
764789

765790
return convertToIntersectionView(graph,
766791
node_data_container,
767792
node_restriction_map,
768793
barrier_nodes,
769-
edge_geometries,
794+
processed_edge_geometries,
770795
turn_lanes_data,
771796
incoming_edge,
772797
outgoing_edges,
773-
std::unordered_set<EdgeID>());
798+
merged_edge_ids);
774799
}
775800

776801
template IntersectionView

0 commit comments

Comments
 (0)