refactor list of const static int into scoped enum

This commit is contained in:
Dennis Luxen 2014-05-08 18:04:05 +02:00
parent b0ead129ca
commit f060dfda40
12 changed files with 846 additions and 941 deletions

View File

@ -794,7 +794,7 @@ void EdgeBasedGraphFactory::Run(
} }
const int turn_penalty = GetTurnPenalty(u, v, w, lua_state); const int turn_penalty = GetTurnPenalty(u, v, w, lua_state);
TurnInstruction turn_instruction = AnalyzeTurn(u, v, w); TurnInstruction turn_instruction = AnalyzeTurn(u, v, w);
if (turn_instruction == TurnInstructionsClass::UTurn) if (turn_instruction == TurnInstruction::UTurn)
{ {
distance += speed_profile.uTurnPenalty; distance += speed_profile.uTurnPenalty;
} }
@ -891,7 +891,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const NodeID w const NodeID w
) const { ) const {
if(u == w) { if(u == w) {
return TurnInstructionsClass::UTurn; return TurnInstruction::UTurn;
} }
const EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v); const EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v);
@ -901,10 +901,10 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2); const EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2);
if(!data1.contraFlow && data2.contraFlow) { if(!data1.contraFlow && data2.contraFlow) {
return TurnInstructionsClass::EnterAgainstAllowedDirection; return TurnInstruction::EnterAgainstAllowedDirection;
} }
if(data1.contraFlow && !data2.contraFlow) { if(data1.contraFlow && !data2.contraFlow) {
return TurnInstructionsClass::LeaveAgainstAllowedDirection; return TurnInstruction::LeaveAgainstAllowedDirection;
} }
//roundabouts need to be handled explicitely //roundabouts need to be handled explicitely
@ -912,19 +912,19 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
//Is a turn possible? If yes, we stay on the roundabout! //Is a turn possible? If yes, we stay on the roundabout!
if( 1 == m_node_based_graph->GetOutDegree(v) ) { if( 1 == m_node_based_graph->GetOutDegree(v) ) {
//No turn possible. //No turn possible.
return TurnInstructionsClass::NoTurn; return TurnInstruction::NoTurn;
} }
return TurnInstructionsClass::StayOnRoundAbout; return TurnInstruction::StayOnRoundAbout;
} }
//Does turn start or end on roundabout? //Does turn start or end on roundabout?
if(data1.roundabout || data2.roundabout) { if(data1.roundabout || data2.roundabout) {
//We are entering the roundabout //We are entering the roundabout
if( (!data1.roundabout) && data2.roundabout) { if( (!data1.roundabout) && data2.roundabout) {
return TurnInstructionsClass::EnterRoundAbout; return TurnInstruction::EnterRoundAbout;
} }
//We are leaving the roundabout //We are leaving the roundabout
if(data1.roundabout && (!data2.roundabout) ) { if(data1.roundabout && (!data2.roundabout) ) {
return TurnInstructionsClass::LeaveRoundAbout; return TurnInstruction::LeaveRoundAbout;
} }
} }
@ -934,9 +934,9 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
//TODO: Here we should also do a small graph exploration to check for //TODO: Here we should also do a small graph exploration to check for
// more complex situations // more complex situations
if( 0 != data1.nameID ) { if( 0 != data1.nameID ) {
return TurnInstructionsClass::NoTurn; return TurnInstruction::NoTurn;
} else if (m_node_based_graph->GetOutDegree(v) <= 2) { } else if (m_node_based_graph->GetOutDegree(v) <= 2) {
return TurnInstructionsClass::NoTurn; return TurnInstruction::NoTurn;
} }
} }

View File

@ -47,7 +47,7 @@ struct OriginalEdgeData
OriginalEdgeData() OriginalEdgeData()
: via_node(std::numeric_limits<unsigned>::max()), : via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()),
turn_instruction(std::numeric_limits<unsigned char>::max()), compressed_geometry(false) turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false)
{ {
} }

View File

@ -43,12 +43,12 @@ struct PathData
PathData() PathData()
: node(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()), : node(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()),
segment_duration(std::numeric_limits<unsigned>::max()), segment_duration(std::numeric_limits<unsigned>::max()),
turn_instruction(std::numeric_limits<TurnInstruction>::max()) turn_instruction(TurnInstruction::NoTurn)
{ {
} }
PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) PathData(NodeID node, unsigned name_id, TurnInstruction turn_instruction, unsigned segment_duration)
: node(no), name_id(na), segment_duration(dur), turn_instruction(tu) : node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction)
{ {
} }
NodeID node; NodeID node;

View File

@ -62,7 +62,7 @@ struct SegmentInformation
const double length, const double length,
const TurnInstruction turn_instruction) const TurnInstruction turn_instruction)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0), : location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), necessary(turn_instruction != 0) turn_instruction(turn_instruction), necessary(turn_instruction != TurnInstruction::NoTurn)
{ {
} }
}; };

View File

@ -28,76 +28,58 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef TURN_INSTRUCTIONS_H #ifndef TURN_INSTRUCTIONS_H
#define TURN_INSTRUCTIONS_H #define TURN_INSTRUCTIONS_H
typedef unsigned char TurnInstruction; enum class TurnInstruction : unsigned char
{
NoTurn = 0, GoStraight, TurnSlightRight, TurnRight, TurnSharpRight, UTurn,
TurnSharpLeft, TurnLeft, TurnSlightLeft, ReachViaPoint, HeadOn, EnterRoundAbout,
LeaveRoundAbout, StayOnRoundAbout, StartAtEndOfStreet, ReachedYourDestination,
EnterAgainstAllowedDirection, LeaveAgainstAllowedDirection,
InverseAccessRestrictionFlag = 127,
AccessRestrictionFlag = 128,
AccessRestrictionPenalty = 129
};
// This is a hack until c++0x is available enough to use scoped enums
struct TurnInstructionsClass struct TurnInstructionsClass
{ {
TurnInstructionsClass() = delete; TurnInstructionsClass() = delete;
TurnInstructionsClass(const TurnInstructionsClass&) = delete; TurnInstructionsClass(const TurnInstructionsClass&) = delete;
const static TurnInstruction NoTurn = 0; // Give no instruction at all
const static TurnInstruction GoStraight = 1; // Tell user to go straight!
const static TurnInstruction TurnSlightRight = 2;
const static TurnInstruction TurnRight = 3;
const static TurnInstruction TurnSharpRight = 4;
const static TurnInstruction UTurn = 5;
const static TurnInstruction TurnSharpLeft = 6;
const static TurnInstruction TurnLeft = 7;
const static TurnInstruction TurnSlightLeft = 8;
const static TurnInstruction ReachViaPoint = 9;
const static TurnInstruction HeadOn = 10;
const static TurnInstruction EnterRoundAbout = 11;
const static TurnInstruction LeaveRoundAbout = 12;
const static TurnInstruction StayOnRoundAbout = 13;
const static TurnInstruction StartAtEndOfStreet = 14;
const static TurnInstruction ReachedYourDestination = 15;
const static TurnInstruction EnterAgainstAllowedDirection = 16;
const static TurnInstruction LeaveAgainstAllowedDirection = 17;
const static TurnInstruction AccessRestrictionFlag = 128;
const static TurnInstruction InverseAccessRestrictionFlag =
0x7f; // ~128 does not work without a warning.
const static int AccessRestrictionPenalty =
1 << 15; // unrelated to the bit set in the restriction flag
static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle) static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle)
{ {
if (angle >= 23 && angle < 67) if (angle >= 23 && angle < 67)
{ {
return TurnSharpRight; return TurnInstruction::TurnSharpRight;
} }
if (angle >= 67 && angle < 113) if (angle >= 67 && angle < 113)
{ {
return TurnRight; return TurnInstruction::TurnRight;
} }
if (angle >= 113 && angle < 158) if (angle >= 113 && angle < 158)
{ {
return TurnSlightRight; return TurnInstruction::TurnSlightRight;
} }
if (angle >= 158 && angle < 202) if (angle >= 158 && angle < 202)
{ {
return GoStraight; return TurnInstruction::GoStraight;
} }
if (angle >= 202 && angle < 248) if (angle >= 202 && angle < 248)
{ {
return TurnSlightLeft; return TurnInstruction::TurnSlightLeft;
} }
if (angle >= 248 && angle < 292) if (angle >= 248 && angle < 292)
{ {
return TurnLeft; return TurnInstruction::TurnLeft;
} }
if (angle >= 292 && angle < 336) if (angle >= 292 && angle < 336)
{ {
return TurnSharpLeft; return TurnInstruction::TurnSharpLeft;
} }
return UTurn; return TurnInstruction::UTurn;
} }
static inline bool TurnIsNecessary(const short turnInstruction) static inline bool TurnIsNecessary(const TurnInstruction turn_instruction)
{ {
if (NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction) if (TurnInstruction::NoTurn == turn_instruction || TurnInstruction::StayOnRoundAbout == turn_instruction)
return false; return false;
return true; return true;
} }

View File

@ -68,7 +68,7 @@ void DescriptionFactory::SetStartSegment(const PhantomNode &source,
const bool source_traversed_in_reverse) const bool source_traversed_in_reverse)
{ {
start_phantom = source; start_phantom = source;
AppendSegment(source.location, PathData(0, source.name_id, 10, source.forward_weight)); AppendSegment(source.location, PathData(0, source.name_id, TurnInstruction::HeadOn, source.forward_weight));
} }
void DescriptionFactory::SetEndSegment(const PhantomNode &target, void DescriptionFactory::SetEndSegment(const PhantomNode &target,
@ -76,7 +76,7 @@ void DescriptionFactory::SetEndSegment(const PhantomNode &target,
{ {
target_phantom = target; target_phantom = target;
path_description.emplace_back( path_description.emplace_back(
target.location, target.name_id, 0, target.reverse_weight, 0, true); target.location, target.name_id, 0, target.reverse_weight, TurnInstruction::NoTurn, true);
} }
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate, void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,

View File

@ -119,7 +119,7 @@ class DescriptionFactory
// unsigned lastTurn = 0; // unsigned lastTurn = 0;
// for(unsigned i = 1; i < path_description.size(); ++i) { // for(unsigned i = 1; i < path_description.size(); ++i) {
// string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id); // string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id);
// if(TurnInstructionsClass::GoStraight == path_description[i].turn_instruction) { // if(TurnInstruction::GoStraight == path_description[i].turn_instruction) {
// if(std::string::npos != string0.find(string1+";") // if(std::string::npos != string0.find(string1+";")
// || std::string::npos != string0.find(";"+string1) // || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;") // || std::string::npos != string0.find(string1+" ;")
@ -129,7 +129,7 @@ class DescriptionFactory
// string1; // string1;
// for(; lastTurn != i; ++lastTurn) // for(; lastTurn != i; ++lastTurn)
// path_description[lastTurn].name_id = path_description[i].name_id; // path_description[lastTurn].name_id = path_description[i].name_id;
// path_description[i].turn_instruction = TurnInstructionsClass::NoTurn; // path_description[i].turn_instruction = TurnInstruction::NoTurn;
// } else if(std::string::npos != string1.find(string0+";") // } else if(std::string::npos != string1.find(string0+";")
// || std::string::npos != string1.find(";"+string0) // || std::string::npos != string1.find(";"+string0)
// || std::string::npos != string1.find(string0+" ;") // || std::string::npos != string1.find(string0+" ;")
@ -138,10 +138,10 @@ class DescriptionFactory
// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " << // SimpleLogger().Write() << "->prev correct: " << string1 << " contains " <<
// string0; // string0;
// path_description[i].name_id = path_description[i-1].name_id; // path_description[i].name_id = path_description[i-1].name_id;
// path_description[i].turn_instruction = TurnInstructionsClass::NoTurn; // path_description[i].turn_instruction = TurnInstruction::NoTurn;
// } // }
// } // }
// if (TurnInstructionsClass::NoTurn != path_description[i].turn_instruction) { // if (TurnInstruction::NoTurn != path_description[i].turn_instruction) {
// lastTurn = i; // lastTurn = i;
// } // }
// string0 = string1; // string0 = string1;
@ -159,7 +159,7 @@ class DescriptionFactory
path_description[segment_start_index].length = segment_length; path_description[segment_start_index].length = segment_length;
path_description[segment_start_index].duration = segment_duration; path_description[segment_start_index].duration = segment_duration;
if (TurnInstructionsClass::NoTurn != path_description[i].turn_instruction) if (TurnInstruction::NoTurn != path_description[i].turn_instruction)
{ {
BOOST_ASSERT(path_description[i].necessary); BOOST_ASSERT(path_description[i].necessary);
segment_length = 0; segment_length = 0;
@ -175,7 +175,7 @@ class DescriptionFactory
{ {
path_description.pop_back(); path_description.pop_back();
path_description.back().necessary = true; path_description.back().necessary = true;
path_description.back().turn_instruction = TurnInstructionsClass::NoTurn; path_description.back().turn_instruction = TurnInstruction::NoTurn;
target_phantom.name_id = (path_description.end() - 2)->name_id; target_phantom.name_id = (path_description.end() - 2)->name_id;
} }
} }
@ -184,7 +184,7 @@ class DescriptionFactory
if (path_description.size() > 2) if (path_description.size() > 2)
{ {
path_description.erase(path_description.begin()); path_description.erase(path_description.begin());
path_description[0].turn_instruction = TurnInstructionsClass::HeadOn; path_description[0].turn_instruction = TurnInstruction::HeadOn;
path_description[0].necessary = true; path_description[0].necessary = true;
start_phantom.name_id = path_description[0].name_id; start_phantom.name_id = path_description[0].name_id;
} }

View File

@ -438,12 +438,11 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
// Fetch data from Factory and generate a string from it. // Fetch data from Factory and generate a string from it.
for (const SegmentInformation &segment : description_factory.path_description) for (const SegmentInformation &segment : description_factory.path_description)
{ {
TurnInstruction current_instruction = TurnInstruction current_instruction = segment.turn_instruction;
segment.turn_instruction & TurnInstructionsClass::InverseAccessRestrictionFlag;
entered_restricted_area_count += (current_instruction != segment.turn_instruction); entered_restricted_area_count += (current_instruction != segment.turn_instruction);
if (TurnInstructionsClass::TurnIsNecessary(current_instruction)) if (TurnInstructionsClass::TurnIsNecessary(current_instruction))
{ {
if (TurnInstructionsClass::EnterRoundAbout == current_instruction) if (TurnInstruction::EnterRoundAbout == current_instruction)
{ {
round_about.name_id = segment.name_id; round_about.name_id = segment.name_id;
round_about.start_index = necessary_segments_running_index; round_about.start_index = necessary_segments_running_index;
@ -455,9 +454,9 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
reply.content.emplace_back(","); reply.content.emplace_back(",");
} }
reply.content.emplace_back("[\""); reply.content.emplace_back("[\"");
if (TurnInstructionsClass::LeaveRoundAbout == current_instruction) if (TurnInstruction::LeaveRoundAbout == current_instruction)
{ {
intToString(TurnInstructionsClass::EnterRoundAbout, temp_instruction); intToString(as_integer(TurnInstruction::EnterRoundAbout), temp_instruction);
reply.content.emplace_back(temp_instruction); reply.content.emplace_back(temp_instruction);
reply.content.emplace_back("-"); reply.content.emplace_back("-");
intToString(round_about.leave_at_exit + 1, temp_instruction); intToString(round_about.leave_at_exit + 1, temp_instruction);
@ -466,7 +465,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
} }
else else
{ {
intToString(current_instruction, temp_instruction); intToString(as_integer(current_instruction), temp_instruction);
reply.content.emplace_back(temp_instruction); reply.content.emplace_back(temp_instruction);
} }
@ -496,7 +495,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
Segment(segment.name_id, segment.length, route_segments_list.size())); Segment(segment.name_id, segment.length, route_segments_list.size()));
} }
} }
else if (TurnInstructionsClass::StayOnRoundAbout == current_instruction) else if (TurnInstruction::StayOnRoundAbout == current_instruction)
{ {
++round_about.leave_at_exit; ++round_about.leave_at_exit;
} }
@ -508,7 +507,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
if (INVALID_EDGE_WEIGHT != route_length) if (INVALID_EDGE_WEIGHT != route_length)
{ {
reply.content.emplace_back(",[\""); reply.content.emplace_back(",[\"");
intToString(TurnInstructionsClass::ReachedYourDestination, temp_instruction); intToString(as_integer(TurnInstruction::ReachedYourDestination), temp_instruction);
reply.content.emplace_back(temp_instruction); reply.content.emplace_back(temp_instruction);
reply.content.emplace_back("\",\""); reply.content.emplace_back("\",\"");
reply.content.emplace_back("\","); reply.content.emplace_back("\",");

File diff suppressed because it is too large Load Diff

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef BASICROUTINGINTERFACE_H_ #ifndef BASIC_ROUTING_INTERFACE_H
#define BASICROUTINGINTERFACE_H_ #define BASIC_ROUTING_INTERFACE_H
#include "../DataStructures/RawRouteData.h" #include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngineData.h" #include "../DataStructures/SearchEngineData.h"
@ -35,7 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/noncopyable.hpp>
#include <stack> #include <stack>
@ -46,23 +45,25 @@ SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap2;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap3; SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap3;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap3; SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap3;
template<class DataFacadeT> template <class DataFacadeT> class BasicRoutingInterface
class BasicRoutingInterface : boost::noncopyable { {
private: private:
typedef typename DataFacadeT::EdgeData EdgeData; typedef typename DataFacadeT::EdgeData EdgeData;
protected: protected:
DataFacadeT *facade; DataFacadeT *facade;
public: public:
BasicRoutingInterface() = delete;
BasicRoutingInterface(const BasicRoutingInterface &) = delete;
explicit BasicRoutingInterface(DataFacadeT *facade) : facade(facade) {} explicit BasicRoutingInterface(DataFacadeT *facade) : facade(facade) {}
virtual ~BasicRoutingInterface() {}; virtual ~BasicRoutingInterface() {};
inline void RoutingStep( inline void RoutingStep(SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap & forward_heap,
SearchEngineData::QueryHeap &reverse_heap, SearchEngineData::QueryHeap &reverse_heap,
NodeID *middle_node_id, NodeID *middle_node_id,
int *upper_bound, int *upper_bound,
const bool forward_direction const bool forward_direction) const
) const
{ {
const NodeID node = forward_heap.DeleteMin(); const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node); const int distance = forward_heap.GetKey(node);
@ -107,7 +108,9 @@ public:
} }
} }
for (EdgeID edge = facade->BeginEdges(node), end_edge = facade->EndEdges(node); edge < end_edge; ++edge) for (EdgeID edge = facade->BeginEdges(node), end_edge = facade->EndEdges(node);
edge < end_edge;
++edge)
{ {
const EdgeData &data = facade->GetEdgeData(edge); const EdgeData &data = facade->GetEdgeData(edge);
bool forward_directionFlag = (forward_direction ? data.forward : data.backward); bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
@ -121,11 +124,13 @@ public:
const int to_distance = distance + edge_weight; const int to_distance = distance + edge_weight;
// New Node discovered -> Add to Heap + Node Info Storage // New Node discovered -> Add to Heap + Node Info Storage
if ( !forward_heap.WasInserted( to ) ) { if (!forward_heap.WasInserted(to))
{
forward_heap.Insert(to, to_distance, node); forward_heap.Insert(to, to_distance, node);
} }
// Found a shorter Path -> Update distance // Found a shorter Path -> Update distance
else if ( to_distance < forward_heap.GetKey( to ) ) { else if (to_distance < forward_heap.GetKey(to))
{
// new parent // new parent
forward_heap.GetData(to).parent = node; forward_heap.GetData(to).parent = node;
forward_heap.DecreaseKey(to, to_distance); forward_heap.DecreaseKey(to, to_distance);
@ -134,19 +139,22 @@ public:
} }
} }
inline void UnpackPath(const std::vector<NodeID> & packed_path, const PhantomNodes & phantom_node_pair, std::vector<PathData> & unpacked_path) const inline void UnpackPath(const std::vector<NodeID> &packed_path,
const PhantomNodes &phantom_node_pair,
std::vector<PathData> &unpacked_path) const
{ {
const bool start_traversed_in_reverse = (packed_path.front() != phantom_node_pair.source_phantom.forward_node_id); const bool start_traversed_in_reverse =
const bool target_traversed_in_reverse = (packed_path.back() != phantom_node_pair.target_phantom.forward_node_id); (packed_path.front() != phantom_node_pair.source_phantom.forward_node_id);
const bool target_traversed_in_reverse =
(packed_path.back() != phantom_node_pair.target_phantom.forward_node_id);
const unsigned packed_path_size = packed_path.size(); const unsigned packed_path_size = packed_path.size();
std::stack<std::pair<NodeID, NodeID>> recursion_stack; std::stack<std::pair<NodeID, NodeID>> recursion_stack;
// We have to push the path in reverse order onto the stack because it's LIFO. // We have to push the path in reverse order onto the stack because it's LIFO.
for(unsigned i = packed_path_size-1; i > 0; --i){ for (unsigned i = packed_path_size - 1; i > 0; --i)
recursion_stack.push( {
std::make_pair(packed_path[i-1], packed_path[i]) recursion_stack.emplace(packed_path[i - 1], packed_path[i]);
);
} }
std::pair<NodeID, NodeID> edge; std::pair<NodeID, NodeID> edge;
@ -159,11 +167,12 @@ public:
// The above explanation unclear? Think! // The above explanation unclear? Think!
EdgeID smaller_edge_id = SPECIAL_EDGEID; EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = INT_MAX; int edge_weight = INT_MAX;
for (EdgeID edge_id = facade->BeginEdges(edge.first); edge_id < facade->EndEdges(edge.first); ++edge_id) for (EdgeID edge_id = facade->BeginEdges(edge.first);
edge_id < facade->EndEdges(edge.first);
++edge_id)
{ {
const int weight = facade->GetEdgeData(edge_id).distance; const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.second) && if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward) facade->GetEdgeData(edge_id).forward)
{ {
smaller_edge_id = edge_id; smaller_edge_id = edge_id;
@ -172,10 +181,13 @@ public:
} }
if (SPECIAL_EDGEID == smaller_edge_id) if (SPECIAL_EDGEID == smaller_edge_id)
{ {
for (EdgeID edge_id = facade->BeginEdges(edge.second); edge_id < facade->EndEdges(edge.second); ++edge_id) for (EdgeID edge_id = facade->BeginEdges(edge.second);
edge_id < facade->EndEdges(edge.second);
++edge_id)
{ {
const int weight = facade->GetEdgeData(edge_id).distance; const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) && facade->GetEdgeData(edge_id).backward) if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward)
{ {
smaller_edge_id = edge_id; smaller_edge_id = edge_id;
edge_weight = weight; edge_weight = weight;
@ -189,8 +201,8 @@ public:
{ // unpack { // unpack
const NodeID middle_node_id = ed.id; const NodeID middle_node_id = ed.id;
// again, we need to this in reversed order // again, we need to this in reversed order
recursion_stack.push(std::make_pair(middle_node_id, edge.second)); recursion_stack.emplace(middle_node_id, edge.second);
recursion_stack.push(std::make_pair(edge.first, middle_node_id)); recursion_stack.emplace(edge.first, middle_node_id);
} }
else else
{ {
@ -201,35 +213,32 @@ public:
if (!facade->EdgeIsCompressed(ed.id)) if (!facade->EdgeIsCompressed(ed.id))
{ {
BOOST_ASSERT(!facade->EdgeIsCompressed(ed.id)); BOOST_ASSERT(!facade->EdgeIsCompressed(ed.id));
unpacked_path.push_back( unpacked_path.emplace_back(facade->GetGeometryIndexForEdgeID(ed.id),
PathData(
facade->GetGeometryIndexForEdgeID(ed.id),
name_index, name_index,
turn_instruction, turn_instruction,
ed.distance ed.distance);
)
);
} }
else else
{ {
std::vector<unsigned> id_vector; std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(facade->GetGeometryIndexForEdgeID(ed.id), id_vector); facade->GetUncompressedGeometry(facade->GetGeometryIndexForEdgeID(ed.id),
id_vector);
const int start_index = ( unpacked_path.empty() ? ( ( start_traversed_in_reverse ) ? id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position - 1 : phantom_node_pair.source_phantom.fwd_segment_position ) : 0 ); const int start_index =
(unpacked_path.empty()
? ((start_traversed_in_reverse)
? id_vector.size() -
phantom_node_pair.source_phantom.fwd_segment_position - 1
: phantom_node_pair.source_phantom.fwd_segment_position)
: 0);
const int end_index = id_vector.size(); const int end_index = id_vector.size();
BOOST_ASSERT(start_index >= 0); BOOST_ASSERT(start_index >= 0);
BOOST_ASSERT(start_index <= end_index); BOOST_ASSERT(start_index <= end_index);
for (int i = start_index; i < end_index; ++i) for (int i = start_index; i < end_index; ++i)
{ {
unpacked_path.push_back( unpacked_path.emplace_back(PathData{
PathData( id_vector[i], name_index, TurnInstruction::NoTurn, 0});
id_vector[i],
name_index,
TurnInstructionsClass::NoTurn,
0
)
);
} }
unpacked_path.back().turn_instruction = turn_instruction; unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().segment_duration = ed.distance; unpacked_path.back().segment_duration = ed.distance;
@ -239,18 +248,22 @@ public:
if (SPECIAL_EDGEID != phantom_node_pair.target_phantom.packed_geometry_id) if (SPECIAL_EDGEID != phantom_node_pair.target_phantom.packed_geometry_id)
{ {
std::vector<unsigned> id_vector; std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.packed_geometry_id, id_vector); facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.packed_geometry_id,
id_vector);
if (target_traversed_in_reverse) if (target_traversed_in_reverse)
{ {
std::reverse(id_vector.begin(), id_vector.end()); std::reverse(id_vector.begin(), id_vector.end());
} }
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id == phantom_node_pair.target_phantom.packed_geometry_id) && unpacked_path.empty(); const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id ==
phantom_node_pair.target_phantom.packed_geometry_id) &&
unpacked_path.empty();
int start_index = 0; int start_index = 0;
int end_index = phantom_node_pair.target_phantom.fwd_segment_position; int end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse) if (target_traversed_in_reverse)
{ {
end_index = id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position; end_index =
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
} }
if (is_local_path) if (is_local_path)
{ {
@ -258,8 +271,10 @@ public:
end_index = phantom_node_pair.target_phantom.fwd_segment_position; end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse) if (target_traversed_in_reverse)
{ {
start_index = id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position; start_index =
end_index = id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position; id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
end_index =
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
} }
} }
@ -267,14 +282,10 @@ public:
for (int i = start_index; i != end_index; (start_index < end_index ? ++i : --i)) for (int i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
{ {
BOOST_ASSERT(i >= -1); BOOST_ASSERT(i >= -1);
unpacked_path.push_back( unpacked_path.emplace_back(PathData{id_vector[i],
PathData(
id_vector[i],
phantom_node_pair.target_phantom.name_id, phantom_node_pair.target_phantom.name_id,
TurnInstructionsClass::NoTurn, TurnInstruction::NoTurn,
0 0});
)
);
} }
} }
@ -302,7 +313,7 @@ public:
inline void UnpackEdge(const NodeID s, const NodeID t, std::vector<NodeID> &unpacked_path) const inline void UnpackEdge(const NodeID s, const NodeID t, std::vector<NodeID> &unpacked_path) const
{ {
std::stack<std::pair<NodeID, NodeID>> recursion_stack; std::stack<std::pair<NodeID, NodeID>> recursion_stack;
recursion_stack.push(std::make_pair(s,t)); recursion_stack.emplace(s, t);
std::pair<NodeID, NodeID> edge; std::pair<NodeID, NodeID> edge;
while (!recursion_stack.empty()) while (!recursion_stack.empty())
@ -312,14 +323,14 @@ public:
EdgeID smaller_edge_id = SPECIAL_EDGEID; EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = INT_MAX; int edge_weight = INT_MAX;
for (EdgeID edge_id = facade->BeginEdges(edge.first); edge_id < facade->EndEdges(edge.first); ++edge_id) for (EdgeID edge_id = facade->BeginEdges(edge.first);
edge_id < facade->EndEdges(edge.first);
++edge_id)
{ {
const int weight = facade->GetEdgeData(edge_id).distance; const int weight = facade->GetEdgeData(edge_id).distance;
if( if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
(facade->GetTarget(edge_id) == edge.second) && facade->GetEdgeData(edge_id).forward)
(weight < edge_weight) && {
facade->GetEdgeData(edge_id).forward
){
smaller_edge_id = edge_id; smaller_edge_id = edge_id;
edge_weight = weight; edge_weight = weight;
} }
@ -327,10 +338,13 @@ public:
if (SPECIAL_EDGEID == smaller_edge_id) if (SPECIAL_EDGEID == smaller_edge_id)
{ {
for (EdgeID edge_id = facade->BeginEdges(edge.second); edge_id < facade->EndEdges(edge.second); ++edge_id) for (EdgeID edge_id = facade->BeginEdges(edge.second);
edge_id < facade->EndEdges(edge.second);
++edge_id)
{ {
const int weight = facade->GetEdgeData(edge_id).distance; const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) && facade->GetEdgeData(edge_id).backward) if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward)
{ {
smaller_edge_id = edge_id; smaller_edge_id = edge_id;
edge_weight = weight; edge_weight = weight;
@ -344,54 +358,50 @@ public:
{ // unpack { // unpack
const NodeID middle_node_id = ed.id; const NodeID middle_node_id = ed.id;
// again, we need to this in reversed order // again, we need to this in reversed order
recursion_stack.push(std::make_pair(middle_node_id, edge.second)); recursion_stack.emplace(middle_node_id, edge.second);
recursion_stack.push(std::make_pair(edge.first, middle_node_id)); recursion_stack.emplace(edge.first, middle_node_id);
} }
else else
{ {
BOOST_ASSERT_MSG(!ed.shortcut, "edge must be shortcut"); BOOST_ASSERT_MSG(!ed.shortcut, "edge must be shortcut");
unpacked_path.push_back(edge.first ); unpacked_path.emplace_back(edge.first);
} }
} }
unpacked_path.push_back(t); unpacked_path.emplace_back(t);
} }
inline void RetrievePackedPathFromHeap( inline void RetrievePackedPathFromHeap(const SearchEngineData::QueryHeap &forward_heap,
const SearchEngineData::QueryHeap & forward_heap,
const SearchEngineData::QueryHeap &reverse_heap, const SearchEngineData::QueryHeap &reverse_heap,
const NodeID middle_node_id, const NodeID middle_node_id,
std::vector<NodeID> & packed_path std::vector<NodeID> &packed_path) const
) const
{ {
NodeID current_node_id = middle_node_id; NodeID current_node_id = middle_node_id;
while (current_node_id != forward_heap.GetData(current_node_id).parent) while (current_node_id != forward_heap.GetData(current_node_id).parent)
{ {
current_node_id = forward_heap.GetData(current_node_id).parent; current_node_id = forward_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id); packed_path.emplace_back(current_node_id);
} }
std::reverse(packed_path.begin(), packed_path.end()); std::reverse(packed_path.begin(), packed_path.end());
packed_path.push_back(middle_node_id); packed_path.emplace_back(middle_node_id);
current_node_id = middle_node_id; current_node_id = middle_node_id;
while (current_node_id != reverse_heap.GetData(current_node_id).parent) while (current_node_id != reverse_heap.GetData(current_node_id).parent)
{ {
current_node_id = reverse_heap.GetData(current_node_id).parent; current_node_id = reverse_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id); packed_path.emplace_back(current_node_id);
} }
} }
inline void RetrievePackedPathFromSingleHeap( inline void RetrievePackedPathFromSingleHeap(const SearchEngineData::QueryHeap &search_heap,
const SearchEngineData::QueryHeap & search_heap,
const NodeID middle_node_id, const NodeID middle_node_id,
std::vector<NodeID>& packed_path std::vector<NodeID> &packed_path) const
) const
{ {
NodeID current_node_id = middle_node_id; NodeID current_node_id = middle_node_id;
while (current_node_id != search_heap.GetData(current_node_id).parent) while (current_node_id != search_heap.GetData(current_node_id).parent)
{ {
current_node_id = search_heap.GetData(current_node_id).parent; current_node_id = search_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id); packed_path.emplace_back(current_node_id);
} }
} }
}; };
#endif /* BASICROUTINGINTERFACE_H_ */ #endif // BASIC_ROUTING_INTERFACE_H

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SHORTESTPATHROUTING_H_ #ifndef SHORTEST_PATH_ROUTING_H
#define SHORTESTPATHROUTING_H_ #define SHORTEST_PATH_ROUTING_H
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -34,33 +34,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/SearchEngineData.h" #include "../DataStructures/SearchEngineData.h"
#include "../typedefs.h" #include "../typedefs.h"
template<class DataFacadeT> template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInterface<DataFacadeT>
class ShortestPathRouting : public BasicRoutingInterface<DataFacadeT>{ {
typedef BasicRoutingInterface<DataFacadeT> super; typedef BasicRoutingInterface<DataFacadeT> super;
typedef SearchEngineData::QueryHeap QueryHeap; typedef SearchEngineData::QueryHeap QueryHeap;
SearchEngineData &engine_working_data; SearchEngineData &engine_working_data;
public: public:
ShortestPathRouting( ShortestPathRouting(DataFacadeT *facade, SearchEngineData &engine_working_data)
DataFacadeT * facade, : super(facade), engine_working_data(engine_working_data)
SearchEngineData & engine_working_data {
) : }
super(facade),
engine_working_data(engine_working_data)
{ }
~ShortestPathRouting() {} ~ShortestPathRouting() {}
void operator()( void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
const std::vector<PhantomNodes> & phantom_nodes_vector, RawRouteData &raw_route_data) const
RawRouteData & raw_route_data
) const
{ {
for (const PhantomNodes &phantom_node_pair : phantom_nodes_vector) for (const PhantomNodes &phantom_node_pair : phantom_nodes_vector)
{ {
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) { if (phantom_node_pair.AtLeastOnePhantomNodeIsInvalid())
// raw_route_data.shortest_path_length = INT_MAX; {
// raw_route_data.alternative_path_length = INT_MAX;
return; return;
} }
} }
@ -74,14 +68,11 @@ public:
std::vector<std::vector<NodeID>> packed_legs2(phantom_nodes_vector.size()); std::vector<std::vector<NodeID>> packed_legs2(phantom_nodes_vector.size());
engine_working_data.InitializeOrClearFirstThreadLocalStorage( engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes() super::facade->GetNumberOfNodes());
);
engine_working_data.InitializeOrClearSecondThreadLocalStorage( engine_working_data.InitializeOrClearSecondThreadLocalStorage(
super::facade->GetNumberOfNodes() super::facade->GetNumberOfNodes());
);
engine_working_data.InitializeOrClearThirdThreadLocalStorage( engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes() super::facade->GetNumberOfNodes());
);
QueryHeap &forward_heap1 = *(engine_working_data.forwardHeap); QueryHeap &forward_heap1 = *(engine_working_data.forwardHeap);
QueryHeap &reverse_heap1 = *(engine_working_data.backwardHeap); QueryHeap &reverse_heap1 = *(engine_working_data.backwardHeap);
@ -92,8 +83,10 @@ public:
// Get distance to next pair of target nodes. // Get distance to next pair of target nodes.
for (const PhantomNodes &phantom_node_pair : phantom_nodes_vector) for (const PhantomNodes &phantom_node_pair : phantom_nodes_vector)
{ {
forward_heap1.Clear(); forward_heap2.Clear(); forward_heap1.Clear();
reverse_heap1.Clear(); reverse_heap2.Clear(); forward_heap2.Clear();
reverse_heap1.Clear();
reverse_heap2.Clear();
int local_upper_bound1 = INT_MAX; int local_upper_bound1 = INT_MAX;
int local_upper_bound2 = INT_MAX; int local_upper_bound2 = INT_MAX;
@ -101,133 +94,97 @@ public:
middle2 = UINT_MAX; middle2 = UINT_MAX;
// insert new starting nodes into forward heap, adjusted by previous distances. // insert new starting nodes into forward heap, adjusted by previous distances.
if( if (search_from_1st_node &&
search_from_1st_node && phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID)
phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID {
) {
// SimpleLogger().Write(logDEBUG) << "fwd1 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.source_phantom.forward_node_id, phantom_node_pair.source_phantom.forward_node_id,
distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id phantom_node_pair.source_phantom.forward_node_id);
);
forward_heap2.Insert( forward_heap2.Insert(
phantom_node_pair.source_phantom.forward_node_id, phantom_node_pair.source_phantom.forward_node_id,
distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id phantom_node_pair.source_phantom.forward_node_id);
);
} }
if( if (search_from_2nd_node &&
search_from_2nd_node && phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID)
phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID {
) {
// SimpleLogger().Write(logDEBUG) << "fwd1 insert: " << phantom_node_pair.source_phantom.reverse_node_id << ", w: " << -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.source_phantom.reverse_node_id, phantom_node_pair.source_phantom.reverse_node_id,
distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id phantom_node_pair.source_phantom.reverse_node_id);
);
forward_heap2.Insert( forward_heap2.Insert(
phantom_node_pair.source_phantom.reverse_node_id, phantom_node_pair.source_phantom.reverse_node_id,
distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id phantom_node_pair.source_phantom.reverse_node_id);
);
} }
// insert new backward nodes into backward heap, unadjusted. // insert new backward nodes into backward heap, unadjusted.
if( phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID ) { if (phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID)
// SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.target_phantom.forward_node_id << ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(); {
reverse_heap1.Insert( reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_node_id,
phantom_node_pair.target_phantom.forward_node_id,
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(), phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.target_phantom.forward_node_id phantom_node_pair.target_phantom.forward_node_id);
);
} }
if( phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID ) { if (phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID)
// SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.target_phantom.reverse_node_id << ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(); {
reverse_heap2.Insert( reverse_heap2.Insert(phantom_node_pair.target_phantom.reverse_node_id,
phantom_node_pair.target_phantom.reverse_node_id,
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(), phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.target_phantom.reverse_node_id phantom_node_pair.target_phantom.reverse_node_id);
);
} }
// const int forward_offset = phantom_node_pair.ComputeForwardQueueOffset();
// const int forward_offset = super::ComputeForwardOffset(
// phantom_node_pair.source_phantom
// );
// const int reverse_offset = -phantom_node_pair.ComputeReverseQueueOffset();
// const int reverse_offset = super::ComputeReverseOffset(
// phantom_node_pair.target_phantom
// );
// run two-Target Dijkstra routing step. // run two-Target Dijkstra routing step.
while(0 < (forward_heap1.Size() + reverse_heap1.Size() )){ while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
if( 0 < forward_heap1.Size() ){ {
if (0 < forward_heap1.Size())
{
super::RoutingStep( super::RoutingStep(
forward_heap1, forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, true);
reverse_heap1,
&middle1,
&local_upper_bound1,
true
);
} }
if( 0 < reverse_heap1.Size() ){ if (0 < reverse_heap1.Size())
{
super::RoutingStep( super::RoutingStep(
reverse_heap1, reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, false);
forward_heap1,
&middle1,
&local_upper_bound1,
false
);
} }
} }
if( !reverse_heap2.Empty() ) { if (!reverse_heap2.Empty())
while(0 < (forward_heap2.Size() + reverse_heap2.Size() )){ {
if( 0 < forward_heap2.Size() ){ while (0 < (forward_heap2.Size() + reverse_heap2.Size()))
{
if (0 < forward_heap2.Size())
{
super::RoutingStep( super::RoutingStep(
forward_heap2, forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, true);
reverse_heap2,
&middle2,
&local_upper_bound2,
true
);
} }
if( 0 < reverse_heap2.Size() ){ if (0 < reverse_heap2.Size())
{
super::RoutingStep( super::RoutingStep(
reverse_heap2, reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, false);
forward_heap2,
&middle2,
&local_upper_bound2,
false
);
} }
} }
} }
// No path found for both target nodes? // No path found for both target nodes?
if( if ((INVALID_EDGE_WEIGHT == local_upper_bound1) &&
(INVALID_EDGE_WEIGHT == local_upper_bound1) && (INVALID_EDGE_WEIGHT == local_upper_bound2))
(INVALID_EDGE_WEIGHT == local_upper_bound2) {
) {
raw_route_data.shortest_path_length = INVALID_EDGE_WEIGHT; raw_route_data.shortest_path_length = INVALID_EDGE_WEIGHT;
raw_route_data.alternative_path_length = INVALID_EDGE_WEIGHT; raw_route_data.alternative_path_length = INVALID_EDGE_WEIGHT;
return; return;
} }
if( SPECIAL_NODEID == middle1 ) { if (SPECIAL_NODEID == middle1)
{
search_from_1st_node = false; search_from_1st_node = false;
} }
if( SPECIAL_NODEID == middle2 ) { if (SPECIAL_NODEID == middle2)
{
search_from_2nd_node = false; search_from_2nd_node = false;
} }
// Was at most one of the two paths not found? // Was at most one of the two paths not found?
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG((INT_MAX != distance1 || INT_MAX != distance2), "no path found");
(INT_MAX != distance1 || INT_MAX != distance2),
"no path found"
);
// Unpack paths if they exist // Unpack paths if they exist
std::vector<NodeID> temporary_packed_leg1; std::vector<NodeID> temporary_packed_leg1;
@ -236,116 +193,95 @@ public:
BOOST_ASSERT((unsigned)current_leg < packed_legs1.size()); BOOST_ASSERT((unsigned)current_leg < packed_legs1.size());
BOOST_ASSERT((unsigned)current_leg < packed_legs2.size()); BOOST_ASSERT((unsigned)current_leg < packed_legs2.size());
if( INVALID_EDGE_WEIGHT != local_upper_bound1 ) { if (INVALID_EDGE_WEIGHT != local_upper_bound1)
{
super::RetrievePackedPathFromHeap( super::RetrievePackedPathFromHeap(
forward_heap1, forward_heap1, reverse_heap1, middle1, temporary_packed_leg1);
reverse_heap1,
middle1,
temporary_packed_leg1
);
} }
if( INVALID_EDGE_WEIGHT != local_upper_bound2 ) { if (INVALID_EDGE_WEIGHT != local_upper_bound2)
{
super::RetrievePackedPathFromHeap( super::RetrievePackedPathFromHeap(
forward_heap2, forward_heap2, reverse_heap2, middle2, temporary_packed_leg2);
reverse_heap2,
middle2,
temporary_packed_leg2
);
} }
// if one of the paths was not found, replace it with the other one. // if one of the paths was not found, replace it with the other one.
if( temporary_packed_leg1.empty() ) { if (temporary_packed_leg1.empty())
temporary_packed_leg1.insert( {
temporary_packed_leg1.end(), temporary_packed_leg1.insert(temporary_packed_leg1.end(),
temporary_packed_leg2.begin(), temporary_packed_leg2.begin(),
temporary_packed_leg2.end() temporary_packed_leg2.end());
);
local_upper_bound1 = local_upper_bound2; local_upper_bound1 = local_upper_bound2;
} }
if( temporary_packed_leg2.empty() ) { if (temporary_packed_leg2.empty())
temporary_packed_leg2.insert( {
temporary_packed_leg2.end(), temporary_packed_leg2.insert(temporary_packed_leg2.end(),
temporary_packed_leg1.begin(), temporary_packed_leg1.begin(),
temporary_packed_leg1.end() temporary_packed_leg1.end());
);
local_upper_bound2 = local_upper_bound1; local_upper_bound2 = local_upper_bound1;
} }
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(!temporary_packed_leg1.empty() || !temporary_packed_leg2.empty(),
!temporary_packed_leg1.empty() || "tempory packed paths empty");
!temporary_packed_leg2.empty(),
"tempory packed paths empty"
);
BOOST_ASSERT( BOOST_ASSERT((0 == current_leg) || !packed_legs1[current_leg - 1].empty());
(0 == current_leg) || !packed_legs1[current_leg-1].empty() BOOST_ASSERT((0 == current_leg) || !packed_legs2[current_leg - 1].empty());
);
BOOST_ASSERT(
(0 == current_leg) || !packed_legs2[current_leg-1].empty()
);
if( 0 < current_leg ) { if (0 < current_leg)
{
const NodeID end_id_of_segment1 = packed_legs1[current_leg - 1].back(); const NodeID end_id_of_segment1 = packed_legs1[current_leg - 1].back();
const NodeID end_id_of_segment2 = packed_legs2[current_leg - 1].back(); const NodeID end_id_of_segment2 = packed_legs2[current_leg - 1].back();
BOOST_ASSERT(!temporary_packed_leg1.empty()); BOOST_ASSERT(!temporary_packed_leg1.empty());
const NodeID start_id_of_leg1 = temporary_packed_leg1.front(); const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
const NodeID start_id_of_leg2 = temporary_packed_leg2.front(); const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
if ((end_id_of_segment1 != start_id_of_leg1) && if ((end_id_of_segment1 != start_id_of_leg1) &&
( end_id_of_segment2 != start_id_of_leg2 ) (end_id_of_segment2 != start_id_of_leg2))
) { {
std::swap(temporary_packed_leg1, temporary_packed_leg2); std::swap(temporary_packed_leg1, temporary_packed_leg2);
std::swap(local_upper_bound1, local_upper_bound2); std::swap(local_upper_bound1, local_upper_bound2);
} }
} }
// remove one path if both legs end at the same segment // remove one path if both legs end at the same segment
if( 0 < current_leg ) { if (0 < current_leg)
{
const NodeID start_id_of_leg1 = temporary_packed_leg1.front(); const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
const NodeID start_id_of_leg2 = temporary_packed_leg2.front(); const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
if( if (start_id_of_leg1 == start_id_of_leg2)
start_id_of_leg1 == start_id_of_leg2 {
) {
const NodeID last_id_of_packed_legs1 = packed_legs1[current_leg - 1].back(); const NodeID last_id_of_packed_legs1 = packed_legs1[current_leg - 1].back();
const NodeID last_id_of_packed_legs2 = packed_legs2[current_leg - 1].back(); const NodeID last_id_of_packed_legs2 = packed_legs2[current_leg - 1].back();
if( start_id_of_leg1 != last_id_of_packed_legs1 ) { if (start_id_of_leg1 != last_id_of_packed_legs1)
{
packed_legs1 = packed_legs2; packed_legs1 = packed_legs2;
BOOST_ASSERT( BOOST_ASSERT(start_id_of_leg1 == temporary_packed_leg1.front());
start_id_of_leg1 == temporary_packed_leg1.front() }
); else if (start_id_of_leg2 != last_id_of_packed_legs2)
} else {
if( start_id_of_leg2 != last_id_of_packed_legs2 ) {
packed_legs2 = packed_legs1; packed_legs2 = packed_legs1;
BOOST_ASSERT( BOOST_ASSERT(start_id_of_leg2 == temporary_packed_leg2.front());
start_id_of_leg2 == temporary_packed_leg2.front()
);
} }
} }
} }
BOOST_ASSERT( BOOST_ASSERT(packed_legs1.size() == packed_legs2.size());
packed_legs1.size() == packed_legs2.size()
);
packed_legs1[current_leg].insert( packed_legs1[current_leg].insert(packed_legs1[current_leg].end(),
packed_legs1[current_leg].end(),
temporary_packed_leg1.begin(), temporary_packed_leg1.begin(),
temporary_packed_leg1.end() temporary_packed_leg1.end());
);
BOOST_ASSERT(packed_legs1[current_leg].size() == temporary_packed_leg1.size()); BOOST_ASSERT(packed_legs1[current_leg].size() == temporary_packed_leg1.size());
packed_legs2[current_leg].insert( packed_legs2[current_leg].insert(packed_legs2[current_leg].end(),
packed_legs2[current_leg].end(),
temporary_packed_leg2.begin(), temporary_packed_leg2.begin(),
temporary_packed_leg2.end() temporary_packed_leg2.end());
);
BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size()); BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size());
if( if ((packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
(packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) && phantom_node_pair.target_phantom.isBidirected())
phantom_node_pair.target_phantom.isBidirected() {
) {
const NodeID last_node_id = packed_legs2[current_leg].back(); const NodeID last_node_id = packed_legs2[current_leg].back();
search_from_1st_node &= !(last_node_id == phantom_node_pair.target_phantom.reverse_node_id); search_from_1st_node &=
search_from_2nd_node &= !(last_node_id == phantom_node_pair.target_phantom.forward_node_id); !(last_node_id == phantom_node_pair.target_phantom.reverse_node_id);
search_from_2nd_node &=
!(last_node_id == phantom_node_pair.target_phantom.forward_node_id);
BOOST_ASSERT(search_from_1st_node != search_from_2nd_node); BOOST_ASSERT(search_from_1st_node != search_from_2nd_node);
} }
@ -359,42 +295,30 @@ public:
std::swap(packed_legs1, packed_legs2); std::swap(packed_legs1, packed_legs2);
} }
raw_route_data.unpacked_path_segments.resize(packed_legs1.size()); raw_route_data.unpacked_path_segments.resize(packed_legs1.size());
// const int start_offset = ( packed_legs1[0].front() == phantom_nodes_vector.front().source_phantom.forward_node_id ? 1 : -1 )*phantom_nodes_vector.front().source_phantom.fwd_segment_position;
raw_route_data.source_traversed_in_reverse = (packed_legs1.front().front() != phantom_nodes_vector.front().source_phantom.forward_node_id); raw_route_data.source_traversed_in_reverse =
raw_route_data.target_traversed_in_reverse = (packed_legs1.back().back() != phantom_nodes_vector.back().target_phantom.forward_node_id); (packed_legs1.front().front() !=
phantom_nodes_vector.front().source_phantom.forward_node_id);
raw_route_data.target_traversed_in_reverse =
(packed_legs1.back().back() !=
phantom_nodes_vector.back().target_phantom.forward_node_id);
for (unsigned i = 0; i < packed_legs1.size(); ++i) for (unsigned i = 0; i < packed_legs1.size(); ++i)
{ {
BOOST_ASSERT(!phantom_nodes_vector.empty()); BOOST_ASSERT(!phantom_nodes_vector.empty());
// const bool at_beginning = (packed_legs1[i] == packed_legs1.front());
// const bool at_end = (packed_legs1[i] == packed_legs1.back());
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size()); BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size());
PhantomNodes unpack_phantom_node_pair = phantom_nodes_vector[i]; PhantomNodes unpack_phantom_node_pair = phantom_nodes_vector[i];
// if (!at_beginning)
// {
// unpack_phantom_node_pair.source_phantom.packed_geometry_id = SPECIAL_EDGEID;
// unpack_phantom_node_pair.source_phantom.fwd_segment_position = 0;
// }
// if (!at_end)
// {
// unpack_phantom_node_pair.target_phantom.packed_geometry_id = SPECIAL_EDGEID;
// unpack_phantom_node_pair.target_phantom.fwd_segment_position = 0;
// }
super::UnpackPath( super::UnpackPath(
// -- packed input // -- packed input
packed_legs1[i], packed_legs1[i],
// -- start and end of (sub-)route // -- start and end of (sub-)route
unpack_phantom_node_pair, unpack_phantom_node_pair,
// -- unpacked output // -- unpacked output
raw_route_data.unpacked_path_segments[i] raw_route_data.unpacked_path_segments[i]);
);
} }
raw_route_data.shortest_path_length = std::min(distance1, distance2); raw_route_data.shortest_path_length = std::min(distance1, distance2);
} }
}; };
#endif /* SHORTESTPATHROUTING_H_ */ #endif /* SHORTEST_PATH_ROUTING_H */

View File

@ -72,6 +72,14 @@ template <int length, int precision> static inline char *printInt(char *buffer,
return buffer; return buffer;
} }
// convert scoped enums to integers
template <typename Enumeration>
auto as_integer(Enumeration const value)
-> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
static inline void intToString(const int value, std::string &output) static inline void intToString(const int value, std::string &output)
{ {
output.clear(); output.clear();