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);
TurnInstruction turn_instruction = AnalyzeTurn(u, v, w);
if (turn_instruction == TurnInstructionsClass::UTurn)
if (turn_instruction == TurnInstruction::UTurn)
{
distance += speed_profile.uTurnPenalty;
}
@ -891,7 +891,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const NodeID w
) const {
if(u == w) {
return TurnInstructionsClass::UTurn;
return TurnInstruction::UTurn;
}
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);
if(!data1.contraFlow && data2.contraFlow) {
return TurnInstructionsClass::EnterAgainstAllowedDirection;
return TurnInstruction::EnterAgainstAllowedDirection;
}
if(data1.contraFlow && !data2.contraFlow) {
return TurnInstructionsClass::LeaveAgainstAllowedDirection;
return TurnInstruction::LeaveAgainstAllowedDirection;
}
//roundabouts need to be handled explicitely
@ -912,19 +912,19 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
//Is a turn possible? If yes, we stay on the roundabout!
if( 1 == m_node_based_graph->GetOutDegree(v) ) {
//No turn possible.
return TurnInstructionsClass::NoTurn;
return TurnInstruction::NoTurn;
}
return TurnInstructionsClass::StayOnRoundAbout;
return TurnInstruction::StayOnRoundAbout;
}
//Does turn start or end on roundabout?
if(data1.roundabout || data2.roundabout) {
//We are entering the roundabout
if( (!data1.roundabout) && data2.roundabout) {
return TurnInstructionsClass::EnterRoundAbout;
return TurnInstruction::EnterRoundAbout;
}
//We are leaving the 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
// more complex situations
if( 0 != data1.nameID ) {
return TurnInstructionsClass::NoTurn;
return TurnInstruction::NoTurn;
} else if (m_node_based_graph->GetOutDegree(v) <= 2) {
return TurnInstructionsClass::NoTurn;
return TurnInstruction::NoTurn;
}
}

View File

@ -47,7 +47,7 @@ struct OriginalEdgeData
OriginalEdgeData()
: via_node(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()
: node(std::numeric_limits<unsigned>::max()), name_id(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)
: node(no), name_id(na), segment_duration(dur), turn_instruction(tu)
PathData(NodeID node, unsigned name_id, TurnInstruction turn_instruction, unsigned segment_duration)
: node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction)
{
}
NodeID node;

View File

@ -62,7 +62,7 @@ struct SegmentInformation
const double length,
const TurnInstruction turn_instruction)
: 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
#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
{
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)
{
if (angle >= 23 && angle < 67)
{
return TurnSharpRight;
return TurnInstruction::TurnSharpRight;
}
if (angle >= 67 && angle < 113)
{
return TurnRight;
return TurnInstruction::TurnRight;
}
if (angle >= 113 && angle < 158)
{
return TurnSlightRight;
return TurnInstruction::TurnSlightRight;
}
if (angle >= 158 && angle < 202)
{
return GoStraight;
return TurnInstruction::GoStraight;
}
if (angle >= 202 && angle < 248)
{
return TurnSlightLeft;
return TurnInstruction::TurnSlightLeft;
}
if (angle >= 248 && angle < 292)
{
return TurnLeft;
return TurnInstruction::TurnLeft;
}
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 true;
}

View File

@ -68,7 +68,7 @@ void DescriptionFactory::SetStartSegment(const PhantomNode &source,
const bool source_traversed_in_reverse)
{
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,
@ -76,7 +76,7 @@ void DescriptionFactory::SetEndSegment(const PhantomNode &target,
{
target_phantom = target;
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,

View File

@ -119,7 +119,7 @@ class DescriptionFactory
// unsigned lastTurn = 0;
// for(unsigned i = 1; i < path_description.size(); ++i) {
// 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+";")
// || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;")
@ -129,7 +129,7 @@ class DescriptionFactory
// string1;
// for(; lastTurn != i; ++lastTurn)
// 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+";")
// || std::string::npos != string1.find(";"+string0)
// || std::string::npos != string1.find(string0+" ;")
@ -138,10 +138,10 @@ class DescriptionFactory
// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " <<
// string0;
// 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;
// }
// string0 = string1;
@ -159,7 +159,7 @@ class DescriptionFactory
path_description[segment_start_index].length = segment_length;
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);
segment_length = 0;
@ -175,7 +175,7 @@ class DescriptionFactory
{
path_description.pop_back();
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;
}
}
@ -184,7 +184,7 @@ class DescriptionFactory
if (path_description.size() > 2)
{
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;
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.
for (const SegmentInformation &segment : description_factory.path_description)
{
TurnInstruction current_instruction =
segment.turn_instruction & TurnInstructionsClass::InverseAccessRestrictionFlag;
TurnInstruction current_instruction = segment.turn_instruction;
entered_restricted_area_count += (current_instruction != segment.turn_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.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("[\"");
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("-");
intToString(round_about.leave_at_exit + 1, temp_instruction);
@ -466,7 +465,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
}
else
{
intToString(current_instruction, temp_instruction);
intToString(as_integer(current_instruction), 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()));
}
}
else if (TurnInstructionsClass::StayOnRoundAbout == current_instruction)
else if (TurnInstruction::StayOnRoundAbout == current_instruction)
{
++round_about.leave_at_exit;
}
@ -508,7 +507,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
if (INVALID_EDGE_WEIGHT != route_length)
{
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("\",\"");
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_
#define BASICROUTINGINTERFACE_H_
#ifndef BASIC_ROUTING_INTERFACE_H
#define BASIC_ROUTING_INTERFACE_H
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngineData.h"
@ -35,7 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/noncopyable.hpp>
#include <stack>
@ -46,30 +45,32 @@ SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap2;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap3;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap3;
template<class DataFacadeT>
class BasicRoutingInterface : boost::noncopyable {
private:
template <class DataFacadeT> class BasicRoutingInterface
{
private:
typedef typename DataFacadeT::EdgeData EdgeData;
protected:
DataFacadeT * facade;
public:
explicit BasicRoutingInterface( DataFacadeT * facade ) : facade(facade) { }
virtual ~BasicRoutingInterface(){ };
inline void RoutingStep(
SearchEngineData::QueryHeap & forward_heap,
SearchEngineData::QueryHeap & reverse_heap,
NodeID * middle_node_id,
int * upper_bound,
const bool forward_direction
) const
protected:
DataFacadeT *facade;
public:
BasicRoutingInterface() = delete;
BasicRoutingInterface(const BasicRoutingInterface &) = delete;
explicit BasicRoutingInterface(DataFacadeT *facade) : facade(facade) {}
virtual ~BasicRoutingInterface() {};
inline void RoutingStep(SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
NodeID *middle_node_id,
int *upper_bound,
const bool forward_direction) const
{
const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node);
if (reverse_heap.WasInserted(node))
{
const int new_distance = reverse_heap.GetKey(node) + distance;
if(new_distance < *upper_bound )
if (new_distance < *upper_bound)
{
if (new_distance >= 0)
{
@ -85,10 +86,10 @@ public:
return;
}
//Stalling
for (EdgeID edge = facade->BeginEdges( node ); edge < facade->EndEdges(node); ++edge)
// Stalling
for (EdgeID edge = facade->BeginEdges(node); edge < facade->EndEdges(node); ++edge)
{
const EdgeData & data = facade->GetEdgeData(edge);
const EdgeData &data = facade->GetEdgeData(edge);
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
if (reverse_flag)
{
@ -99,7 +100,7 @@ public:
if (forward_heap.WasInserted(to))
{
if(forward_heap.GetKey( to ) + edge_weight < distance)
if (forward_heap.GetKey(to) + edge_weight < distance)
{
return;
}
@ -107,9 +108,11 @@ 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);
if (forward_directionFlag)
{
@ -117,36 +120,41 @@ public:
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.distance;
BOOST_ASSERT_MSG( edge_weight > 0, "edge_weight invalid" );
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const int to_distance = distance + edge_weight;
//New Node discovered -> Add to Heap + Node Info Storage
if ( !forward_heap.WasInserted( to ) ) {
forward_heap.Insert( to, to_distance, node );
// New Node discovered -> Add to Heap + Node Info Storage
if (!forward_heap.WasInserted(to))
{
forward_heap.Insert(to, to_distance, node);
}
//Found a shorter Path -> Update distance
else if ( to_distance < forward_heap.GetKey( to ) ) {
//new parent
forward_heap.GetData( to ).parent = node;
forward_heap.DecreaseKey( to, to_distance );
// Found a shorter Path -> Update distance
else if (to_distance < forward_heap.GetKey(to))
{
// new parent
forward_heap.GetData(to).parent = node;
forward_heap.DecreaseKey(to, to_distance);
}
}
}
}
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 target_traversed_in_reverse = (packed_path.back() != phantom_node_pair.target_phantom.forward_node_id);
const bool start_traversed_in_reverse =
(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();
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.
for(unsigned i = packed_path_size-1; i > 0; --i){
recursion_stack.push(
std::make_pair(packed_path[i-1], packed_path[i])
);
// 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)
{
recursion_stack.emplace(packed_path[i - 1], packed_path[i]);
}
std::pair<NodeID, NodeID> edge;
@ -159,11 +167,12 @@ public:
// The above explanation unclear? Think!
EdgeID smaller_edge_id = SPECIAL_EDGEID;
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;
if ((facade->GetTarget(edge_id) == edge.second) &&
(weight < edge_weight) &&
if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward)
{
smaller_edge_id = edge_id;
@ -172,10 +181,13 @@ public:
}
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;
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;
edge_weight = weight;
@ -184,13 +196,13 @@ public:
}
BOOST_ASSERT_MSG(edge_weight != INVALID_EDGE_WEIGHT, "edge id invalid");
const EdgeData & ed = facade->GetEdgeData(smaller_edge_id);
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id);
if (ed.shortcut)
{//unpack
{ // unpack
const NodeID middle_node_id = ed.id;
//again, we need to this in reversed order
recursion_stack.push(std::make_pair(middle_node_id, edge.second));
recursion_stack.push(std::make_pair(edge.first, middle_node_id));
// again, we need to this in reversed order
recursion_stack.emplace(middle_node_id, edge.second);
recursion_stack.emplace(edge.first, middle_node_id);
}
else
{
@ -200,36 +212,33 @@ public:
if (!facade->EdgeIsCompressed(ed.id))
{
BOOST_ASSERT( !facade->EdgeIsCompressed(ed.id) );
unpacked_path.push_back(
PathData(
facade->GetGeometryIndexForEdgeID(ed.id),
name_index,
turn_instruction,
ed.distance
)
);
BOOST_ASSERT(!facade->EdgeIsCompressed(ed.id));
unpacked_path.emplace_back(facade->GetGeometryIndexForEdgeID(ed.id),
name_index,
turn_instruction,
ed.distance);
}
else
{
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();
BOOST_ASSERT(start_index >= 0);
BOOST_ASSERT(start_index <= end_index);
for (int i = start_index; i < end_index; ++i)
{
unpacked_path.push_back(
PathData(
id_vector[i],
name_index,
TurnInstructionsClass::NoTurn,
0
)
);
unpacked_path.emplace_back(PathData{
id_vector[i], name_index, TurnInstruction::NoTurn, 0});
}
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().segment_duration = ed.distance;
@ -239,18 +248,22 @@ public:
if (SPECIAL_EDGEID != phantom_node_pair.target_phantom.packed_geometry_id)
{
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)
{
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 end_index = phantom_node_pair.target_phantom.fwd_segment_position;
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)
{
@ -258,23 +271,21 @@ public:
end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
start_index = id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
end_index = id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
start_index =
id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
end_index =
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
}
BOOST_ASSERT(start_index >= 0);
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 );
unpacked_path.push_back(
PathData(
id_vector[i],
phantom_node_pair.target_phantom.name_id,
TurnInstructionsClass::NoTurn,
0
)
);
BOOST_ASSERT(i >= -1);
unpacked_path.emplace_back(PathData{id_vector[i],
phantom_node_pair.target_phantom.name_id,
TurnInstruction::NoTurn,
0});
}
}
@ -285,10 +296,10 @@ public:
// the last node.
if (unpacked_path.size() > 1)
{
const unsigned last_index = unpacked_path.size()-1;
const unsigned second_to_last_index = last_index -1;
const unsigned last_index = unpacked_path.size() - 1;
const unsigned second_to_last_index = last_index - 1;
//looks like a trivially true check but tests for underflow
// looks like a trivially true check but tests for underflow
BOOST_ASSERT(last_index > second_to_last_index);
if (unpacked_path[last_index].node == unpacked_path[second_to_last_index].node)
@ -299,10 +310,10 @@ 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;
recursion_stack.push(std::make_pair(s,t));
std::stack<std::pair<NodeID, NodeID>> recursion_stack;
recursion_stack.emplace(s, t);
std::pair<NodeID, NodeID> edge;
while (!recursion_stack.empty())
@ -312,14 +323,14 @@ public:
EdgeID smaller_edge_id = SPECIAL_EDGEID;
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;
if(
(facade->GetTarget(edge_id) == edge.second) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward
){
if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward)
{
smaller_edge_id = edge_id;
edge_weight = weight;
}
@ -327,10 +338,13 @@ public:
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;
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;
edge_weight = weight;
@ -339,59 +353,55 @@ public:
}
BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge weight invalid");
const EdgeData& ed = facade->GetEdgeData(smaller_edge_id);
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id);
if (ed.shortcut)
{//unpack
{ // unpack
const NodeID middle_node_id = ed.id;
//again, we need to this in reversed order
recursion_stack.push(std::make_pair(middle_node_id, edge.second));
recursion_stack.push(std::make_pair(edge.first, middle_node_id));
// again, we need to this in reversed order
recursion_stack.emplace(middle_node_id, edge.second);
recursion_stack.emplace(edge.first, middle_node_id);
}
else
{
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(
const SearchEngineData::QueryHeap & forward_heap,
const SearchEngineData::QueryHeap & reverse_heap,
const NodeID middle_node_id,
std::vector<NodeID> & packed_path
) const
inline void RetrievePackedPathFromHeap(const SearchEngineData::QueryHeap &forward_heap,
const SearchEngineData::QueryHeap &reverse_heap,
const NodeID middle_node_id,
std::vector<NodeID> &packed_path) const
{
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;
packed_path.push_back(current_node_id);
packed_path.emplace_back(current_node_id);
}
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;
while (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(
const SearchEngineData::QueryHeap & search_heap,
const NodeID middle_node_id,
std::vector<NodeID>& packed_path
) const
inline void RetrievePackedPathFromSingleHeap(const SearchEngineData::QueryHeap &search_heap,
const NodeID middle_node_id,
std::vector<NodeID> &packed_path) const
{
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;
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_
#define SHORTESTPATHROUTING_H_
#ifndef SHORTEST_PATH_ROUTING_H
#define SHORTEST_PATH_ROUTING_H
#include <boost/assert.hpp>
@ -34,33 +34,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/SearchEngineData.h"
#include "../typedefs.h"
template<class DataFacadeT>
class ShortestPathRouting : public BasicRoutingInterface<DataFacadeT>{
template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInterface<DataFacadeT>
{
typedef BasicRoutingInterface<DataFacadeT> super;
typedef SearchEngineData::QueryHeap QueryHeap;
SearchEngineData & engine_working_data;
SearchEngineData &engine_working_data;
public:
ShortestPathRouting(
DataFacadeT * facade,
SearchEngineData & engine_working_data
) :
super(facade),
engine_working_data(engine_working_data)
{ }
~ShortestPathRouting() { }
void operator()(
const std::vector<PhantomNodes> & phantom_nodes_vector,
RawRouteData & raw_route_data
) const
public:
ShortestPathRouting(DataFacadeT *facade, SearchEngineData &engine_working_data)
: super(facade), engine_working_data(engine_working_data)
{
for (const PhantomNodes & phantom_node_pair : phantom_nodes_vector)
}
~ShortestPathRouting() {}
void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
RawRouteData &raw_route_data) const
{
for (const PhantomNodes &phantom_node_pair : phantom_nodes_vector)
{
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) {
// raw_route_data.shortest_path_length = INT_MAX;
// raw_route_data.alternative_path_length = INT_MAX;
if (phantom_node_pair.AtLeastOnePhantomNodeIsInvalid())
{
return;
}
}
@ -70,283 +64,225 @@ public:
bool search_from_2nd_node = true;
NodeID middle1 = UINT_MAX;
NodeID middle2 = UINT_MAX;
std::vector<std::vector<NodeID> > packed_legs1(phantom_nodes_vector.size());
std::vector<std::vector<NodeID> > packed_legs2(phantom_nodes_vector.size());
std::vector<std::vector<NodeID>> packed_legs1(phantom_nodes_vector.size());
std::vector<std::vector<NodeID>> packed_legs2(phantom_nodes_vector.size());
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
super::facade->GetNumberOfNodes());
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
super::facade->GetNumberOfNodes());
engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
super::facade->GetNumberOfNodes());
QueryHeap & forward_heap1 = *(engine_working_data.forwardHeap);
QueryHeap & reverse_heap1 = *(engine_working_data.backwardHeap);
QueryHeap & forward_heap2 = *(engine_working_data.forwardHeap2);
QueryHeap & reverse_heap2 = *(engine_working_data.backwardHeap2);
QueryHeap &forward_heap1 = *(engine_working_data.forwardHeap);
QueryHeap &reverse_heap1 = *(engine_working_data.backwardHeap);
QueryHeap &forward_heap2 = *(engine_working_data.forwardHeap2);
QueryHeap &reverse_heap2 = *(engine_working_data.backwardHeap2);
int current_leg = 0;
//Get distance to next pair of target nodes.
for(const PhantomNodes & phantom_node_pair : phantom_nodes_vector)
// Get distance to next pair of target nodes.
for (const PhantomNodes &phantom_node_pair : phantom_nodes_vector)
{
forward_heap1.Clear(); forward_heap2.Clear();
reverse_heap1.Clear(); reverse_heap2.Clear();
forward_heap1.Clear();
forward_heap2.Clear();
reverse_heap1.Clear();
reverse_heap2.Clear();
int local_upper_bound1 = INT_MAX;
int local_upper_bound2 = INT_MAX;
middle1 = UINT_MAX;
middle2 = UINT_MAX;
//insert new starting nodes into forward heap, adjusted by previous distances.
if(
search_from_1st_node &&
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();
// insert new starting nodes into forward heap, adjusted by previous distances.
if (search_from_1st_node &&
phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID)
{
forward_heap1.Insert(
phantom_node_pair.source_phantom.forward_node_id,
distance1-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id
);
distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id);
forward_heap2.Insert(
phantom_node_pair.source_phantom.forward_node_id,
distance1-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id
);
distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id);
}
if(
search_from_2nd_node &&
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();
if (search_from_2nd_node &&
phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID)
{
forward_heap1.Insert(
phantom_node_pair.source_phantom.reverse_node_id,
distance2-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id
);
distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id);
forward_heap2.Insert(
phantom_node_pair.source_phantom.reverse_node_id,
distance2-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id
);
distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id);
}
//insert new backward nodes into backward heap, unadjusted.
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(
phantom_node_pair.target_phantom.forward_node_id,
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.target_phantom.forward_node_id
);
// insert new backward nodes into backward heap, unadjusted.
if (phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID)
{
reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_node_id,
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.target_phantom.forward_node_id);
}
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(
phantom_node_pair.target_phantom.reverse_node_id,
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.target_phantom.reverse_node_id
);
if (phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID)
{
reverse_heap2.Insert(phantom_node_pair.target_phantom.reverse_node_id,
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
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.
while(0 < (forward_heap1.Size() + reverse_heap1.Size() )){
if( 0 < forward_heap1.Size() ){
// run two-Target Dijkstra routing step.
while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
{
if (0 < forward_heap1.Size())
{
super::RoutingStep(
forward_heap1,
reverse_heap1,
&middle1,
&local_upper_bound1,
true
);
forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, true);
}
if( 0 < reverse_heap1.Size() ){
if (0 < reverse_heap1.Size())
{
super::RoutingStep(
reverse_heap1,
forward_heap1,
&middle1,
&local_upper_bound1,
false
);
reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, false);
}
}
if( !reverse_heap2.Empty() ) {
while(0 < (forward_heap2.Size() + reverse_heap2.Size() )){
if( 0 < forward_heap2.Size() ){
if (!reverse_heap2.Empty())
{
while (0 < (forward_heap2.Size() + reverse_heap2.Size()))
{
if (0 < forward_heap2.Size())
{
super::RoutingStep(
forward_heap2,
reverse_heap2,
&middle2,
&local_upper_bound2,
true
);
forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, true);
}
if( 0 < reverse_heap2.Size() ){
if (0 < reverse_heap2.Size())
{
super::RoutingStep(
reverse_heap2,
forward_heap2,
&middle2,
&local_upper_bound2,
false
);
reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, false);
}
}
}
//No path found for both target nodes?
if(
(INVALID_EDGE_WEIGHT == local_upper_bound1) &&
(INVALID_EDGE_WEIGHT == local_upper_bound2)
) {
// No path found for both target nodes?
if ((INVALID_EDGE_WEIGHT == local_upper_bound1) &&
(INVALID_EDGE_WEIGHT == local_upper_bound2))
{
raw_route_data.shortest_path_length = INVALID_EDGE_WEIGHT;
raw_route_data.alternative_path_length = INVALID_EDGE_WEIGHT;
return;
}
if( SPECIAL_NODEID == middle1 ) {
if (SPECIAL_NODEID == middle1)
{
search_from_1st_node = false;
}
if( SPECIAL_NODEID == middle2 ) {
if (SPECIAL_NODEID == middle2)
{
search_from_2nd_node = false;
}
//Was at most one of the two paths not found?
BOOST_ASSERT_MSG(
(INT_MAX != distance1 || INT_MAX != distance2),
"no path found"
);
// Was at most one of the two paths not found?
BOOST_ASSERT_MSG((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_leg2;
BOOST_ASSERT( (unsigned)current_leg < packed_legs1.size() );
BOOST_ASSERT( (unsigned)current_leg < packed_legs2.size() );
BOOST_ASSERT((unsigned)current_leg < packed_legs1.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(
forward_heap1,
reverse_heap1,
middle1,
temporary_packed_leg1
);
forward_heap1, reverse_heap1, middle1, temporary_packed_leg1);
}
if( INVALID_EDGE_WEIGHT != local_upper_bound2 ) {
if (INVALID_EDGE_WEIGHT != local_upper_bound2)
{
super::RetrievePackedPathFromHeap(
forward_heap2,
reverse_heap2,
middle2,
temporary_packed_leg2
);
forward_heap2, reverse_heap2, middle2, temporary_packed_leg2);
}
//if one of the paths was not found, replace it with the other one.
if( temporary_packed_leg1.empty() ) {
temporary_packed_leg1.insert(
temporary_packed_leg1.end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end()
);
// if one of the paths was not found, replace it with the other one.
if (temporary_packed_leg1.empty())
{
temporary_packed_leg1.insert(temporary_packed_leg1.end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end());
local_upper_bound1 = local_upper_bound2;
}
if( temporary_packed_leg2.empty() ) {
temporary_packed_leg2.insert(
temporary_packed_leg2.end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end()
);
if (temporary_packed_leg2.empty())
{
temporary_packed_leg2.insert(temporary_packed_leg2.end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end());
local_upper_bound2 = local_upper_bound1;
}
BOOST_ASSERT_MSG(
!temporary_packed_leg1.empty() ||
!temporary_packed_leg2.empty(),
"tempory packed paths empty"
);
BOOST_ASSERT_MSG(!temporary_packed_leg1.empty() || !temporary_packed_leg2.empty(),
"tempory packed paths empty");
BOOST_ASSERT(
(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_legs1[current_leg - 1].empty());
BOOST_ASSERT((0 == current_leg) || !packed_legs2[current_leg - 1].empty());
if( 0 < current_leg ) {
const NodeID end_id_of_segment1 = packed_legs1[current_leg-1].back();
const NodeID end_id_of_segment2 = packed_legs2[current_leg-1].back();
BOOST_ASSERT( !temporary_packed_leg1.empty() );
if (0 < current_leg)
{
const NodeID end_id_of_segment1 = packed_legs1[current_leg - 1].back();
const NodeID end_id_of_segment2 = packed_legs2[current_leg - 1].back();
BOOST_ASSERT(!temporary_packed_leg1.empty());
const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
if( ( end_id_of_segment1 != start_id_of_leg1 ) &&
( end_id_of_segment2 != start_id_of_leg2 )
) {
if ((end_id_of_segment1 != start_id_of_leg1) &&
(end_id_of_segment2 != start_id_of_leg2))
{
std::swap(temporary_packed_leg1, temporary_packed_leg2);
std::swap(local_upper_bound1, local_upper_bound2);
}
}
// 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_leg2 = temporary_packed_leg2.front();
if(
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_legs2 = packed_legs2[current_leg-1].back();
if( start_id_of_leg1 != last_id_of_packed_legs1 ) {
if (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_legs2 = packed_legs2[current_leg - 1].back();
if (start_id_of_leg1 != last_id_of_packed_legs1)
{
packed_legs1 = packed_legs2;
BOOST_ASSERT(
start_id_of_leg1 == temporary_packed_leg1.front()
);
} else
if( start_id_of_leg2 != last_id_of_packed_legs2 ) {
BOOST_ASSERT(start_id_of_leg1 == temporary_packed_leg1.front());
}
else if (start_id_of_leg2 != last_id_of_packed_legs2)
{
packed_legs2 = packed_legs1;
BOOST_ASSERT(
start_id_of_leg2 == temporary_packed_leg2.front()
);
BOOST_ASSERT(start_id_of_leg2 == temporary_packed_leg2.front());
}
}
}
BOOST_ASSERT(
packed_legs1.size() == packed_legs2.size()
);
BOOST_ASSERT(packed_legs1.size() == packed_legs2.size());
packed_legs1[current_leg].insert(
packed_legs1[current_leg].end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end()
);
BOOST_ASSERT(packed_legs1[current_leg].size() == temporary_packed_leg1.size() );
packed_legs2[current_leg].insert(
packed_legs2[current_leg].end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end()
);
BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size() );
packed_legs1[current_leg].insert(packed_legs1[current_leg].end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end());
BOOST_ASSERT(packed_legs1[current_leg].size() == temporary_packed_leg1.size());
packed_legs2[current_leg].insert(packed_legs2[current_leg].end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end());
BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size());
if(
(packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
phantom_node_pair.target_phantom.isBidirected()
) {
if ((packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
phantom_node_pair.target_phantom.isBidirected())
{
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_2nd_node &= !(last_node_id == phantom_node_pair.target_phantom.forward_node_id);
BOOST_ASSERT( search_from_1st_node != search_from_2nd_node );
search_from_1st_node &=
!(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);
}
distance1 = local_upper_bound1;
@ -356,45 +292,33 @@ public:
if (distance1 > distance2)
{
std::swap( packed_legs1, packed_legs2 );
std::swap(packed_legs1, packed_legs2);
}
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.unpacked_path_segments.resize(packed_legs1.size());
raw_route_data.source_traversed_in_reverse = (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);
raw_route_data.source_traversed_in_reverse =
(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)
{
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());
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(
// -- packed input
packed_legs1[i],
// -- start and end of (sub-)route
unpack_phantom_node_pair,
// -- 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);
}
};
#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;
}
// 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)
{
output.clear();