Skip to content

Commit 3771e99

Browse files
committed
Fix snapping target locations to ways used in turn restrictions
Currently there is an edge-case in the turn restriction implementation, such that routes can not be found if the target input location snaps to a way used in a (multi) via restriction. With the addition of snapping input locations to multiple ways, we can now also snap to the "duplicate" edges created for the restriction graph, thereby fixing the problem. This is achieved by adding the duplicate restriction edges to the geospatial search RTree. This does open up the possibility of multiple paths representing exactly the same route - one using the original edge as a source, the other using the duplicate restriction graph edge as source. This is fine, as both edges are represented by the same geometry, so will generate the same result.
1 parent d34f21e commit 3771e99

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

features/car/multi_via_restrictions.feature

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,3 +1031,61 @@ Feature: Car - Multiple Via Turn restrictions
10311031
| from | to | route | locations |
10321032
| a | f | ab,bc,cd,de,ef,ef | a,b,c,d,e,f |
10331033

1034+
1035+
@restriction-way
1036+
Scenario: Snap source/target to via restriction way
1037+
Given the node map
1038+
"""
1039+
a-1-b-2-c-3-d
1040+
"""
1041+
1042+
And the ways
1043+
| nodes |
1044+
| ab |
1045+
| bc |
1046+
| cd |
1047+
1048+
And the relations
1049+
| type | way:from | way:via | way:to | restriction |
1050+
| restriction | ab | bc | cd | no_straight_on |
1051+
1052+
When I route I should get
1053+
| from | to | route |
1054+
| 1 | 2 | ab,bc,bc |
1055+
| 2 | 3 | bc,cd,cd |
1056+
1057+
1058+
@restriction-way
1059+
Scenario: Car - Snap source/target to multi-via restriction way
1060+
# Example: https://www.openstreetmap.org/relation/11787041
1061+
Given the node map
1062+
"""
1063+
|--g---f---e
1064+
a | 1
1065+
|--b---c---d
1066+
1067+
"""
1068+
1069+
And the nodes
1070+
| node | highway |
1071+
| b | traffic_signals |
1072+
1073+
And the ways
1074+
| nodes | oneway | name |
1075+
| ab | yes | enter |
1076+
| bc | yes | enter |
1077+
| cd | yes | right |
1078+
| de | yes | up |
1079+
| ef | yes | left |
1080+
| fc | yes | down |
1081+
| fg | yes | exit |
1082+
| ga | yes | exit |
1083+
1084+
And the relations
1085+
| type | way:from | way:via | way:to | restriction |
1086+
| restriction | bc | cd,de,ef | fg | no_u_turn |
1087+
1088+
When I route I should get
1089+
| from | to | route | locations |
1090+
| a | 1 | enter,right,up,up | a,c,d,_ |
1091+
| 1 | a | up,left,exit,exit | _,e,f,a |

src/extractor/edge_based_graph_factory.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,44 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
412412
m_edge_based_node_distances.push_back(
413413
m_edge_based_node_distances[nbe_to_ebn_mapping[eid]]);
414414

415+
const auto &forward_geometry = m_compressed_edge_container.GetBucketReference(eid);
416+
const auto segment_count = forward_geometry.size();
417+
418+
NodeID current_edge_source_coordinate_id = node_u;
419+
const EdgeData &forward_data = m_node_based_graph.GetEdgeData(eid);
420+
421+
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id) {
422+
if (edge_based_node_id == SPECIAL_NODEID)
423+
{
424+
return SegmentID{SPECIAL_SEGMENTID, false};
425+
}
426+
427+
return SegmentID{edge_based_node_id, true};
428+
};
429+
430+
// Add segments of edge-based nodes
431+
for (const auto i : util::irange(std::size_t{0}, segment_count))
432+
{
433+
const NodeID current_edge_target_coordinate_id = forward_geometry[i].node_id;
434+
435+
// don't add node-segments for penalties
436+
if (current_edge_target_coordinate_id == current_edge_source_coordinate_id)
437+
continue;
438+
439+
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
440+
441+
// build edges
442+
m_edge_based_node_segments.emplace_back(
443+
edge_id_to_segment_id(edge_based_node_id),
444+
SegmentID{SPECIAL_SEGMENTID, false},
445+
current_edge_source_coordinate_id,
446+
current_edge_target_coordinate_id,
447+
i,
448+
forward_data.flags.startpoint);
449+
450+
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
451+
}
452+
415453
edge_based_node_id++;
416454
progress.PrintStatus(progress_counter++);
417455
}

0 commit comments

Comments
 (0)