From 991a0b38c5ac78793e50dfffa3e191bc39f1baba Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Mon, 28 Mar 2016 17:06:51 +0200 Subject: [PATCH] Implement re-enabling of PhantomNode directions after bearing filtering --- include/engine/geospatial_query.hpp | 29 +++--- include/engine/phantom_node.hpp | 78 ++++++---------- .../routing_algorithms/alternative_path.hpp | 52 +++++------ .../direct_shortest_path.hpp | 28 +++--- .../routing_algorithms/many_to_many.hpp | 28 +++--- .../routing_algorithms/routing_base.hpp | 79 ++++++++-------- .../routing_algorithms/shortest_path.hpp | 90 ++++++++++--------- include/extractor/edge_based_node.hpp | 38 ++++---- include/util/static_rtree.hpp | 10 +-- include/util/typedefs.hpp | 19 ++++ src/engine/plugins/match.cpp | 20 ++--- src/engine/plugins/tile.cpp | 4 +- src/engine/plugins/viaroute.cpp | 23 +++-- src/extractor/edge_based_graph_factory.cpp | 26 ++++-- src/extractor/extractor.cpp | 34 +++---- unit_tests/util/static_rtree.cpp | 24 ++--- 16 files changed, 302 insertions(+), 280 deletions(-) diff --git a/include/engine/geospatial_query.hpp b/include/engine/geospatial_query.hpp index 0c9de69c9..b22032ed1 100644 --- a/include/engine/geospatial_query.hpp +++ b/include/engine/geospatial_query.hpp @@ -244,8 +244,8 @@ template class GeospatialQuery bool has_big_component = false; auto results = rtree.Nearest( input_coordinate, - [this, bearing, bearing_range, &has_big_component, &has_small_component]( - const EdgeData &data) + [this, bearing, bearing_range, &has_big_component, + &has_small_component](const EdgeData &data) { auto use_segment = (!has_small_component || (!has_big_component && !data.component.is_tiny)); @@ -290,8 +290,8 @@ template class GeospatialQuery bool has_big_component = false; auto results = rtree.Nearest( input_coordinate, - [this, bearing, bearing_range, &has_big_component, &has_small_component]( - const EdgeData &data) + [this, bearing, bearing_range, &has_big_component, + &has_small_component](const EdgeData &data) { auto use_segment = (!has_small_component || (!has_big_component && !data.component.is_tiny)); @@ -384,22 +384,18 @@ template class GeospatialQuery } ratio = std::min(1.0, std::max(0.0, ratio)); - if (SPECIAL_NODEID != data.forward_edge_based_node_id) + if (data.forward_segment_id.id != SPECIAL_SEGMENTID) { forward_weight *= ratio; } - if (SPECIAL_NODEID != data.reverse_edge_based_node_id) + if (data.reverse_segment_id.id != SPECIAL_SEGMENTID) { reverse_weight *= 1.0 - ratio; } - auto transformed = PhantomNodeWithDistance{PhantomNode{data, - forward_weight, - forward_offset, - reverse_weight, - reverse_offset, - point_on_segment, - input_coordinate}, + auto transformed = PhantomNodeWithDistance{PhantomNode{data, forward_weight, forward_offset, + reverse_weight, reverse_offset, + point_on_segment, input_coordinate}, current_perpendicular_distance}; return transformed; @@ -409,6 +405,9 @@ template class GeospatialQuery const int filter_bearing, const int filter_bearing_range) { + BOOST_ASSERT(segment.forward_segment_id.id != SPECIAL_SEGMENTID || !segment.forward_segment_id.enabled); + BOOST_ASSERT(segment.reverse_segment_id.id != SPECIAL_SEGMENTID || !segment.reverse_segment_id.enabled); + const double forward_edge_bearing = util::coordinate_calculation::bearing( coordinates->at(segment.u), coordinates->at(segment.v)); @@ -419,11 +418,11 @@ template class GeospatialQuery const bool forward_bearing_valid = util::bearing::CheckInBounds(std::round(forward_edge_bearing), filter_bearing, filter_bearing_range) && - segment.forward_edge_based_node_id != SPECIAL_NODEID; + segment.forward_segment_id.enabled; const bool backward_bearing_valid = util::bearing::CheckInBounds(std::round(backward_edge_bearing), filter_bearing, filter_bearing_range) && - segment.reverse_edge_based_node_id != SPECIAL_NODEID; + segment.reverse_segment_id.enabled; return std::make_pair(forward_bearing_valid, backward_bearing_valid); } diff --git a/include/engine/phantom_node.hpp b/include/engine/phantom_node.hpp index 57c5bddc3..244276cdf 100644 --- a/include/engine/phantom_node.hpp +++ b/include/engine/phantom_node.hpp @@ -31,7 +31,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "extractor/travel_mode.hpp" #include "util/typedefs.hpp" -#include "osrm/coordinate.hpp" +#include "util/coordinate.hpp" + +#include #include #include @@ -44,8 +46,8 @@ namespace engine struct PhantomNode { - PhantomNode(NodeID forward_node_id, - NodeID reverse_node_id, + PhantomNode(SegmentID forward_segment_id, + SegmentID reverse_segment_id, unsigned name_id, int forward_weight, int reverse_weight, @@ -60,8 +62,8 @@ struct PhantomNode unsigned short fwd_segment_position, extractor::TravelMode forward_travel_mode, extractor::TravelMode backward_travel_mode) - : forward_node_id(forward_node_id), reverse_node_id(reverse_node_id), name_id(name_id), - forward_weight(forward_weight), reverse_weight(reverse_weight), + : forward_segment_id(forward_segment_id), reverse_segment_id(reverse_segment_id), + name_id(name_id), forward_weight(forward_weight), reverse_weight(reverse_weight), forward_offset(forward_offset), reverse_offset(reverse_offset), forward_packed_geometry_id(forward_packed_geometry_id_), reverse_packed_geometry_id(reverse_packed_geometry_id_), @@ -72,7 +74,8 @@ struct PhantomNode } PhantomNode() - : forward_node_id(SPECIAL_NODEID), reverse_node_id(SPECIAL_NODEID), + : forward_segment_id{SPECIAL_SEGMENTID, false}, + reverse_segment_id{SPECIAL_SEGMENTID, false}, name_id(std::numeric_limits::max()), forward_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0), forward_packed_geometry_id(SPECIAL_EDGEID), reverse_packed_geometry_id(SPECIAL_EDGEID), @@ -84,33 +87,22 @@ struct PhantomNode int GetForwardWeightPlusOffset() const { - if (SPECIAL_NODEID == forward_node_id) - { - return 0; - } + BOOST_ASSERT(forward_segment_id.enabled); return forward_offset + forward_weight; } int GetReverseWeightPlusOffset() const { - if (SPECIAL_NODEID == reverse_node_id) - { - return 0; - } + BOOST_ASSERT(reverse_segment_id.enabled); return reverse_offset + reverse_weight; } - bool IsBidirected() const - { - return (forward_node_id != SPECIAL_NODEID) && (reverse_node_id != SPECIAL_NODEID); - } - - bool IsCompressed() const { return (forward_offset != 0) || (reverse_offset != 0); } + bool IsBidirected() const { return forward_segment_id.enabled && reverse_segment_id.enabled; } bool IsValid(const unsigned number_of_nodes) const { - return location.IsValid() && - ((forward_node_id < number_of_nodes) || (reverse_node_id < number_of_nodes)) && + return location.IsValid() && ((forward_segment_id.id < number_of_nodes) || + (reverse_segment_id.id < number_of_nodes)) && ((forward_weight != INVALID_EDGE_WEIGHT) || (reverse_weight != INVALID_EDGE_WEIGHT)) && (component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID); @@ -133,33 +125,21 @@ struct PhantomNode int reverse_offset_, const util::Coordinate location_, const util::Coordinate input_location_) + : forward_segment_id{other.forward_segment_id}, + reverse_segment_id{other.reverse_segment_id}, name_id{other.name_id}, + forward_weight{forward_weight_}, reverse_weight{reverse_weight_}, + forward_offset{forward_offset_}, reverse_offset{reverse_offset_}, + forward_packed_geometry_id{other.forward_packed_geometry_id}, + reverse_packed_geometry_id{other.reverse_packed_geometry_id}, + component{other.component.id, other.component.is_tiny}, location{location_}, + input_location{input_location_}, fwd_segment_position{other.fwd_segment_position}, + forward_travel_mode{other.forward_travel_mode}, + backward_travel_mode{other.backward_travel_mode} { - forward_node_id = other.forward_edge_based_node_id; - reverse_node_id = other.reverse_edge_based_node_id; - name_id = other.name_id; - - forward_weight = forward_weight_; - reverse_weight = reverse_weight_; - - forward_offset = forward_offset_; - reverse_offset = reverse_offset_; - - forward_packed_geometry_id = other.forward_packed_geometry_id; - reverse_packed_geometry_id = other.reverse_packed_geometry_id; - - component.id = other.component.id; - component.is_tiny = other.component.is_tiny; - - location = location_; - input_location = input_location_; - fwd_segment_position = other.fwd_segment_position; - - forward_travel_mode = other.forward_travel_mode; - backward_travel_mode = other.backward_travel_mode; } - NodeID forward_node_id; - NodeID reverse_node_id; + SegmentID forward_segment_id; + SegmentID reverse_segment_id; unsigned name_id; int forward_weight; int reverse_weight; @@ -174,7 +154,7 @@ struct PhantomNode } component; // bit-fields are broken on Windows #ifndef _MSC_VER - static_assert(sizeof(ComponentType) == 4, "ComponentType needs to 4 bytes big"); + static_assert(sizeof(ComponentType) == 4, "ComponentType needs to be 4 bytes big"); #endif util::Coordinate location; util::Coordinate input_location; @@ -214,8 +194,8 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNodes &pn) inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn) { - out << "node1: " << pn.forward_node_id << ", " - << "node2: " << pn.reverse_node_id << ", " + out << "node1: " << pn.forward_segment_id.id << ", " + << "node2: " << pn.reverse_segment_id.id << ", " << "name: " << pn.name_id << ", " << "fwd-w: " << pn.forward_weight << ", " << "rev-w: " << pn.reverse_weight << ", " diff --git a/include/engine/routing_algorithms/alternative_path.hpp b/include/engine/routing_algorithms/alternative_path.hpp index 024b03611..8dcc123ec 100644 --- a/include/engine/routing_algorithms/alternative_path.hpp +++ b/include/engine/routing_algorithms/alternative_path.hpp @@ -84,45 +84,37 @@ class AlternativeRouting final int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT; NodeID middle_node = SPECIAL_NODEID; const EdgeWeight min_edge_offset = - std::min(-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), - -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); + std::min(phantom_node_pair.source_phantom.forward_segment_id.enabled ? -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset() : 0, + phantom_node_pair.source_phantom.reverse_segment_id.enabled ? -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset() : 0); - if (phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID) + if (phantom_node_pair.source_phantom.forward_segment_id.enabled) { - // util::SimpleLogger().Write(logDEBUG) << "fwd-a insert: " << - // phantom_node_pair.source_phantom.forward_node_id << ", w: " << - // -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); - forward_heap1.Insert(phantom_node_pair.source_phantom.forward_node_id, + BOOST_ASSERT(phantom_node_pair.source_phantom.forward_segment_id.id != SPECIAL_SEGMENTID); + forward_heap1.Insert(phantom_node_pair.source_phantom.forward_segment_id.id, -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), - phantom_node_pair.source_phantom.forward_node_id); + phantom_node_pair.source_phantom.forward_segment_id.id); } - if (phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID) + if (phantom_node_pair.source_phantom.reverse_segment_id.enabled) { - // util::SimpleLogger().Write(logDEBUG) << "fwd-b insert: " << - // phantom_node_pair.source_phantom.reverse_node_id << ", w: " << - // -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); - forward_heap1.Insert(phantom_node_pair.source_phantom.reverse_node_id, + BOOST_ASSERT(phantom_node_pair.source_phantom.reverse_segment_id.id != SPECIAL_SEGMENTID); + forward_heap1.Insert(phantom_node_pair.source_phantom.reverse_segment_id.id, -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), - phantom_node_pair.source_phantom.reverse_node_id); + phantom_node_pair.source_phantom.reverse_segment_id.id); } - if (phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID) + if (phantom_node_pair.target_phantom.forward_segment_id.enabled) { - // util::SimpleLogger().Write(logDEBUG) << "rev-a insert: " << - // phantom_node_pair.target_phantom.forward_node_id << ", w: " << - // phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(); - reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_node_id, + BOOST_ASSERT(phantom_node_pair.target_phantom.forward_segment_id.id != SPECIAL_SEGMENTID); + reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_segment_id.id, phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(), - phantom_node_pair.target_phantom.forward_node_id); + phantom_node_pair.target_phantom.forward_segment_id.id); } - if (phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID) + if (phantom_node_pair.target_phantom.reverse_segment_id.enabled) { - // util::SimpleLogger().Write(logDEBUG) << "rev-b insert: " << - // phantom_node_pair.target_phantom.reverse_node_id << ", w: " << - // phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(); - reverse_heap1.Insert(phantom_node_pair.target_phantom.reverse_node_id, + BOOST_ASSERT(phantom_node_pair.target_phantom.reverse_segment_id.id != SPECIAL_SEGMENTID); + reverse_heap1.Insert(phantom_node_pair.target_phantom.reverse_segment_id.id, phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(), - phantom_node_pair.target_phantom.reverse_node_id); + phantom_node_pair.target_phantom.reverse_segment_id.id); } // search from s and t till new_min/(1+epsilon) > length_of_shortest_path @@ -316,9 +308,9 @@ class AlternativeRouting final BOOST_ASSERT(!packed_shortest_path.empty()); raw_route_data.unpacked_path_segments.resize(1); raw_route_data.source_traversed_in_reverse.push_back( - (packed_shortest_path.front() != phantom_node_pair.source_phantom.forward_node_id)); + (packed_shortest_path.front() != phantom_node_pair.source_phantom.forward_segment_id.id)); raw_route_data.target_traversed_in_reverse.push_back( - (packed_shortest_path.back() != phantom_node_pair.target_phantom.forward_node_id)); + (packed_shortest_path.back() != phantom_node_pair.target_phantom.forward_segment_id.id)); super::UnpackPath( // -- packed input @@ -338,9 +330,9 @@ class AlternativeRouting final s_v_middle, v_t_middle, packed_alternate_path); raw_route_data.alt_source_traversed_in_reverse.push_back(( - packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id)); + packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_segment_id.id)); raw_route_data.alt_target_traversed_in_reverse.push_back( - (packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_node_id)); + (packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_segment_id.id)); // unpack the alternate path super::UnpackPath(packed_alternate_path.begin(), packed_alternate_path.end(), diff --git a/include/engine/routing_algorithms/direct_shortest_path.hpp b/include/engine/routing_algorithms/direct_shortest_path.hpp index 2e928cdc9..970949e02 100644 --- a/include/engine/routing_algorithms/direct_shortest_path.hpp +++ b/include/engine/routing_algorithms/direct_shortest_path.hpp @@ -60,31 +60,31 @@ class DirectShortestPathRouting final BOOST_ASSERT(source_phantom.IsValid()); BOOST_ASSERT(target_phantom.IsValid()); - if (source_phantom.forward_node_id != SPECIAL_NODEID) + if (source_phantom.forward_segment_id.enabled) { - forward_heap.Insert(source_phantom.forward_node_id, + forward_heap.Insert(source_phantom.forward_segment_id.id, -source_phantom.GetForwardWeightPlusOffset(), - source_phantom.forward_node_id); + source_phantom.forward_segment_id.id); } - if (source_phantom.reverse_node_id != SPECIAL_NODEID) + if (source_phantom.reverse_segment_id.enabled) { - forward_heap.Insert(source_phantom.reverse_node_id, + forward_heap.Insert(source_phantom.reverse_segment_id.id, -source_phantom.GetReverseWeightPlusOffset(), - source_phantom.reverse_node_id); + source_phantom.reverse_segment_id.id); } - if (target_phantom.forward_node_id != SPECIAL_NODEID) + if (target_phantom.forward_segment_id.enabled) { - reverse_heap.Insert(target_phantom.forward_node_id, + reverse_heap.Insert(target_phantom.forward_segment_id.id, target_phantom.GetForwardWeightPlusOffset(), - target_phantom.forward_node_id); + target_phantom.forward_segment_id.id); } - if (target_phantom.reverse_node_id != SPECIAL_NODEID) + if (target_phantom.reverse_segment_id.enabled) { - reverse_heap.Insert(target_phantom.reverse_node_id, + reverse_heap.Insert(target_phantom.reverse_segment_id.id, target_phantom.GetReverseWeightPlusOffset(), - target_phantom.reverse_node_id); + target_phantom.reverse_segment_id.id); } int distance = INVALID_EDGE_WEIGHT; @@ -124,9 +124,9 @@ class DirectShortestPathRouting final raw_route_data.shortest_path_length = distance; raw_route_data.unpacked_path_segments.resize(1); raw_route_data.source_traversed_in_reverse.push_back( - (packed_leg.front() != phantom_node_pair.source_phantom.forward_node_id)); + (packed_leg.front() != phantom_node_pair.source_phantom.forward_segment_id.id)); raw_route_data.target_traversed_in_reverse.push_back( - (packed_leg.back() != phantom_node_pair.target_phantom.forward_node_id)); + (packed_leg.back() != phantom_node_pair.target_phantom.forward_segment_id.id)); super::UnpackPath(packed_leg.begin(), packed_leg.end(), phantom_node_pair, raw_route_data.unpacked_path_segments.front()); diff --git a/include/engine/routing_algorithms/many_to_many.hpp b/include/engine/routing_algorithms/many_to_many.hpp index d61db7039..e09a91dd3 100644 --- a/include/engine/routing_algorithms/many_to_many.hpp +++ b/include/engine/routing_algorithms/many_to_many.hpp @@ -71,15 +71,17 @@ class ManyToManyRouting final query_heap.Clear(); // insert target(s) at distance 0 - if (SPECIAL_NODEID != phantom.forward_node_id) + if (phantom.forward_segment_id.enabled) { - query_heap.Insert(phantom.forward_node_id, phantom.GetForwardWeightPlusOffset(), - phantom.forward_node_id); + query_heap.Insert(phantom.forward_segment_id.id, + phantom.GetForwardWeightPlusOffset(), + phantom.forward_segment_id.id); } - if (SPECIAL_NODEID != phantom.reverse_node_id) + if (phantom.reverse_segment_id.enabled) { - query_heap.Insert(phantom.reverse_node_id, phantom.GetReverseWeightPlusOffset(), - phantom.reverse_node_id); + query_heap.Insert(phantom.reverse_segment_id.id, + phantom.GetReverseWeightPlusOffset(), + phantom.reverse_segment_id.id); } // explore search space @@ -97,15 +99,17 @@ class ManyToManyRouting final query_heap.Clear(); // insert target(s) at distance 0 - if (SPECIAL_NODEID != phantom.forward_node_id) + if (phantom.forward_segment_id.enabled) { - query_heap.Insert(phantom.forward_node_id, -phantom.GetForwardWeightPlusOffset(), - phantom.forward_node_id); + query_heap.Insert(phantom.forward_segment_id.id, + -phantom.GetForwardWeightPlusOffset(), + phantom.forward_segment_id.id); } - if (SPECIAL_NODEID != phantom.reverse_node_id) + if (phantom.reverse_segment_id.enabled) { - query_heap.Insert(phantom.reverse_node_id, -phantom.GetReverseWeightPlusOffset(), - phantom.reverse_node_id); + query_heap.Insert(phantom.reverse_segment_id.id, + -phantom.GetReverseWeightPlusOffset(), + phantom.reverse_segment_id.id); } // explore search space diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index 5233fd36b..1bebbf676 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -213,9 +213,9 @@ template class BasicRoutingInterface std::vector &unpacked_path) const { const bool start_traversed_in_reverse = - (*packed_path_begin != phantom_node_pair.source_phantom.forward_node_id); + (*packed_path_begin != phantom_node_pair.source_phantom.forward_segment_id.id); const bool target_traversed_in_reverse = - (*std::prev(packed_path_end) != phantom_node_pair.target_phantom.forward_node_id); + (*std::prev(packed_path_end) != phantom_node_pair.target_phantom.forward_segment_id.id); BOOST_ASSERT(std::distance(packed_path_begin, packed_path_end) > 0); std::stack> recursion_stack; @@ -391,11 +391,12 @@ template class BasicRoutingInterface { BOOST_ASSERT(i < id_vector.size()); BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0); - unpacked_path.emplace_back(PathData{ - id_vector[i], phantom_node_pair.target_phantom.name_id, weight_vector[i], - extractor::guidance::TurnInstruction::NO_TURN(), - target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode - : phantom_node_pair.target_phantom.forward_travel_mode}); + unpacked_path.emplace_back( + PathData{id_vector[i], phantom_node_pair.target_phantom.name_id, weight_vector[i], + extractor::guidance::TurnInstruction::NO_TURN(), + target_traversed_in_reverse + ? phantom_node_pair.target_phantom.backward_travel_mode + : phantom_node_pair.target_phantom.forward_travel_mode}); } if (is_local_path && unpacked_path.size() > 0) @@ -520,8 +521,8 @@ template class BasicRoutingInterface // A forced loop might be necessary, if source and target are on the same segment. // If this is the case and the offsets of the respective direction are larger for the source // than the target - // then a force loop is required (e.g. source_phantom.forward_node_id == - // target_phantom.forward_node_id + // then a force loop is required (e.g. source_phantom.forward_segment_id == + // target_phantom.forward_segment_id // && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset()) // requires // a force loop, if the heaps have been initialized with positive offsets. @@ -588,8 +589,8 @@ template class BasicRoutingInterface // A forced loop might be necessary, if source and target are on the same segment. // If this is the case and the offsets of the respective direction are larger for the source // than the target - // then a force loop is required (e.g. source_phantom.forward_node_id == - // target_phantom.forward_node_id + // then a force loop is required (e.g. source_phantom.forward_segment_id == + // target_phantom.forward_segment_id // && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset()) // requires // a force loop, if the heaps have been initialized with positive offsets. @@ -760,7 +761,9 @@ template class BasicRoutingInterface bool NeedsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom) const { - return source_phantom.forward_node_id == target_phantom.forward_node_id && + return source_phantom.forward_segment_id.enabled && + target_phantom.forward_segment_id.enabled && + source_phantom.forward_segment_id.id == target_phantom.forward_segment_id.id && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset(); } @@ -768,7 +771,9 @@ template class BasicRoutingInterface bool NeedsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom) const { - return source_phantom.reverse_node_id == target_phantom.reverse_node_id && + return source_phantom.reverse_segment_id.enabled && + target_phantom.reverse_segment_id.enabled && + source_phantom.reverse_segment_id.id == target_phantom.reverse_segment_id.id && source_phantom.GetReverseWeightPlusOffset() > target_phantom.GetReverseWeightPlusOffset(); } @@ -812,30 +817,30 @@ template class BasicRoutingInterface BOOST_ASSERT(forward_heap.Empty()); BOOST_ASSERT(reverse_heap.Empty()); - if (source_phantom.forward_node_id != SPECIAL_NODEID) + if (source_phantom.forward_segment_id.enabled) { - forward_heap.Insert(source_phantom.forward_node_id, + forward_heap.Insert(source_phantom.forward_segment_id.id, -source_phantom.GetForwardWeightPlusOffset(), - source_phantom.forward_node_id); + source_phantom.forward_segment_id.id); } - if (source_phantom.reverse_node_id != SPECIAL_NODEID) + if (source_phantom.reverse_segment_id.enabled) { - forward_heap.Insert(source_phantom.reverse_node_id, + forward_heap.Insert(source_phantom.reverse_segment_id.id, -source_phantom.GetReverseWeightPlusOffset(), - source_phantom.reverse_node_id); + source_phantom.reverse_segment_id.id); } - if (target_phantom.forward_node_id != SPECIAL_NODEID) + if (target_phantom.forward_segment_id.enabled) { - reverse_heap.Insert(target_phantom.forward_node_id, + reverse_heap.Insert(target_phantom.forward_segment_id.id, target_phantom.GetForwardWeightPlusOffset(), - target_phantom.forward_node_id); + target_phantom.forward_segment_id.id); } - if (target_phantom.reverse_node_id != SPECIAL_NODEID) + if (target_phantom.reverse_segment_id.enabled) { - reverse_heap.Insert(target_phantom.reverse_node_id, + reverse_heap.Insert(target_phantom.reverse_segment_id.id, target_phantom.GetReverseWeightPlusOffset(), - target_phantom.reverse_node_id); + target_phantom.reverse_segment_id.id); } const bool constexpr DO_NOT_FORCE_LOOPS = @@ -866,30 +871,30 @@ template class BasicRoutingInterface BOOST_ASSERT(forward_heap.Empty()); BOOST_ASSERT(reverse_heap.Empty()); - if (source_phantom.forward_node_id != SPECIAL_NODEID) + if (source_phantom.forward_segment_id.enabled) { - forward_heap.Insert(source_phantom.forward_node_id, + forward_heap.Insert(source_phantom.forward_segment_id.id, -source_phantom.GetForwardWeightPlusOffset(), - source_phantom.forward_node_id); + source_phantom.forward_segment_id.id); } - if (source_phantom.reverse_node_id != SPECIAL_NODEID) + if (source_phantom.reverse_segment_id.enabled) { - forward_heap.Insert(source_phantom.reverse_node_id, + forward_heap.Insert(source_phantom.reverse_segment_id.id, -source_phantom.GetReverseWeightPlusOffset(), - source_phantom.reverse_node_id); + source_phantom.reverse_segment_id.id); } - if (target_phantom.forward_node_id != SPECIAL_NODEID) + if (target_phantom.forward_segment_id.enabled) { - reverse_heap.Insert(target_phantom.forward_node_id, + reverse_heap.Insert(target_phantom.forward_segment_id.id, target_phantom.GetForwardWeightPlusOffset(), - target_phantom.forward_node_id); + target_phantom.forward_segment_id.id); } - if (target_phantom.reverse_node_id != SPECIAL_NODEID) + if (target_phantom.reverse_segment_id.enabled) { - reverse_heap.Insert(target_phantom.reverse_node_id, + reverse_heap.Insert(target_phantom.reverse_segment_id.id, target_phantom.GetReverseWeightPlusOffset(), - target_phantom.reverse_node_id); + target_phantom.reverse_segment_id.id); } const bool constexpr DO_NOT_FORCE_LOOPS = diff --git a/include/engine/routing_algorithms/shortest_path.hpp b/include/engine/routing_algorithms/shortest_path.hpp index 0c0f99175..488c16522 100644 --- a/include/engine/routing_algorithms/shortest_path.hpp +++ b/include/engine/routing_algorithms/shortest_path.hpp @@ -56,29 +56,29 @@ class ShortestPathRouting final reverse_heap.Clear(); if (search_from_forward_node) { - forward_heap.Insert(source_phantom.forward_node_id, + forward_heap.Insert(source_phantom.forward_segment_id.id, total_distance_to_forward - source_phantom.GetForwardWeightPlusOffset(), - source_phantom.forward_node_id); + source_phantom.forward_segment_id.id); } if (search_from_reverse_node) { - forward_heap.Insert(source_phantom.reverse_node_id, + forward_heap.Insert(source_phantom.reverse_segment_id.id, total_distance_to_reverse - source_phantom.GetReverseWeightPlusOffset(), - source_phantom.reverse_node_id); + source_phantom.reverse_segment_id.id); } if (search_to_forward_node) { - reverse_heap.Insert(target_phantom.forward_node_id, + reverse_heap.Insert(target_phantom.forward_segment_id.id, target_phantom.GetForwardWeightPlusOffset(), - target_phantom.forward_node_id); + target_phantom.forward_segment_id.id); } if (search_to_reverse_node) { - reverse_heap.Insert(target_phantom.reverse_node_id, + reverse_heap.Insert(target_phantom.reverse_segment_id.id, target_phantom.GetReverseWeightPlusOffset(), - target_phantom.reverse_node_id); + target_phantom.reverse_segment_id.id); } BOOST_ASSERT(forward_heap.Size() > 0); @@ -88,8 +88,10 @@ class ShortestPathRouting final auto is_oneway_source = !(search_from_forward_node && search_from_reverse_node); auto is_oneway_target = !(search_to_forward_node && search_to_reverse_node); // we only enable loops here if we can't search from forward to backward node - auto needs_loop_forwad = is_oneway_source && super::NeedsLoopForward(source_phantom, target_phantom); - auto needs_loop_backwards = is_oneway_target && super::NeedsLoopBackwards(source_phantom, target_phantom); + auto needs_loop_forwad = + is_oneway_source && super::NeedsLoopForward(source_phantom, target_phantom); + auto needs_loop_backwards = + is_oneway_target && super::NeedsLoopBackwards(source_phantom, target_phantom); if (super::facade->GetCoreSize() > 0) { forward_core_heap.Clear(); @@ -97,7 +99,8 @@ class ShortestPathRouting final BOOST_ASSERT(forward_core_heap.Size() == 0); BOOST_ASSERT(reverse_core_heap.Size() == 0); super::SearchWithCore(forward_heap, reverse_heap, forward_core_heap, reverse_core_heap, - new_total_distance, leg_packed_path, needs_loop_forwad, needs_loop_backwards); + new_total_distance, leg_packed_path, needs_loop_forwad, + needs_loop_backwards); } else { @@ -130,23 +133,23 @@ class ShortestPathRouting final { forward_heap.Clear(); reverse_heap.Clear(); - reverse_heap.Insert(target_phantom.forward_node_id, + reverse_heap.Insert(target_phantom.forward_segment_id.id, target_phantom.GetForwardWeightPlusOffset(), - target_phantom.forward_node_id); + target_phantom.forward_segment_id.id); if (search_from_forward_node) { - forward_heap.Insert(source_phantom.forward_node_id, + forward_heap.Insert(source_phantom.forward_segment_id.id, total_distance_to_forward - source_phantom.GetForwardWeightPlusOffset(), - source_phantom.forward_node_id); + source_phantom.forward_segment_id.id); } if (search_from_reverse_node) { - forward_heap.Insert(source_phantom.reverse_node_id, + forward_heap.Insert(source_phantom.reverse_segment_id.id, total_distance_to_reverse - source_phantom.GetReverseWeightPlusOffset(), - source_phantom.reverse_node_id); + source_phantom.reverse_segment_id.id); } BOOST_ASSERT(forward_heap.Size() > 0); BOOST_ASSERT(reverse_heap.Size() > 0); @@ -176,22 +179,22 @@ class ShortestPathRouting final { forward_heap.Clear(); reverse_heap.Clear(); - reverse_heap.Insert(target_phantom.reverse_node_id, + reverse_heap.Insert(target_phantom.reverse_segment_id.id, target_phantom.GetReverseWeightPlusOffset(), - target_phantom.reverse_node_id); + target_phantom.reverse_segment_id.id); if (search_from_forward_node) { - forward_heap.Insert(source_phantom.forward_node_id, + forward_heap.Insert(source_phantom.forward_segment_id.id, total_distance_to_forward - source_phantom.GetForwardWeightPlusOffset(), - source_phantom.forward_node_id); + source_phantom.forward_segment_id.id); } if (search_from_reverse_node) { - forward_heap.Insert(source_phantom.reverse_node_id, + forward_heap.Insert(source_phantom.reverse_segment_id.id, total_distance_to_reverse - source_phantom.GetReverseWeightPlusOffset(), - source_phantom.reverse_node_id); + source_phantom.reverse_segment_id.id); } BOOST_ASSERT(forward_heap.Size() > 0); BOOST_ASSERT(reverse_heap.Size() > 0); @@ -234,10 +237,11 @@ class ShortestPathRouting final raw_route_data.unpacked_path_segments[current_leg]); raw_route_data.source_traversed_in_reverse.push_back( - (*leg_begin != phantom_nodes_vector[current_leg].source_phantom.forward_node_id)); + (*leg_begin != + phantom_nodes_vector[current_leg].source_phantom.forward_segment_id.id)); raw_route_data.target_traversed_in_reverse.push_back( (*std::prev(leg_end) != - phantom_nodes_vector[current_leg].target_phantom.forward_node_id)); + phantom_nodes_vector[current_leg].target_phantom.forward_segment_id.id)); } } @@ -245,6 +249,8 @@ class ShortestPathRouting final const boost::optional uturns, InternalRouteResult &raw_route_data) const { + const bool allow_u_turn_at_via = uturns ? *uturns : super::facade->GetUTurnsDefault(); + engine_working_data.InitializeOrClearFirstThreadLocalStorage( super::facade->GetNumberOfNodes()); engine_working_data.InitializeOrClearSecondThreadLocalStorage( @@ -258,9 +264,9 @@ class ShortestPathRouting final int total_distance_to_forward = 0; int total_distance_to_reverse = 0; bool search_from_forward_node = - phantom_nodes_vector.front().source_phantom.forward_node_id != SPECIAL_NODEID; + phantom_nodes_vector.front().source_phantom.forward_segment_id.enabled; bool search_from_reverse_node = - phantom_nodes_vector.front().source_phantom.reverse_node_id != SPECIAL_NODEID; + phantom_nodes_vector.front().source_phantom.reverse_segment_id.enabled; std::vector prev_packed_leg_to_forward; std::vector prev_packed_leg_to_reverse; @@ -270,8 +276,6 @@ class ShortestPathRouting final std::vector total_packed_path_to_reverse; std::vector packed_leg_to_reverse_begin; - const bool allow_u_turn_at_via = uturns ? *uturns : super::facade->GetUTurnsDefault(); - std::size_t current_leg = 0; // this implements a dynamic program that finds the shortest route through // a list of vias @@ -286,13 +290,11 @@ class ShortestPathRouting final const auto &source_phantom = phantom_node_pair.source_phantom; const auto &target_phantom = phantom_node_pair.target_phantom; - bool search_to_forward_node = target_phantom.forward_node_id != SPECIAL_NODEID; - bool search_to_reverse_node = target_phantom.reverse_node_id != SPECIAL_NODEID; + bool search_to_forward_node = target_phantom.forward_segment_id.enabled; + bool search_to_reverse_node = target_phantom.reverse_segment_id.enabled; - BOOST_ASSERT(!search_from_forward_node || - source_phantom.forward_node_id != SPECIAL_NODEID); - BOOST_ASSERT(!search_from_reverse_node || - source_phantom.reverse_node_id != SPECIAL_NODEID); + BOOST_ASSERT(!search_from_forward_node || source_phantom.forward_segment_id.enabled); + BOOST_ASSERT(!search_from_reverse_node || source_phantom.reverse_segment_id.enabled); BOOST_ASSERT(search_from_forward_node || search_from_reverse_node); @@ -308,14 +310,14 @@ class ShortestPathRouting final new_total_distance_to_forward, packed_leg_to_forward); // if only the reverse node is valid (e.g. when using the match plugin) we // actually need to move - if (target_phantom.forward_node_id == SPECIAL_NODEID) + if (target_phantom.forward_segment_id.enabled) { - BOOST_ASSERT(target_phantom.reverse_node_id != SPECIAL_NODEID); + BOOST_ASSERT(target_phantom.reverse_segment_id.enabled); new_total_distance_to_reverse = new_total_distance_to_forward; packed_leg_to_reverse = std::move(packed_leg_to_forward); new_total_distance_to_forward = INVALID_EDGE_WEIGHT; } - else if (target_phantom.reverse_node_id != SPECIAL_NODEID) + else if (target_phantom.reverse_segment_id.enabled) { new_total_distance_to_reverse = new_total_distance_to_forward; packed_leg_to_reverse = packed_leg_to_forward; @@ -346,16 +348,16 @@ class ShortestPathRouting final { bool forward_to_forward = (new_total_distance_to_forward != INVALID_EDGE_WEIGHT) && - packed_leg_to_forward.front() == source_phantom.forward_node_id; + packed_leg_to_forward.front() == source_phantom.forward_segment_id.id; bool reverse_to_forward = (new_total_distance_to_forward != INVALID_EDGE_WEIGHT) && - packed_leg_to_forward.front() == source_phantom.reverse_node_id; + packed_leg_to_forward.front() == source_phantom.reverse_segment_id.id; bool forward_to_reverse = (new_total_distance_to_reverse != INVALID_EDGE_WEIGHT) && - packed_leg_to_reverse.front() == source_phantom.forward_node_id; + packed_leg_to_reverse.front() == source_phantom.forward_segment_id.id; bool reverse_to_reverse = (new_total_distance_to_reverse != INVALID_EDGE_WEIGHT) && - packed_leg_to_reverse.front() == source_phantom.reverse_node_id; + packed_leg_to_reverse.front() == source_phantom.reverse_segment_id.id; BOOST_ASSERT(!forward_to_forward || !reverse_to_forward); BOOST_ASSERT(!forward_to_reverse || !reverse_to_reverse); @@ -390,7 +392,7 @@ class ShortestPathRouting final if (new_total_distance_to_forward != INVALID_EDGE_WEIGHT) { - BOOST_ASSERT(target_phantom.forward_node_id != SPECIAL_NODEID); + BOOST_ASSERT(target_phantom.forward_segment_id.enabled); packed_leg_to_forward_begin.push_back(total_packed_path_to_forward.size()); total_packed_path_to_forward.insert(total_packed_path_to_forward.end(), @@ -407,7 +409,7 @@ class ShortestPathRouting final if (new_total_distance_to_reverse != INVALID_EDGE_WEIGHT) { - BOOST_ASSERT(target_phantom.reverse_node_id != SPECIAL_NODEID); + BOOST_ASSERT(target_phantom.reverse_segment_id.enabled); packed_leg_to_reverse_begin.push_back(total_packed_path_to_reverse.size()); total_packed_path_to_reverse.insert(total_packed_path_to_reverse.end(), diff --git a/include/extractor/edge_based_node.hpp b/include/extractor/edge_based_node.hpp index 701e7ece2..699e9e77c 100644 --- a/include/extractor/edge_based_node.hpp +++ b/include/extractor/edge_based_node.hpp @@ -20,44 +20,44 @@ namespace extractor struct EdgeBasedNode { EdgeBasedNode() - : forward_edge_based_node_id(SPECIAL_NODEID), reverse_edge_based_node_id(SPECIAL_NODEID), - u(SPECIAL_NODEID), v(SPECIAL_NODEID), name_id(0), - forward_packed_geometry_id(SPECIAL_EDGEID), reverse_packed_geometry_id(SPECIAL_EDGEID), - component{INVALID_COMPONENTID, false}, + : forward_segment_id{SPECIAL_SEGMENTID, false}, + reverse_segment_id{SPECIAL_SEGMENTID, false}, u(SPECIAL_NODEID), + v(SPECIAL_NODEID), name_id(0), forward_packed_geometry_id(SPECIAL_EDGEID), + reverse_packed_geometry_id(SPECIAL_EDGEID), component{INVALID_COMPONENTID, false}, fwd_segment_position(std::numeric_limits::max()), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE), backward_travel_mode(TRAVEL_MODE_INACCESSIBLE) { } - explicit EdgeBasedNode(NodeID forward_edge_based_node_id, - NodeID reverse_edge_based_node_id, + explicit EdgeBasedNode(const SegmentID forward_segment_id_, + const SegmentID reverse_segment_id_, NodeID u, NodeID v, unsigned name_id, - unsigned forward_weight_or_packed_geometry_id_, - unsigned reverse_weight_or_packed_geometry_id_, + unsigned forward_geometry_id_, + unsigned reverse_geometry_id_, bool is_tiny_component, unsigned component_id, unsigned short fwd_segment_position, TravelMode forward_travel_mode, TravelMode backward_travel_mode) - : forward_edge_based_node_id(forward_edge_based_node_id), - reverse_edge_based_node_id(reverse_edge_based_node_id), u(u), v(v), name_id(name_id), - forward_packed_geometry_id(forward_weight_or_packed_geometry_id_), - reverse_packed_geometry_id(reverse_weight_or_packed_geometry_id_), + : forward_segment_id(forward_segment_id_), + reverse_segment_id(reverse_segment_id_), u(u), v(v), name_id(name_id), + forward_packed_geometry_id(forward_geometry_id_), + reverse_packed_geometry_id(reverse_geometry_id_), component{component_id, is_tiny_component}, fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode) { - BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) || - (reverse_edge_based_node_id != SPECIAL_NODEID)); + BOOST_ASSERT(forward_segment_id.enabled || + reverse_segment_id.enabled); } - NodeID forward_edge_based_node_id; // needed for edge-expanded graph - NodeID reverse_edge_based_node_id; // needed for edge-expanded graph - NodeID u; // indices into the coordinates array - NodeID v; // indices into the coordinates array - unsigned name_id; // id of the edge name + SegmentID forward_segment_id; // needed for edge-expanded graph + SegmentID reverse_segment_id; // needed for edge-expanded graph + NodeID u; // indices into the coordinates array + NodeID v; // indices into the coordinates array + unsigned name_id; // id of the edge name unsigned forward_packed_geometry_id; unsigned reverse_packed_geometry_id; diff --git a/include/util/static_rtree.hpp b/include/util/static_rtree.hpp index 6ef2a9d6c..43f41e29d 100644 --- a/include/util/static_rtree.hpp +++ b/include/util/static_rtree.hpp @@ -440,14 +440,8 @@ class StaticRTree // store phantom node in result vector results.push_back(std::move(current_segment)); - if (!use_segment.first) - { - results.back().forward_edge_based_node_id = SPECIAL_NODEID; - } - else if (!use_segment.second) - { - results.back().reverse_edge_based_node_id = SPECIAL_NODEID; - } + results.back().forward_segment_id.enabled &= use_segment.first; + results.back().reverse_segment_id.enabled &= use_segment.second; } } diff --git a/include/util/typedefs.hpp b/include/util/typedefs.hpp index 4db96ccaf..b3404bc2c 100644 --- a/include/util/typedefs.hpp +++ b/include/util/typedefs.hpp @@ -30,6 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "util/strong_typedef.hpp" +#include + #include #include @@ -56,9 +58,26 @@ using EdgeID = unsigned int; using EdgeWeight = int; static const NodeID SPECIAL_NODEID = std::numeric_limits::max(); +static const NodeID SPECIAL_SEGMENTID = std::numeric_limits::max(); static const EdgeID SPECIAL_EDGEID = std::numeric_limits::max(); static const unsigned INVALID_NAMEID = std::numeric_limits::max(); static const unsigned INVALID_COMPONENTID = 0; static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits::max(); +struct SegmentID +{ + SegmentID(const NodeID id_, const bool enabled_) : id{id_}, enabled{enabled_} + { + BOOST_ASSERT(!enabled || id != SPECIAL_SEGMENTID); + } + + NodeID id : 31; + bool enabled : 1; +}; + +// bit-fields are broken on Windows +#ifndef _MSC_VER +static_assert(sizeof(SegmentID) == 4, "SegmentID needs to be 4 bytes big"); +#endif + #endif /* TYPEDEFS_H */ diff --git a/src/engine/plugins/match.cpp b/src/engine/plugins/match.cpp index 777bdc814..1fff3fefc 100644 --- a/src/engine/plugins/match.cpp +++ b/src/engine/plugins/match.cpp @@ -56,10 +56,10 @@ void filterCandidates(const std::vector &coordinates, candidates.begin(), candidates.end(), [](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs) { - return lhs.phantom_node.forward_node_id < rhs.phantom_node.forward_node_id || - (lhs.phantom_node.forward_node_id == rhs.phantom_node.forward_node_id && - (lhs.phantom_node.reverse_node_id < rhs.phantom_node.reverse_node_id || - (lhs.phantom_node.reverse_node_id == rhs.phantom_node.reverse_node_id && + return lhs.phantom_node.forward_segment_id.id < rhs.phantom_node.forward_segment_id.id || + (lhs.phantom_node.forward_segment_id.id == rhs.phantom_node.forward_segment_id.id && + (lhs.phantom_node.reverse_segment_id.id < rhs.phantom_node.reverse_segment_id.id || + (lhs.phantom_node.reverse_segment_id.id == rhs.phantom_node.reverse_segment_id.id && lhs.distance < rhs.distance))); }); @@ -67,8 +67,8 @@ void filterCandidates(const std::vector &coordinates, candidates.begin(), candidates.end(), [](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs) { - return lhs.phantom_node.forward_node_id == rhs.phantom_node.forward_node_id && - lhs.phantom_node.reverse_node_id == rhs.phantom_node.reverse_node_id; + return lhs.phantom_node.forward_segment_id.id == rhs.phantom_node.forward_segment_id.id && + lhs.phantom_node.reverse_segment_id.id == rhs.phantom_node.reverse_segment_id.id; }); candidates.resize(new_end - candidates.begin()); @@ -78,15 +78,15 @@ void filterCandidates(const std::vector &coordinates, for (const auto i : util::irange(0, compact_size)) { // Split edge if it is bidirectional and append reverse direction to end of list - if (candidates[i].phantom_node.forward_node_id != SPECIAL_NODEID && - candidates[i].phantom_node.reverse_node_id != SPECIAL_NODEID) + if (candidates[i].phantom_node.forward_segment_id.enabled && + candidates[i].phantom_node.reverse_segment_id.enabled) { PhantomNode reverse_node(candidates[i].phantom_node); - reverse_node.forward_node_id = SPECIAL_NODEID; + reverse_node.forward_segment_id.enabled = false; candidates.push_back( PhantomNodeWithDistance{reverse_node, candidates[i].distance}); - candidates[i].phantom_node.reverse_node_id = SPECIAL_NODEID; + candidates[i].phantom_node.reverse_segment_id.enabled = false; } } } diff --git a/src/engine/plugins/tile.cpp b/src/engine/plugins/tile.cpp index f33a711d1..eb168852c 100644 --- a/src/engine/plugins/tile.cpp +++ b/src/engine/plugins/tile.cpp @@ -364,7 +364,7 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str }; // If this is a valid forward edge, go ahead and add it to the tile - if (forward_weight != 0 && edge.forward_edge_based_node_id != SPECIAL_NODEID) + if (forward_weight != 0 && edge.forward_segment_id.enabled) { std::int32_t start_x = 0; std::int32_t start_y = 0; @@ -383,7 +383,7 @@ Status TilePlugin::HandleRequest(const api::TileParameters ¶meters, std::str // Repeat the above for the coordinates reversed and using the `reverse` // properties - if (reverse_weight != 0 && edge.reverse_edge_based_node_id != SPECIAL_NODEID) + if (reverse_weight != 0 && edge.reverse_segment_id.enabled) { std::int32_t start_x = 0; std::int32_t start_y = 0; diff --git a/src/engine/plugins/viaroute.cpp b/src/engine/plugins/viaroute.cpp index 1c1cda4e3..ffd62b35b 100644 --- a/src/engine/plugins/viaroute.cpp +++ b/src/engine/plugins/viaroute.cpp @@ -50,20 +50,33 @@ Status ViaRoutePlugin::HandleRequest(const api::RouteParameters &route_parameter auto phantom_node_pairs = GetPhantomNodes(route_parameters); if (phantom_node_pairs.size() != route_parameters.coordinates.size()) { - return Error("NoSegment", - std::string("Could not find a matching segment for coordinate ") + - std::to_string(phantom_node_pairs.size()), + return Error("NoSegment", std::string("Could not find a matching segment for coordinate ") + + std::to_string(phantom_node_pairs.size()), json_result); } BOOST_ASSERT(phantom_node_pairs.size() == route_parameters.coordinates.size()); auto snapped_phantoms = SnapPhantomNodes(phantom_node_pairs); + const bool allow_u_turn_at_via = + route_parameters.uturns ? *route_parameters.uturns : facade.GetUTurnsDefault(); + InternalRouteResult raw_route; - auto build_phantom_pairs = [&raw_route](const PhantomNode &first_node, - const PhantomNode &second_node) + auto build_phantom_pairs = [&raw_route, allow_u_turn_at_via](const PhantomNode &first_node, + const PhantomNode &second_node) { raw_route.segment_end_coordinates.push_back(PhantomNodes{first_node, second_node}); + auto &last_inserted = raw_route.segment_end_coordinates.back(); + // enable forward direction if possible + if (last_inserted.source_phantom.forward_segment_id.id != SPECIAL_SEGMENTID) + { + last_inserted.source_phantom.forward_segment_id.enabled |= allow_u_turn_at_via; + } + // enable reverse direction if possible + if (last_inserted.source_phantom.reverse_segment_id.id != SPECIAL_SEGMENTID) + { + last_inserted.source_phantom.reverse_segment_id.enabled |= allow_u_turn_at_via; + } }; util::for_each_pair(snapped_phantoms, build_phantom_pairs); diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index bab868e26..4cbde57c7 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -122,18 +122,30 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI NodeID current_edge_source_coordinate_id = node_u; + const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id) + { + if (edge_based_node_id == SPECIAL_NODEID) + { + return SegmentID{SPECIAL_SEGMENTID, false}; + } + + return SegmentID{edge_based_node_id, true}; + }; + // traverse arrays from start and end respectively for (const auto i : util::irange(std::size_t{ 0 }, geometry_size)) { - BOOST_ASSERT(current_edge_source_coordinate_id == - m_compressed_edge_container.GetBucketReference( - edge_id_2)[geometry_size - 1 - i].node_id); + BOOST_ASSERT( + current_edge_source_coordinate_id == + m_compressed_edge_container.GetBucketReference(edge_id_2)[geometry_size - 1 - i] + .node_id); const NodeID current_edge_target_coordinate_id = forward_geometry[i].node_id; BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id); // build edges m_edge_based_node_list.emplace_back( - forward_data.edge_id, reverse_data.edge_id, current_edge_source_coordinate_id, + edge_id_to_segment_id(forward_data.edge_id), + edge_id_to_segment_id(reverse_data.edge_id), current_edge_source_coordinate_id, current_edge_target_coordinate_id, forward_data.name_id, m_compressed_edge_container.GetPositionForID(edge_id_1), m_compressed_edge_container.GetPositionForID(edge_id_2), false, INVALID_COMPONENTID, i, @@ -208,7 +220,8 @@ unsigned EdgeBasedGraphFactory::RenumberEdges() // oneway streets always require this self-loop. Other streets only if a u-turn plus // traversal // of the street takes longer than the loop - m_edge_based_node_weights.push_back(edge_data.distance + profile_properties.u_turn_penalty); + m_edge_based_node_weights.push_back(edge_data.distance + + profile_properties.u_turn_penalty); BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges()); edge_data.edge_id = numbered_edges_count; @@ -344,7 +357,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( distance += profile_properties.traffic_signal_penalty; } - const int turn_penalty = use_turn_function ? GetTurnPenalty(turn_angle, lua_state) : 0; + const int turn_penalty = + use_turn_function ? GetTurnPenalty(turn_angle, lua_state) : 0; const auto turn_instruction = turn.instruction; if (guidance::isUturn(turn_instruction)) diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 50f75aaa1..368867d38 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -108,7 +108,7 @@ int Extractor::run() util::SimpleLogger().Write() << "Parsing in progress.."; TIMER_START(parsing); - auto& main_context = scripting_environment.GetContex(); + auto &main_context = scripting_environment.GetContex(); // setup raster sources if (util::luaFunctionExists(main_context.state, "source_function")) @@ -163,7 +163,7 @@ int Extractor::run() { ExtractionNode result_node; ExtractionWay result_way; - auto& local_context = scripting_environment.GetContex(); + auto &local_context = scripting_environment.GetContex(); for (auto x = range.begin(), end = range.end(); x != end; ++x) { @@ -258,7 +258,7 @@ int Extractor::run() // movement (e.g. turn from A->B, and B->A) becomes an edge // - auto& main_context = scripting_environment.GetContex(); + auto &main_context = scripting_environment.GetContex(); util::SimpleLogger().Write() << "Generating edge-expanded graph representation"; @@ -269,8 +269,7 @@ int Extractor::run() std::vector node_is_startpoint; std::vector edge_based_node_weights; std::vector internal_to_external_node_map; - auto graph_size = BuildEdgeExpandedGraph(main_context.state, - main_context.properties, + auto graph_size = BuildEdgeExpandedGraph(main_context.state, main_context.properties, internal_to_external_node_map, edge_based_node_list, node_is_startpoint, edge_based_node_weights, edge_based_edge_list); @@ -317,7 +316,8 @@ int Extractor::run() return 0; } -void Extractor::WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const +void Extractor::WriteProfileProperties(const std::string &output_path, + const ProfileProperties &properties) const { boost::filesystem::ofstream out_stream(output_path); if (!out_stream) @@ -325,7 +325,7 @@ void Extractor::WriteProfileProperties(const std::string& output_path, const Pro throw util::exception("Could not open " + output_path + " for writing."); } - out_stream.write(reinterpret_cast(&properties), sizeof(properties)); + out_stream.write(reinterpret_cast(&properties), sizeof(properties)); } void Extractor::FindComponents(unsigned max_edge_id, @@ -375,12 +375,12 @@ void Extractor::FindComponents(unsigned max_edge_id, // connect forward and backward nodes of each edge for (const auto &node : input_nodes) { - if (node.reverse_edge_based_node_id != SPECIAL_NODEID) + if (node.reverse_segment_id.enabled) { - BOOST_ASSERT(node.forward_edge_based_node_id <= max_edge_id); - BOOST_ASSERT(node.reverse_edge_based_node_id <= max_edge_id); - edges.push_back({node.forward_edge_based_node_id, node.reverse_edge_based_node_id, {}}); - edges.push_back({node.reverse_edge_based_node_id, node.forward_edge_based_node_id, {}}); + BOOST_ASSERT(node.forward_segment_id.id <= max_edge_id); + BOOST_ASSERT(node.reverse_segment_id.id <= max_edge_id); + edges.push_back({node.forward_segment_id.id, node.reverse_segment_id.id, {}}); + edges.push_back({node.reverse_segment_id.id, node.forward_segment_id.id, {}}); } } @@ -396,10 +396,10 @@ void Extractor::FindComponents(unsigned max_edge_id, for (auto &node : input_nodes) { - auto forward_component = component_search.get_component_id(node.forward_edge_based_node_id); - BOOST_ASSERT(node.reverse_edge_based_node_id == SPECIAL_EDGEID || + auto forward_component = component_search.get_component_id(node.forward_segment_id.id); + BOOST_ASSERT(!node.reverse_segment_id.enabled || forward_component == - component_search.get_component_id(node.reverse_edge_based_node_id)); + component_search.get_component_id(node.reverse_segment_id.id)); const unsigned component_size = component_search.get_component_size(forward_component); node.component.is_tiny = component_size < config.small_component_size; @@ -468,8 +468,8 @@ Extractor::LoadNodeBasedGraph(std::unordered_set &barrier_nodes, \brief Building an edge-expanded graph from node-based input and turn restrictions */ std::pair -Extractor::BuildEdgeExpandedGraph(lua_State* lua_state, - const ProfileProperties& profile_properties, +Extractor::BuildEdgeExpandedGraph(lua_State *lua_state, + const ProfileProperties &profile_properties, std::vector &internal_to_external_node_map, std::vector &node_based_edge_list, std::vector &node_is_startpoint, diff --git a/unit_tests/util/static_rtree.cpp b/unit_tests/util/static_rtree.cpp index da1a46f66..afbe831f0 100644 --- a/unit_tests/util/static_rtree.cpp +++ b/unit_tests/util/static_rtree.cpp @@ -160,8 +160,8 @@ struct GraphFixture // so we have something to test against. Because this isn't a real // graph, the actual values aren't important, we just need something // to examine during tests. - d.forward_edge_based_node_id = pair.second; - d.reverse_edge_based_node_id = pair.first; + d.forward_segment_id = {pair.second, true}; + d.reverse_segment_id = {pair.first, true}; edges.emplace_back(d); } } @@ -416,8 +416,8 @@ BOOST_AUTO_TEST_CASE(bearing_tests) { auto results = query.NearestPhantomNodes(input, 5); BOOST_CHECK_EQUAL(results.size(), 2); - BOOST_CHECK_EQUAL(results.back().phantom_node.forward_node_id, 0); - BOOST_CHECK_EQUAL(results.back().phantom_node.reverse_node_id, 1); + BOOST_CHECK_EQUAL(results.back().phantom_node.forward_segment_id.id, 0); + BOOST_CHECK_EQUAL(results.back().phantom_node.reverse_segment_id.id, 1); } { @@ -428,10 +428,10 @@ BOOST_AUTO_TEST_CASE(bearing_tests) { auto results = query.NearestPhantomNodes(input, 5, 45, 10); BOOST_CHECK_EQUAL(results.size(), 2); - BOOST_CHECK_EQUAL(results[0].phantom_node.forward_node_id, 1); - BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_node_id, SPECIAL_NODEID); - BOOST_CHECK_EQUAL(results[1].phantom_node.forward_node_id, SPECIAL_NODEID); - BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_node_id, 1); + BOOST_CHECK_EQUAL(results[0].phantom_node.forward_segment_id.id, 1); + BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_segment_id.id, SPECIAL_SEGMENTID); + BOOST_CHECK_EQUAL(results[1].phantom_node.forward_segment_id.id, SPECIAL_SEGMENTID); + BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_segment_id.id, 1); } { @@ -447,10 +447,10 @@ BOOST_AUTO_TEST_CASE(bearing_tests) { auto results = query.NearestPhantomNodesInRange(input, 11000, 45, 10); BOOST_CHECK_EQUAL(results.size(), 2); - BOOST_CHECK_EQUAL(results[0].phantom_node.forward_node_id, 1); - BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_node_id, SPECIAL_NODEID); - BOOST_CHECK_EQUAL(results[1].phantom_node.forward_node_id, SPECIAL_NODEID); - BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_node_id, 1); + BOOST_CHECK_EQUAL(results[0].phantom_node.forward_segment_id.id, 1); + BOOST_CHECK_EQUAL(results[0].phantom_node.reverse_segment_id.id, SPECIAL_SEGMENTID); + BOOST_CHECK_EQUAL(results[1].phantom_node.forward_segment_id.id, SPECIAL_SEGMENTID); + BOOST_CHECK_EQUAL(results[1].phantom_node.reverse_segment_id.id, 1); } }