refactor route name extraction into its own class, fix name extraction
This commit is contained in:
parent
a69b3535a5
commit
da5eec1c5f
143
Algorithms/ExtractRouteNames.h
Normal file
143
Algorithms/ExtractRouteNames.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXTRACT_ROUTE_NAMES_H
|
||||||
|
#define EXTRACT_ROUTE_NAMES_H
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct RouteNames
|
||||||
|
{
|
||||||
|
std::string shortest_path_name_1;
|
||||||
|
std::string shortest_path_name_2;
|
||||||
|
std::string alternative_path_name_1;
|
||||||
|
std::string alternative_path_name_2;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
|
||||||
|
{
|
||||||
|
// TODO: break into function object with several functions, i.e. simplify
|
||||||
|
// construct routes names
|
||||||
|
RouteNames operator()(std::vector<SegmentT> &shortest_path_segments,
|
||||||
|
std::vector<SegmentT> &alternative_path_segments,
|
||||||
|
const DataFacadeT *facade)
|
||||||
|
{
|
||||||
|
RouteNames route_names;
|
||||||
|
|
||||||
|
SegmentT shortest_segment_1, shortest_segment_2;
|
||||||
|
SegmentT alternative_segment_1, alternative_segment_2;
|
||||||
|
|
||||||
|
auto length_comperator = [](SegmentT a, SegmentT b)
|
||||||
|
{ return a.length > b.length; };
|
||||||
|
auto name_id_comperator = [](SegmentT a, SegmentT b)
|
||||||
|
{ return a.name_id < b.name_id; };
|
||||||
|
|
||||||
|
if (shortest_path_segments.empty())
|
||||||
|
{
|
||||||
|
return route_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), length_comperator);
|
||||||
|
shortest_segment_1 = shortest_path_segments[0];
|
||||||
|
if (!alternative_path_segments.empty())
|
||||||
|
{
|
||||||
|
std::sort(alternative_path_segments.begin(),
|
||||||
|
alternative_path_segments.end(),
|
||||||
|
length_comperator);
|
||||||
|
alternative_segment_1 = alternative_path_segments[0];
|
||||||
|
}
|
||||||
|
std::vector<SegmentT> shortest_path_set_difference(shortest_path_segments.size());
|
||||||
|
std::vector<SegmentT> alternative_path_set_difference(alternative_path_segments.size());
|
||||||
|
std::set_difference(shortest_path_segments.begin(),
|
||||||
|
shortest_path_segments.end(),
|
||||||
|
alternative_path_segments.begin(),
|
||||||
|
alternative_path_segments.end(),
|
||||||
|
shortest_path_set_difference.begin(),
|
||||||
|
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::set_difference(alternative_path_segments.begin(),
|
||||||
|
alternative_path_segments.end(),
|
||||||
|
shortest_path_segments.begin(),
|
||||||
|
shortest_path_segments.end(),
|
||||||
|
alternative_path_set_difference.begin(),
|
||||||
|
name_id_comperator);
|
||||||
|
size_of_difference = alternative_path_set_difference.size();
|
||||||
|
if (size_of_difference)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (i < size_of_difference &&
|
||||||
|
alternative_path_set_difference[i].name_id ==
|
||||||
|
alternative_path_segments[0].name_id)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (i < size_of_difference)
|
||||||
|
{
|
||||||
|
alternative_segment_2 = alternative_path_set_difference[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shortest_segment_1.position > shortest_segment_2.position)
|
||||||
|
{
|
||||||
|
std::swap(shortest_segment_1, shortest_segment_2);
|
||||||
|
}
|
||||||
|
if (alternative_segment_1.position > alternative_segment_2.position)
|
||||||
|
{
|
||||||
|
std::swap(alternative_segment_1, alternative_segment_2);
|
||||||
|
}
|
||||||
|
route_names.shortest_path_name_1 =
|
||||||
|
facade->GetEscapedNameForNameID(shortest_segment_1.name_id);
|
||||||
|
route_names.shortest_path_name_2 =
|
||||||
|
facade->GetEscapedNameForNameID(shortest_segment_2.name_id);
|
||||||
|
|
||||||
|
route_names.alternative_path_name_1 =
|
||||||
|
facade->GetEscapedNameForNameID(alternative_segment_1.name_id);
|
||||||
|
route_names.alternative_path_name_2 =
|
||||||
|
facade->GetEscapedNameForNameID(alternative_segment_2.name_id);
|
||||||
|
|
||||||
|
return route_names;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EXTRACT_ROUTE_NAMES_H
|
@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "BaseDescriptor.h"
|
#include "BaseDescriptor.h"
|
||||||
#include "DescriptionFactory.h"
|
#include "DescriptionFactory.h"
|
||||||
#include "../Algorithms/ObjectToBase64.h"
|
#include "../Algorithms/ObjectToBase64.h"
|
||||||
|
#include "../Algorithms/ExtractRouteNames.h"
|
||||||
#include "../DataStructures/JSONContainer.h"
|
#include "../DataStructures/JSONContainer.h"
|
||||||
#include "../DataStructures/SegmentInformation.h"
|
#include "../DataStructures/SegmentInformation.h"
|
||||||
#include "../DataStructures/TurnInstructions.h"
|
#include "../DataStructures/TurnInstructions.h"
|
||||||
@ -46,8 +47,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
// TODO: initalize in c'tor
|
// TODO: initalize in c'tor
|
||||||
DataFacadeT *facade;
|
DataFacadeT *facade;
|
||||||
DescriptorConfig config;
|
DescriptorConfig config;
|
||||||
DescriptionFactory description_factory;
|
DescriptionFactory description_factory, alternate_description_factory;
|
||||||
DescriptionFactory alternate_description_factory;
|
|
||||||
FixedPointCoordinate current;
|
FixedPointCoordinate current;
|
||||||
unsigned entered_restricted_area_count;
|
unsigned entered_restricted_area_count;
|
||||||
struct RoundAbout
|
struct RoundAbout
|
||||||
@ -68,14 +68,8 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
};
|
};
|
||||||
std::vector<Segment> shortest_path_segments, alternative_path_segments;
|
std::vector<Segment> shortest_path_segments, alternative_path_segments;
|
||||||
std::vector<unsigned> shortest_leg_end_indices, alternative_leg_end_indices;
|
std::vector<unsigned> shortest_leg_end_indices, alternative_leg_end_indices;
|
||||||
|
ExtractRouteNames<DataFacadeT, Segment> GenerateRouteNames;
|
||||||
|
|
||||||
struct RouteNames
|
|
||||||
{
|
|
||||||
std::string shortest_path_name_1;
|
|
||||||
std::string shortest_path_name_2;
|
|
||||||
std::string alternative_path_name_1;
|
|
||||||
std::string alternative_path_name_2;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JSONDescriptor() : facade(nullptr), entered_restricted_area_count(0)
|
JSONDescriptor() : facade(nullptr), entered_restricted_area_count(0)
|
||||||
@ -166,14 +160,6 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
json_route_summary.values["end_point"] = facade->GetEscapedNameForNameID(description_factory.summary.target_name_id);
|
json_route_summary.values["end_point"] = facade->GetEscapedNameForNameID(description_factory.summary.target_name_id);
|
||||||
json_result.values["route_summary"] = json_route_summary;
|
json_result.values["route_summary"] = json_route_summary;
|
||||||
|
|
||||||
// Get Names for both routes
|
|
||||||
RouteNames route_names;
|
|
||||||
JSON::Array json_route_names;
|
|
||||||
GetRouteNames(shortest_path_segments, alternative_path_segments, facade, route_names);
|
|
||||||
json_route_names.values.push_back(route_names.shortest_path_name_1);
|
|
||||||
json_route_names.values.push_back(route_names.shortest_path_name_2);
|
|
||||||
json_result.values["route_name"] = json_route_names;
|
|
||||||
|
|
||||||
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
|
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
|
||||||
|
|
||||||
JSON::Array json_via_points_array;
|
JSON::Array json_via_points_array;
|
||||||
@ -244,16 +230,25 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
json_altenative_indices_array.values.push_back(0);
|
json_altenative_indices_array.values.push_back(0);
|
||||||
json_altenative_indices_array.values.push_back(alternate_description_factory.path_description.size());
|
json_altenative_indices_array.values.push_back(alternate_description_factory.path_description.size());
|
||||||
json_result.values["alternative_indices"] = json_altenative_indices_array;
|
json_result.values["alternative_indices"] = json_altenative_indices_array;
|
||||||
|
} else {
|
||||||
|
json_result.values["found_alternative"] = JSON::False();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Names for both routes
|
||||||
|
RouteNames route_names = GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade);
|
||||||
|
JSON::Array json_route_names;
|
||||||
|
json_route_names.values.push_back(route_names.shortest_path_name_1);
|
||||||
|
json_route_names.values.push_back(route_names.shortest_path_name_2);
|
||||||
|
json_result.values["route_name"] = json_route_names;
|
||||||
|
|
||||||
|
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
|
||||||
|
{
|
||||||
JSON::Array json_alternate_names_array;
|
JSON::Array json_alternate_names_array;
|
||||||
JSON::Array json_alternate_names;
|
JSON::Array json_alternate_names;
|
||||||
json_alternate_names.values.push_back(route_names.alternative_path_name_1);
|
json_alternate_names.values.push_back(route_names.alternative_path_name_1);
|
||||||
json_alternate_names.values.push_back(route_names.alternative_path_name_2);
|
json_alternate_names.values.push_back(route_names.alternative_path_name_2);
|
||||||
json_alternate_names_array.values.push_back(json_alternate_names);
|
json_alternate_names_array.values.push_back(json_alternate_names);
|
||||||
json_result.values["alternative_names"] = json_alternate_names_array;
|
json_result.values["alternative_names"] = json_alternate_names_array;
|
||||||
|
|
||||||
} else {
|
|
||||||
json_result.values["found_alternative"] = JSON::False();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON::Object json_hint_object;
|
JSON::Object json_hint_object;
|
||||||
@ -277,96 +272,6 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
SimpleLogger().Write(logDEBUG) << "rendering took: " << TIMER_MSEC(route_render);
|
SimpleLogger().Write(logDEBUG) << "rendering took: " << TIMER_MSEC(route_render);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: break into function object with several functions, i.e. simplify
|
|
||||||
// construct routes names
|
|
||||||
void GetRouteNames(std::vector<Segment> &shortest_path_segments,
|
|
||||||
std::vector<Segment> &alternative_path_segments,
|
|
||||||
const DataFacadeT *facade,
|
|
||||||
RouteNames &route_names)
|
|
||||||
{
|
|
||||||
Segment shortest_segment_1, shortest_segment_2;
|
|
||||||
Segment alternative_segment_1, alternative_segment_2;
|
|
||||||
|
|
||||||
auto length_comperator = [](Segment a, Segment b)
|
|
||||||
{ return a.length < b.length; };
|
|
||||||
auto name_id_comperator = [](Segment a, Segment b)
|
|
||||||
{ return a.name_id < b.name_id; };
|
|
||||||
|
|
||||||
if (!shortest_path_segments.empty())
|
|
||||||
{
|
|
||||||
std::sort(
|
|
||||||
shortest_path_segments.begin(), shortest_path_segments.end(), length_comperator);
|
|
||||||
shortest_segment_1 = shortest_path_segments[0];
|
|
||||||
if (!alternative_path_segments.empty())
|
|
||||||
{
|
|
||||||
std::sort(alternative_path_segments.begin(),
|
|
||||||
alternative_path_segments.end(),
|
|
||||||
length_comperator);
|
|
||||||
alternative_segment_1 = alternative_path_segments[0];
|
|
||||||
}
|
|
||||||
std::vector<Segment> shortest_path_set_difference(shortest_path_segments.size());
|
|
||||||
std::vector<Segment> alternative_path_set_difference(alternative_path_segments.size());
|
|
||||||
std::set_difference(shortest_path_segments.begin(),
|
|
||||||
shortest_path_segments.end(),
|
|
||||||
alternative_path_segments.begin(),
|
|
||||||
alternative_path_segments.end(),
|
|
||||||
shortest_path_set_difference.begin(),
|
|
||||||
length_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::set_difference(alternative_path_segments.begin(),
|
|
||||||
alternative_path_segments.end(),
|
|
||||||
shortest_path_segments.begin(),
|
|
||||||
shortest_path_segments.end(),
|
|
||||||
alternative_path_set_difference.begin(),
|
|
||||||
name_id_comperator);
|
|
||||||
size_of_difference = alternative_path_set_difference.size();
|
|
||||||
if (size_of_difference)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
while (i < size_of_difference &&
|
|
||||||
alternative_path_set_difference[i].name_id == alternative_path_segments[0].name_id)
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
if (i < size_of_difference)
|
|
||||||
{
|
|
||||||
alternative_segment_2 = alternative_path_set_difference[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shortest_segment_1.position > shortest_segment_2.position)
|
|
||||||
{
|
|
||||||
std::swap(shortest_segment_1, shortest_segment_2);
|
|
||||||
}
|
|
||||||
if (alternative_segment_1.position > alternative_segment_2.position)
|
|
||||||
{
|
|
||||||
std::swap(alternative_segment_1, alternative_segment_2);
|
|
||||||
}
|
|
||||||
route_names.shortest_path_name_1 =
|
|
||||||
facade->GetEscapedNameForNameID(shortest_segment_1.name_id);
|
|
||||||
route_names.shortest_path_name_2 =
|
|
||||||
facade->GetEscapedNameForNameID(shortest_segment_2.name_id);
|
|
||||||
|
|
||||||
route_names.alternative_path_name_1 =
|
|
||||||
facade->GetEscapedNameForNameID(alternative_segment_1.name_id);
|
|
||||||
route_names.alternative_path_name_2 =
|
|
||||||
facade->GetEscapedNameForNameID(alternative_segment_2.name_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: reorder parameters
|
// TODO: reorder parameters
|
||||||
inline void BuildTextualDescription(DescriptionFactory &description_factory,
|
inline void BuildTextualDescription(DescriptionFactory &description_factory,
|
||||||
JSON::Array & json_instruction_array,
|
JSON::Array & json_instruction_array,
|
||||||
|
Loading…
Reference in New Issue
Block a user