osrm-backend/src/engine/routing_algorithms/routing_base.cpp
2018-08-02 12:19:24 +02:00

112 lines
4.8 KiB
C++

#include "engine/routing_algorithms/routing_base.hpp"
namespace osrm
{
namespace engine
{
namespace routing_algorithms
{
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom)
{
return source_phantom.IsValidForwardSource() && target_phantom.IsValidForwardTarget() &&
source_phantom.forward_segment_id.id == target_phantom.forward_segment_id.id &&
source_phantom.GetForwardWeightPlusOffset() >
target_phantom.GetForwardWeightPlusOffset();
}
bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom)
{
return source_phantom.IsValidReverseSource() && target_phantom.IsValidReverseTarget() &&
source_phantom.reverse_segment_id.id == target_phantom.reverse_segment_id.id &&
source_phantom.GetReverseWeightPlusOffset() >
target_phantom.GetReverseWeightPlusOffset();
}
bool needsLoopForward(const PhantomNodes &phantoms)
{
return needsLoopForward(phantoms.source_phantom, phantoms.target_phantom);
}
bool needsLoopBackwards(const PhantomNodes &phantoms)
{
return needsLoopBackwards(phantoms.source_phantom, phantoms.target_phantom);
}
EdgeDistance adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
const EdgeDistance uncorrected_distance)
{
EdgeDistance distance = uncorrected_distance;
if (!path.empty())
{
// check the direction of travel to figure out how to calculate the offset to/from
// the source/target
if (source_phantom.forward_segment_id.id == path.front())
{
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
// -->s <-- subtract offset to start at source
// ......... <-- want this distance as result
// entry 0---1---2---3--- <-- 3 is exit node
distance -= source_phantom.GetForwardDistance();
}
else if (source_phantom.reverse_segment_id.id == path.front())
{
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
// s<------- <-- subtract offset to start at source
// ... <-- want this distance
// entry 0---1---2---3 <-- 3 is exit node
distance -= source_phantom.GetReverseDistance();
}
if (target_phantom.forward_segment_id.id == path.back())
{
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
// ++>t <-- add offset to get to target
// ................ <-- want this distance as result
// entry 0---1---2---3--- <-- 3 is exit node
distance += target_phantom.GetForwardDistance();
}
else if (target_phantom.reverse_segment_id.id == path.back())
{
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
// <++t <-- add offset to get from target
// ................ <-- want this distance as result
// entry 0---1---2---3--- <-- 3 is exit node
distance += target_phantom.GetReverseDistance();
}
}
else
{
// there is no shortcut to unpack. source and target are on the same EBG Node.
// if the offset of the target is greater than the offset of the source, subtract it
if (target_phantom.GetForwardDistance() > source_phantom.GetForwardDistance())
{
// --------->t <-- offsets
// ->s <-- subtract source offset from target offset
// ......... <-- want this distance as result
// entry 0---1---2---3--- <-- 3 is exit node
distance = target_phantom.GetForwardDistance() - source_phantom.GetForwardDistance();
}
else
{
// s<--- <-- offsets
// t<--------- <-- subtract source offset from target offset
// ...... <-- want this distance as result
// entry 0---1---2---3--- <-- 3 is exit node
distance = target_phantom.GetReverseDistance() - source_phantom.GetReverseDistance();
}
}
BOOST_ASSERT_MSG(distance >= 0 || distance > -1.0f,
"Distance correction generated negative number");
// guard against underflow errors caused by rounding
distance = std::max(EdgeDistance{0}, distance);
return distance;
}
} // namespace routing_algorithms
} // namespace engine
} // namespace osrm