Refactor routing plugins:

- remove superflous members from RawRouteData, partially implements #1238
- DescriptorTable moved to BaseDescriptor.h
- added templated assignment c'tor to DescriptorConfig
- refactored check for valid input coordinates, moved to BasePlugin.h
- replaced shared_ptr's to descriptors in ViaRoutePlugin.h with unique_ptr
- implemented FindIncrementalPhantomNode in facades for a single, i.e. first result
- untangled a few includes
This commit is contained in:
Dennis Luxen 2014-10-22 19:02:19 +02:00
parent 002da1e02d
commit 463511871f
10 changed files with 112 additions and 93 deletions

View File

@ -68,12 +68,10 @@ struct RawRouteData
std::vector<std::vector<PathData>> unpacked_path_segments;
std::vector<PathData> unpacked_alternative;
std::vector<PhantomNodes> segment_end_coordinates;
std::vector<FixedPointCoordinate> raw_via_node_coordinates;
std::vector<bool> source_traversed_in_reverse;
std::vector<bool> target_traversed_in_reverse;
std::vector<bool> alt_source_traversed_in_reverse;
std::vector<bool> alt_target_traversed_in_reverse;
unsigned check_sum;
int shortest_path_length;
int alternative_path_length;
@ -82,8 +80,7 @@ struct RawRouteData
return (leg != unpacked_path_segments.size() - 1);
}
RawRouteData()
: check_sum(SPECIAL_NODEID),
RawRouteData() :
shortest_path_length(INVALID_EDGE_WEIGHT),
alternative_path_length(INVALID_EDGE_WEIGHT)
{

View File

@ -35,13 +35,35 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Reply.h>
#include <string>
#include <unordered_map>
#include <vector>
struct DescriptorTable : public std::unordered_map<std::string, unsigned>
{
unsigned get_id(const std::string &key)
{
auto iter = find(key);
if (iter != end())
{
return iter->second;
}
return 0;
}
};
struct DescriptorConfig
{
DescriptorConfig() : instructions(true), geometry(true), encode_geometry(true), zoom_level(18)
{
}
template<class OtherT>
DescriptorConfig(const OtherT &other) : instructions(other.print_instructions),
geometry(other.geometry),
encode_geometry(other.compression),
zoom_level(other.zoom_level) { }
bool instructions;
bool geometry;
bool encode_geometry;

View File

@ -278,7 +278,7 @@ template <class DataFacadeT> class JSONDescriptor final : public BaseDescriptor<
}
JSON::Object json_hint_object;
json_hint_object.values["checksum"] = raw_route.check_sum;
json_hint_object.values["checksum"] = facade->GetCheckSum();
JSON::Array json_location_hint_array;
std::string hint;
for (const auto i : osrm::irange<std::size_t>(0, raw_route.segment_end_coordinates.size()))

View File

@ -34,6 +34,7 @@ namespace boost { namespace interprocess { class named_mutex; } }
#include <osrm/RouteParameters.h>
#include <osrm/ServerPaths.h>
#include "../DataStructures/QueryEdge.h"
#include "../Plugins/BasePlugin.h"
#include "../Plugins/DistanceTablePlugin.h"
#include "../Plugins/HelloWorldPlugin.h"

View File

@ -28,8 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef BASEPLUGIN_H_
#define BASEPLUGIN_H_
#include "../Util/StringUtil.h"
#include <osrm/Coordinate.h>
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
@ -45,6 +43,20 @@ class BasePlugin
virtual ~BasePlugin() {}
virtual const std::string GetDescriptor() const = 0;
virtual void HandleRequest(const RouteParameters &routeParameters, http::Reply &reply) = 0;
virtual bool check_all_coordinates(const std::vector<FixedPointCoordinate> coordinates) const final
{
if (2 > coordinates.size() ||
std::any_of(std::begin(coordinates),
std::end(coordinates),
[](const FixedPointCoordinate &coordinate)
{
return !coordinate.isValid();
}))
{
return false;
}
return true;
}
};
#endif /* BASEPLUGIN_H_ */

View File

@ -64,37 +64,17 @@ template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (2 > route_parameters.coordinates.size())
if (!check_all_coordinates(route_parameters.coordinates))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
RawRouteData raw_route;
raw_route.check_sum = facade->GetCheckSum();
if (std::any_of(begin(route_parameters.coordinates),
end(route_parameters.coordinates),
[&](FixedPointCoordinate coordinate)
{
return !coordinate.isValid();
}))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
for (const FixedPointCoordinate &coordinate : route_parameters.coordinates)
{
raw_route.raw_via_node_coordinates.emplace_back(std::move(coordinate));
}
const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum);
const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum());
unsigned max_locations =
std::min(100u, static_cast<unsigned>(raw_route.raw_via_node_coordinates.size()));
std::min(100u, static_cast<unsigned>(route_parameters.coordinates.size()));
PhantomNodeArray phantom_node_vector(max_locations);
for (unsigned i = 0; i < max_locations; ++i)
for (const auto i : osrm::irange(1u, max_locations))
{
if (checksum_OK && i < route_parameters.hints.size() &&
!route_parameters.hints[i].empty())
@ -107,7 +87,7 @@ template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
continue;
}
}
facade->IncrementalFindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i],
phantom_node_vector[i],
route_parameters.zoom_level,
1);

View File

@ -31,29 +31,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BasePlugin.h"
#include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../Util/make_unique.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include <cstdlib>
#include <algorithm>
#include <memory>
#include <unordered_map>
#include <string>
#include <vector>
template <class DataFacadeT> class ViaRoutePlugin final : public BasePlugin
{
private:
std::unordered_map<std::string, unsigned> descriptor_table;
DescriptorTable descriptor_table;
std::string descriptor_string;
std::unique_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;
DataFacadeT *facade;
public:
explicit ViaRoutePlugin(DataFacadeT *facade) : descriptor_string("viaroute"), facade(facade)
@ -71,30 +70,17 @@ template <class DataFacadeT> class ViaRoutePlugin final : public BasePlugin
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (2 > route_parameters.coordinates.size() ||
std::any_of(begin(route_parameters.coordinates),
end(route_parameters.coordinates),
[&](FixedPointCoordinate coordinate)
{
return !coordinate.isValid();
}))
if (!check_all_coordinates(route_parameters.coordinates))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
reply.status = http::Reply::ok;
RawRouteData raw_route;
raw_route.check_sum = facade->GetCheckSum();
for (const FixedPointCoordinate &coordinate : route_parameters.coordinates)
{
raw_route.raw_via_node_coordinates.emplace_back(coordinate);
}
std::vector<PhantomNode> phantom_node_vector(route_parameters.coordinates.size());
const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum());
std::vector<PhantomNode> phantom_node_vector(raw_route.raw_via_node_coordinates.size());
const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum);
for (unsigned i = 0; i < raw_route.raw_via_node_coordinates.size(); ++i)
for (const auto i : osrm::irange<std::size_t>(0, route_parameters.coordinates.size()))
{
if (checksum_OK && i < route_parameters.hints.size() &&
!route_parameters.hints[i].empty())
@ -105,25 +91,23 @@ template <class DataFacadeT> class ViaRoutePlugin final : public BasePlugin
continue;
}
}
facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
phantom_node_vector[i],
route_parameters.zoom_level);
facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i],
phantom_node_vector[i],
route_parameters.zoom_level);
}
PhantomNodes current_phantom_node_pair;
for (unsigned i = 0; i < phantom_node_vector.size() - 1; ++i)
RawRouteData raw_route;
auto build_phantom_pairs = [&raw_route] (const PhantomNode &first, const PhantomNode &second)
{
current_phantom_node_pair.source_phantom = phantom_node_vector[i];
current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1];
raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair);
}
raw_route.segment_end_coordinates.emplace_back(PhantomNodes{first, second});
};
osrm::for_each_pair(phantom_node_vector, build_phantom_pairs);
const bool is_alternate_requested = route_parameters.alternate_route;
const bool is_only_one_segment = (1 == raw_route.segment_end_coordinates.size());
if (is_alternate_requested && is_only_one_segment)
if (route_parameters.alternate_route &&
1 == raw_route.segment_end_coordinates.size())
{
search_engine_ptr->alternative_path(raw_route.segment_end_coordinates.front(),
raw_route);
search_engine_ptr->alternative_path(
raw_route.segment_end_coordinates.front(), raw_route);
}
else
{
@ -135,42 +119,24 @@ template <class DataFacadeT> class ViaRoutePlugin final : public BasePlugin
{
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
}
reply.status = http::Reply::ok;
DescriptorConfig descriptor_config;
auto iter = descriptor_table.find(route_parameters.output_format);
unsigned descriptor_type = (iter != descriptor_table.end() ? iter->second : 0);
descriptor_config.zoom_level = route_parameters.zoom_level;
descriptor_config.instructions = route_parameters.print_instructions;
descriptor_config.geometry = route_parameters.geometry;
descriptor_config.encode_geometry = route_parameters.compression;
std::shared_ptr<BaseDescriptor<DataFacadeT>> descriptor;
switch (descriptor_type)
std::unique_ptr<BaseDescriptor<DataFacadeT>> descriptor;
switch (descriptor_table.get_id(route_parameters.output_format))
{
// case 0:
// descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>();
// break;
case 1:
descriptor = std::make_shared<GPXDescriptor<DataFacadeT>>(facade);
descriptor = osrm::make_unique<GPXDescriptor<DataFacadeT>>(facade);
break;
// case 2:
// descriptor = std::make_shared<GEOJSONDescriptor<DataFacadeT>>();
// descriptor = osrm::make_unique<GEOJSONDescriptor<DataFacadeT>>();
// break;
default:
descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>(facade);
descriptor = osrm::make_unique<JSONDescriptor<DataFacadeT>>(facade);
break;
}
descriptor->SetConfig(descriptor_config);
descriptor->SetConfig(route_parameters);
descriptor->Run(raw_route, reply);
}
private:
std::string descriptor_string;
DataFacadeT *facade;
};
#endif // VIA_ROUTE_PLUGIN_H

View File

@ -108,6 +108,11 @@ template <class EdgeDataT> class BaseDataFacade
const unsigned zoom_level,
const unsigned number_of_results) = 0;
virtual bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_leve) = 0;
virtual unsigned GetCheckSum() const = 0;
virtual unsigned GetNameIndexFromEdgeID(const unsigned id) const = 0;

View File

@ -390,6 +390,24 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
input_coordinate, resulting_phantom_node, zoom_level);
}
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) final
{
std::vector<PhantomNode> resulting_phantom_node_vector;
auto result = IncrementalFindPhantomNodeForCoordinate(input_coordinate,
resulting_phantom_node_vector,
zoom_level,
1);
if (result)
{
BOOST_ASSERT(!resulting_phantom_node_vector.empty());
resulting_phantom_node = resulting_phantom_node_vector.front();
}
return result;
}
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,

View File

@ -383,6 +383,24 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
input_coordinate, resulting_phantom_node, zoom_level);
}
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) final
{
std::vector<PhantomNode> resulting_phantom_node_vector;
auto result = IncrementalFindPhantomNodeForCoordinate(input_coordinate,
resulting_phantom_node_vector,
zoom_level,
1);
if (result)
{
BOOST_ASSERT(!resulting_phantom_node_vector.empty());
resulting_phantom_node = resulting_phantom_node_vector.front();
}
return result;
}
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,