fix and refactor the selection of RouteNames

This commit is contained in:
Dennis Luxen 2014-06-06 11:30:12 +02:00
parent 1079bf7843
commit 01773c2a00

View File

@ -45,18 +45,36 @@ struct RouteNames
// construct routes names // construct routes names
template <class DataFacadeT, class SegmentT> struct ExtractRouteNames template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
{ {
private:
SegmentT PickNextLongestSegment(const std::vector<SegmentT> &segment_list,
const unsigned blocked_name_id) const
{
SegmentT result_segment;
result_segment.length = 0;
for (const SegmentT &segment : segment_list)
{
if (segment.name_id != blocked_name_id && segment.length > result_segment.length)
{
result_segment = segment;
}
}
return result_segment;
}
public:
RouteNames operator()(std::vector<SegmentT> &shortest_path_segments, RouteNames operator()(std::vector<SegmentT> &shortest_path_segments,
std::vector<SegmentT> &alternative_path_segments, std::vector<SegmentT> &alternative_path_segments,
const DataFacadeT *facade) const DataFacadeT *facade) const
{ {
RouteNames route_names; RouteNames route_names;
SegmentT shortest_segment_1, shortest_segment_2; SegmentT shortest_segment_1, shortest_segment_2;
SegmentT alternative_segment_1, alternative_segment_2; SegmentT alternative_segment_1, alternative_segment_2;
auto length_comperator = [](SegmentT a, SegmentT b) auto length_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.length > b.length; }; { return a.length > b.length; };
auto name_id_comperator = [](SegmentT a, SegmentT b) auto name_id_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.name_id < b.name_id; }; { return a.name_id < b.name_id; };
if (shortest_path_segments.empty()) if (shortest_path_segments.empty())
@ -64,6 +82,7 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
return route_names; return route_names;
} }
// pick the longest segment for the shortest path.
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), length_comperator); std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), length_comperator);
shortest_segment_1 = shortest_path_segments[0]; shortest_segment_1 = shortest_path_segments[0];
if (!alternative_path_segments.empty()) if (!alternative_path_segments.empty())
@ -71,10 +90,14 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
std::sort(alternative_path_segments.begin(), std::sort(alternative_path_segments.begin(),
alternative_path_segments.end(), alternative_path_segments.end(),
length_comperator); length_comperator);
// also pick the longest segment for the alternative path
alternative_segment_1 = alternative_path_segments[0]; alternative_segment_1 = alternative_path_segments[0];
} }
// compute the set difference (for shortest path) depending on names between shortest and
// alternative
std::vector<SegmentT> shortest_path_set_difference(shortest_path_segments.size()); std::vector<SegmentT> shortest_path_set_difference(shortest_path_segments.size());
std::vector<SegmentT> alternative_path_set_difference(alternative_path_segments.size());
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), name_id_comperator); std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), name_id_comperator);
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), name_id_comperator); std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), name_id_comperator);
std::set_difference(shortest_path_segments.begin(), std::set_difference(shortest_path_segments.begin(),
@ -83,42 +106,38 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
alternative_path_segments.end(), alternative_path_segments.end(),
shortest_path_set_difference.begin(), shortest_path_set_difference.begin(),
name_id_comperator); name_id_comperator);
int size_of_difference = shortest_path_set_difference.size();
if (size_of_difference)
{
int i = 0;
while (i < size_of_difference &&
shortest_path_set_difference[i].name_id == shortest_path_segments[0].name_id)
{
++i;
}
if (i < size_of_difference)
{
shortest_segment_2 = shortest_path_set_difference[i];
}
}
std::sort(shortest_path_set_difference.begin(),
shortest_path_set_difference.end(),
length_comperator);
shortest_segment_2 =
PickNextLongestSegment(shortest_path_set_difference, shortest_path_segments[0].name_id);
// compute the set difference (for alternative path) depending on names between shortest and
// alternative
// vectors are still sorted, no need to do again
BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(),
shortest_path_segments.end(),
name_id_comperator));
BOOST_ASSERT(std::is_sorted(alternative_path_segments.begin(),
alternative_path_segments.end(),
name_id_comperator));
std::vector<SegmentT> alternative_path_set_difference(alternative_path_segments.size());
std::set_difference(alternative_path_segments.begin(), std::set_difference(alternative_path_segments.begin(),
alternative_path_segments.end(), alternative_path_segments.end(),
shortest_path_segments.begin(), shortest_path_segments.begin(),
shortest_path_segments.end(), shortest_path_segments.end(),
alternative_path_set_difference.begin(), alternative_path_set_difference.begin(),
name_id_comperator); name_id_comperator);
size_of_difference = alternative_path_set_difference.size();
if (size_of_difference) std::sort(alternative_path_set_difference.begin(),
{ alternative_path_set_difference.end(),
int i = 0; length_comperator);
while (i < size_of_difference && alternative_segment_2 = PickNextLongestSegment(alternative_path_set_difference,
alternative_path_set_difference[i].name_id == alternative_path_segments[0].name_id);
alternative_path_segments[0].name_id)
{ // move the segments into the order in which they occur.
++i;
}
if (i < size_of_difference)
{
alternative_segment_2 = alternative_path_set_difference[i];
}
}
if (shortest_segment_1.position > shortest_segment_2.position) if (shortest_segment_1.position > shortest_segment_2.position)
{ {
std::swap(shortest_segment_1, shortest_segment_2); std::swap(shortest_segment_1, shortest_segment_2);
@ -127,6 +146,8 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
{ {
std::swap(alternative_segment_1, alternative_segment_2); std::swap(alternative_segment_1, alternative_segment_2);
} }
// fetching names for the selected segments
route_names.shortest_path_name_1 = route_names.shortest_path_name_1 =
facade->GetEscapedNameForNameID(shortest_segment_1.name_id); facade->GetEscapedNameForNameID(shortest_segment_1.name_id);
route_names.shortest_path_name_2 = route_names.shortest_path_name_2 =