Add support for tile plugin

This commit is contained in:
Patrick Niklaus 2016-03-03 01:48:30 +01:00
parent 36f9366f3f
commit 58fb633df3
34 changed files with 457 additions and 243 deletions

View File

@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "osrm/status.hpp" #include "osrm/status.hpp"
#include <memory> #include <memory>
#include <string>
namespace osrm namespace osrm
{ {
@ -42,6 +43,7 @@ using engine::api::TableParameters;
using engine::api::NearestParameters; using engine::api::NearestParameters;
using engine::api::TripParameters; using engine::api::TripParameters;
using engine::api::MatchParameters; using engine::api::MatchParameters;
using engine::api::TileParameters;
class OSRM final class OSRM final
{ {
@ -57,6 +59,7 @@ class OSRM final
Status Nearest(const NearestParameters &parameters, json::Object &result); Status Nearest(const NearestParameters &parameters, json::Object &result);
Status Trip(const TripParameters &parameters, json::Object &result); Status Trip(const TripParameters &parameters, json::Object &result);
Status Match(const MatchParameters &parameters, json::Object &result); Status Match(const MatchParameters &parameters, json::Object &result);
Status Tile(const TileParameters &parameters, std::string &result);
private: private:
std::unique_ptr<engine::Engine> engine_; std::unique_ptr<engine::Engine> engine_;

View File

@ -24,6 +24,7 @@ struct TableParameters;
struct NearestParameters; struct NearestParameters;
struct TripParameters; struct TripParameters;
struct MatchParameters; struct MatchParameters;
struct TileParameters;
} // ns api } // ns api
class Engine; class Engine;

View File

@ -33,9 +33,9 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<std::string::iterator>
using Iterator = std::string::iterator; using Iterator = std::string::iterator;
using RadiusesT = std::vector<boost::optional<double>>; using RadiusesT = std::vector<boost::optional<double>>;
BaseParametersGrammar(qi::rule<Iterator> &child_rule, BaseParametersGrammar(qi::rule<Iterator> &root_rule_,
engine::api::BaseParameters &parameters_) engine::api::BaseParameters &parameters_)
: BaseParametersGrammar::base_type(child_rule), base_parameters(parameters_) : BaseParametersGrammar::base_type(root_rule_), base_parameters(parameters_)
{ {
const auto add_bearing = [this](boost::optional<boost::fusion::vector2<short, short>> bearing_range) { const auto add_bearing = [this](boost::optional<boost::fusion::vector2<short, short>> bearing_range) {
boost::optional<engine::api::BaseParameters::Bearing> bearing; boost::optional<engine::api::BaseParameters::Bearing> bearing;
@ -54,26 +54,45 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<std::string::iterator>
base_parameters.hints.push_back(engine::Hint::FromBase64(hint_string)); base_parameters.hints.push_back(engine::Hint::FromBase64(hint_string));
} }
}; };
const auto add_coordinate = [this](const boost::fusion::vector<double, double> &lonLat)
{
base_parameters.coordinates.emplace_back(
util::Coordinate(util::FixedLongitude(boost::fusion::at_c<0>(lonLat) * COORDINATE_PRECISION),
util::FixedLatitude(boost::fusion::at_c<1>(lonLat) * COORDINATE_PRECISION)));
};
const auto polyline_to_coordinates = [this](const std::string &polyline)
{
base_parameters.coordinates = engine::decodePolyline(polyline);
};
alpha_numeral = +qi::char_("a-zA-Z0-9"); alpha_numeral = +qi::char_("a-zA-Z0-9");
polyline_chars = qi::char_("a-zA-Z0-9_.--[]{}@?|\\%~`^");
base64_char = qi::char_("a-zA-Z0-9--_"); base64_char = qi::char_("a-zA-Z0-9--_");
radiuses_rule = qi::lit("radiuses=") >> -qi::double_ % ";"; radiuses_rule = qi::lit("radiuses=") >> -qi::double_ % ";";
hints_rule = qi::lit("hints=") >> qi::as_string[qi::repeat(engine::ENCODED_HINT_SIZE)[base64_char]][add_hint] % ";"; hints_rule = qi::lit("hints=") >> qi::as_string[qi::repeat(engine::ENCODED_HINT_SIZE)[base64_char]][add_hint] % ";";
bearings_rule = bearings_rule =
qi::lit("bearings=") >> (-(qi::short_ >> ',' >> qi::short_))[add_bearing] % ";"; qi::lit("bearings=") >> (-(qi::short_ >> ',' >> qi::short_))[add_bearing] % ";";
polyline_rule = qi::as_string[qi::lit("polyline(") >> +polyline_chars >>
qi::lit(")")][polyline_to_coordinates];
location_rule = (qi::double_ >> qi::lit(',') >> qi::double_)[add_coordinate];
query_rule = (location_rule % ';') | polyline_rule;
base_rule = bearings_rule | radiuses_rule[set_radiuses] | hints_rule; base_rule = bearings_rule | radiuses_rule[set_radiuses] | hints_rule;
} }
protected:
qi::rule<Iterator> base_rule; qi::rule<Iterator> base_rule;
qi::rule<Iterator> query_rule;
private: private:
engine::api::BaseParameters &base_parameters; engine::api::BaseParameters &base_parameters;
qi::rule<Iterator> bearings_rule; qi::rule<Iterator> bearings_rule;
qi::rule<Iterator> hints_rule; qi::rule<Iterator> hints_rule;
qi::rule<Iterator> polyline_rule, location_rule;
qi::rule<Iterator, RadiusesT()> radiuses_rule; qi::rule<Iterator, RadiusesT()> radiuses_rule;
qi::rule<Iterator, unsigned char()> base64_char; qi::rule<Iterator, unsigned char()> base64_char;
qi::rule<Iterator, std::string()> alpha_numeral; qi::rule<Iterator, std::string()> alpha_numeral, polyline_chars;
}; };
} }
} }

View File

@ -70,7 +70,7 @@ struct MatchParametersGrammar final : public BaseParametersGrammar
timestamps_rule = qi::lit("timestamps=") >> qi::uint_ % ";"; timestamps_rule = qi::lit("timestamps=") >> qi::uint_ % ";";
match_rule = steps_rule[set_steps] | geometries_rule | match_rule = steps_rule[set_steps] | geometries_rule |
overview_rule | timestamps_rule[set_timestamps]; overview_rule | timestamps_rule[set_timestamps];
root_rule = -((base_rule | match_rule) % '&'); root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (match_rule | base_rule) % '&');
} }
engine::api::MatchParameters parameters; engine::api::MatchParameters parameters;

View File

@ -31,13 +31,14 @@ struct NearestParametersGrammar final : public BaseParametersGrammar
parameters.number_of_results = number; parameters.number_of_results = number;
}; };
nearest_rule = (qi::lit("number=") >> qi::uint_)[set_number]; nearest_rule = (qi::lit("number=") >> qi::uint_)[set_number];
root_rule = *(base_rule | nearest_rule); root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (nearest_rule | base_rule) % '&');
} }
engine::api::NearestParameters parameters; engine::api::NearestParameters parameters;
private: private:
qi::rule<Iterator> root_rule, nearest_rule; qi::rule<Iterator> root_rule;
qi::rule<Iterator> nearest_rule;
}; };
} }
} }

View File

@ -1,8 +1,8 @@
#ifndef SERVER_API_ROUTE_PARAMETERS_PARSER_HPP #ifndef SERVER_API_ROUTE_PARAMETERS_PARSER_HPP
#define SERVER_API_ROUTE_PARAMETERS_PARSER_HPP #define SERVER_API_ROUTE_PARAMETERS_PARSER_HPP
#include "engine/api/route_parameters.hpp" #include "engine/api/base_parameters.hpp"
#include "engine/api/table_parameters.hpp" #include "engine/api/tile_parameters.hpp"
#include <boost/optional/optional.hpp> #include <boost/optional/optional.hpp>
@ -20,7 +20,11 @@ namespace api
namespace detail namespace detail
{ {
template <typename T> using is_parameter_t = std::is_base_of<engine::api::BaseParameters, T>; template <typename T>
using is_parameter_t =
std::integral_constant<bool,
std::is_base_of<engine::api::BaseParameters, T>::value ||
std::is_same<engine::api::TileParameters, T>::value>;
} // ns detail } // ns detail
// Starts parsing and iter and modifies it until iter == end or parsing failed // Starts parsing and iter and modifies it until iter == end or parsing failed

View File

@ -18,8 +18,7 @@ struct ParsedURL
std::string service; std::string service;
unsigned version; unsigned version;
std::string profile; std::string profile;
std::vector<util::Coordinate> coordinates; std::string query;
std::string options;
}; };
} }
} }

View File

@ -75,13 +75,15 @@ struct RouteParametersGrammar : public BaseParametersGrammar
uturns_rule = qi::lit("uturns=") >> -qi::bool_ % ";"; uturns_rule = qi::lit("uturns=") >> -qi::bool_ % ";";
route_rule = steps_rule[set_steps] | alternative_rule[set_alternative] | geometries_rule | route_rule = steps_rule[set_steps] | alternative_rule[set_alternative] | geometries_rule |
overview_rule | uturns_rule[set_uturns]; overview_rule | uturns_rule[set_uturns];
root_rule = -((base_rule | route_rule) % '&');
root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (route_rule | base_rule) % '&');
} }
engine::api::RouteParameters parameters; engine::api::RouteParameters parameters;
private: private:
qi::rule<Iterator> root_rule, route_rule, geometries_rule, overview_rule; qi::rule<Iterator> root_rule;
qi::rule<Iterator> route_rule, geometries_rule, overview_rule;
qi::rule<Iterator, UturnsT()> uturns_rule; qi::rule<Iterator, UturnsT()> uturns_rule;
qi::rule<Iterator, StepsT()> steps_rule; qi::rule<Iterator, StepsT()> steps_rule;
qi::rule<Iterator, AlternativeT()> alternative_rule; qi::rule<Iterator, AlternativeT()> alternative_rule;

View File

@ -39,13 +39,15 @@ struct TableParametersGrammar final : public BaseParametersGrammar
destinations_rule = (qi::lit("destinations=") >> (qi::ulong_ % ";")[set_destiantions]) | qi::lit("destinations=all"); destinations_rule = (qi::lit("destinations=") >> (qi::ulong_ % ";")[set_destiantions]) | qi::lit("destinations=all");
sources_rule = (qi::lit("sources=") >> (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all"); sources_rule = (qi::lit("sources=") >> (qi::ulong_ % ";")[set_sources]) | qi::lit("sources=all");
table_rule = destinations_rule | sources_rule; table_rule = destinations_rule | sources_rule;
root_rule = -((base_rule | table_rule) % '&');
root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (table_rule | base_rule) % '&');
} }
engine::api::TableParameters parameters; engine::api::TableParameters parameters;
private: private:
qi::rule<Iterator> root_rule, table_rule; qi::rule<Iterator> root_rule;
qi::rule<Iterator> table_rule;
qi::rule<Iterator> sources_rule; qi::rule<Iterator> sources_rule;
qi::rule<Iterator> destinations_rule; qi::rule<Iterator> destinations_rule;
}; };

View File

@ -0,0 +1,50 @@
#ifndef SERVER_API_TILE_PARAMETERS_GRAMMAR_HPP
#define SERVER_API_TILE_PARAMETERS_GRAMMAR_HPP
#include "engine/api/tile_parameters.hpp"
#include "engine/polyline_compressor.hpp"
#include "engine/hint.hpp"
#include <boost/spirit/include/qi_lit.hpp>
#include <boost/spirit/include/qi_uint.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/qi_operator.hpp>
#include <string>
namespace osrm
{
namespace server
{
namespace api
{
namespace qi = boost::spirit::qi;
struct TileParametersGrammar final : boost::spirit::qi::grammar<std::string::iterator>
{
using Iterator = std::string::iterator;
TileParametersGrammar()
: TileParametersGrammar::base_type(root_rule)
{
const auto set_x = [this](const unsigned x_) { parameters.x = x_; };
const auto set_y = [this](const unsigned y_) { parameters.y = y_; };
const auto set_z = [this](const unsigned z_) { parameters.z = z_; };
query_rule = qi::lit("tile(") >> qi::uint_[set_x] >> qi::lit(",") >> qi::uint_[set_y] >> qi::lit(",") >> qi::uint_[set_z] >> qi::lit(")");
root_rule = query_rule >> qi::lit(".mvt");
}
engine::api::TileParameters parameters;
private:
qi::rule<Iterator> root_rule;
qi::rule<Iterator> query_rule;
};
}
}
}
#endif

View File

@ -63,7 +63,8 @@ struct TripParametersGrammar final : public BaseParametersGrammar
qi::lit("overview=full")[set_full_type] | qi::lit("overview=full")[set_full_type] |
qi::lit("overview=false")[set_false_type]; qi::lit("overview=false")[set_false_type];
trip_rule = steps_rule[set_steps] | geometries_rule | overview_rule; trip_rule = steps_rule[set_steps] | geometries_rule | overview_rule;
root_rule = -((base_rule | trip_rule) % '&');
root_rule = query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (trip_rule | base_rule) % '&');
} }
engine::api::TripParameters parameters; engine::api::TripParameters parameters;

View File

@ -5,6 +5,8 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "osrm/osrm.hpp" #include "osrm/osrm.hpp"
#include <variant/variant.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
@ -18,12 +20,12 @@ namespace service
class BaseService class BaseService
{ {
public: public:
using ResultT = mapbox::util::variant<util::json::Object, std::string>;
BaseService(OSRM &routing_machine) : routing_machine(routing_machine) {} BaseService(OSRM &routing_machine) : routing_machine(routing_machine) {}
virtual ~BaseService() = default; virtual ~BaseService() = default;
virtual engine::Status RunQuery(std::vector<util::Coordinate> coordinates, virtual engine::Status RunQuery(std::string &query, ResultT &result) = 0;
std::string &options,
util::json::Object &json_result) = 0;
virtual unsigned GetVersion() = 0; virtual unsigned GetVersion() = 0;

View File

@ -22,9 +22,7 @@ class MatchService final : public BaseService
public: public:
MatchService(OSRM &routing_machine) : BaseService(routing_machine) {} MatchService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status RunQuery(std::vector<util::Coordinate> coordinates, engine::Status RunQuery(std::string &query, ResultT &result) final override;
std::string &options,
util::json::Object &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -22,9 +22,7 @@ class NearestService final : public BaseService
public: public:
NearestService(OSRM &routing_machine) : BaseService(routing_machine) {} NearestService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status RunQuery(std::vector<util::Coordinate> coordinates, engine::Status RunQuery(std::string &query, ResultT &result) final override;
std::string &options,
util::json::Object &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -22,9 +22,7 @@ class RouteService final : public BaseService
public: public:
RouteService(OSRM &routing_machine) : BaseService(routing_machine) {} RouteService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status RunQuery(std::vector<util::Coordinate> coordinates, engine::Status RunQuery(std::string &query, ResultT &result) final override;
std::string &options,
util::json::Object &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -22,9 +22,7 @@ class TableService final : public BaseService
public: public:
TableService(OSRM &routing_machine) : BaseService(routing_machine) {} TableService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status RunQuery(std::vector<util::Coordinate> coordinates, engine::Status RunQuery(std::string &query, ResultT &result) final override;
std::string &options,
util::json::Object &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -0,0 +1,33 @@
#ifndef SERVER_SERVICE_TILE_SERVICE_HPP
#define SERVER_SERVICE_TILE_SERVICE_HPP
#include "server/service/base_service.hpp"
#include "engine/status.hpp"
#include "util/coordinate.hpp"
#include "osrm/osrm.hpp"
#include <string>
#include <vector>
namespace osrm
{
namespace server
{
namespace service
{
class TileService final : public BaseService
{
public:
TileService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status RunQuery(std::string &query, ResultT &result) final override;
unsigned GetVersion() final override { return 1; }
};
}
}
}
#endif

View File

@ -22,9 +22,7 @@ class TripService final : public BaseService
public: public:
TripService(OSRM &routing_machine) : BaseService(routing_machine) {} TripService(OSRM &routing_machine) : BaseService(routing_machine) {}
engine::Status RunQuery(std::vector<util::Coordinate> coordinates, engine::Status RunQuery(std::string &query, ResultT &result) final override;
std::string &options,
util::json::Object &result) final override;
unsigned GetVersion() final override { return 1; } unsigned GetVersion() final override { return 1; }
}; };

View File

@ -27,10 +27,12 @@ class ServiceHandler
{ {
public: public:
ServiceHandler(osrm::EngineConfig &config); ServiceHandler(osrm::EngineConfig &config);
using ResultT = service::BaseService::ResultT;
engine::Status RunQuery(api::ParsedURL parsed_url, util::json::Object &json_result); engine::Status RunQuery(api::ParsedURL parsed_url, ResultT &result);
private: private:
std::unordered_map<std::string, std::unique_ptr<service::BaseService>> service_map; std::unordered_map<std::string, std::unique_ptr<service::BaseService>> service_map;
OSRM routing_machine; OSRM routing_machine;
}; };

View File

@ -50,15 +50,6 @@ namespace json
struct Object; struct Object;
struct Array; struct Array;
// For encoding raw binary data in a JSON response
struct Buffer
{
Buffer() = default;
Buffer(const char *value) : value(value) {}
Buffer(std::string value) : value(std::move(value)) {}
std::string value;
};
struct String struct String
{ {
String() = default; String() = default;
@ -87,7 +78,6 @@ struct Null
}; };
using Value = mapbox::util::variant<String, using Value = mapbox::util::variant<String,
Buffer,
Number, Number,
mapbox::util::recursive_wrapper<Object>, mapbox::util::recursive_wrapper<Object>,
mapbox::util::recursive_wrapper<Array>, mapbox::util::recursive_wrapper<Array>,

View File

@ -25,13 +25,6 @@ struct Renderer
{ {
explicit Renderer(std::ostream &_out) : out(_out) {} explicit Renderer(std::ostream &_out) : out(_out) {}
void operator()(const Buffer &buffer) const
{
out << "\"";
out << escape_JSON(buffer.value);
out << "\"";
}
void operator()(const String &string) const void operator()(const String &string) const
{ {
out << "\""; out << "\"";
@ -88,14 +81,6 @@ struct ArrayRenderer
{ {
explicit ArrayRenderer(std::vector<char> &_out) : out(_out) {} explicit ArrayRenderer(std::vector<char> &_out) : out(_out) {}
void operator()(const Buffer &buffer) const
{
out.push_back('\"');
const auto string_to_insert = escape_JSON(buffer.value);
out.insert(std::end(out), std::begin(string_to_insert), std::end(string_to_insert));
out.push_back('\"');
}
void operator()(const String &string) const void operator()(const String &string) const
{ {
out.push_back('\"'); out.push_back('\"');

View File

@ -46,4 +46,9 @@ engine::Status OSRM::Match(const engine::api::MatchParameters &params, json::Obj
return engine_->Match(params, result); return engine_->Match(params, result);
} }
engine::Status OSRM::Tile(const engine::api::TileParameters &params, std::string &result)
{
return engine_->Tile(params, result);
}
} // ns osrm } // ns osrm

View File

@ -5,6 +5,7 @@
#include "server/api/nearest_parameter_grammar.hpp" #include "server/api/nearest_parameter_grammar.hpp"
#include "server/api/trip_parameter_grammar.hpp" #include "server/api/trip_parameter_grammar.hpp"
#include "server/api/match_parameter_grammar.hpp" #include "server/api/match_parameter_grammar.hpp"
#include "server/api/tile_parameter_grammar.hpp"
namespace osrm namespace osrm
{ {
@ -15,7 +16,10 @@ namespace api
namespace detail namespace detail
{ {
template <typename T> using is_grammar_t = std::is_base_of<BaseParametersGrammar, T>; template <typename T>
using is_grammar_t = std::integral_constant<bool,
std::is_base_of<BaseParametersGrammar, T>::value ||
std::is_same<TileParametersGrammar, T>::value>;
template <typename ParameterT, template <typename ParameterT,
typename GrammarT, typename GrammarT,
@ -70,6 +74,13 @@ boost::optional<engine::api::MatchParameters> parseParameters(std::string::itera
return detail::parseParameters<engine::api::MatchParameters, MatchParametersGrammar>(iter, end); return detail::parseParameters<engine::api::MatchParameters, MatchParametersGrammar>(iter, end);
} }
template <>
boost::optional<engine::api::TileParameters> parseParameters(std::string::iterator &iter,
std::string::iterator end)
{
return detail::parseParameters<engine::api::TileParameters, TileParametersGrammar>(iter, end);
}
} // ns api } // ns api
} // ns server } // ns server
} // ns osrm } // ns osrm

View File

@ -41,45 +41,29 @@ struct URLGrammar : boost::spirit::qi::grammar<Iterator>
{ {
parsed_url.profile = std::move(profile); parsed_url.profile = std::move(profile);
}; };
const auto set_options = [this](std::string &options) const auto set_query = [this](std::string &query)
{ {
parsed_url.options = std::move(options); parsed_url.query = std::move(query);
};
const auto add_coordinate = [this](const boost::fusion::vector<double, double> &lonLat)
{
parsed_url.coordinates.emplace_back(util::Coordinate(
util::FixedLongitude(boost::fusion::at_c<0>(lonLat) * COORDINATE_PRECISION),
util::FixedLatitude(boost::fusion::at_c<1>(lonLat) * COORDINATE_PRECISION)));
};
const auto polyline_to_coordinates = [this](const std::string &polyline)
{
parsed_url.coordinates = engine::decodePolyline(polyline);
}; };
alpha_numeral = qi::char_("a-zA-Z0-9"); alpha_numeral = qi::char_("a-zA-Z0-9");
polyline_chars = qi::char_("a-zA-Z0-9_.--[]{}@?|\\%~`^"); polyline_chars = qi::char_("a-zA-Z0-9_.--[]{}@?|\\%~`^");
all_chars = polyline_chars | qi::char_("=,;:&"); all_chars = polyline_chars | qi::char_("=,;:&().");
polyline_rule = qi::as_string[qi::lit("polyline(") >> +polyline_chars >>
qi::lit(")")][polyline_to_coordinates];
location_rule = (qi::double_ >> qi::lit(',') >> qi::double_)[add_coordinate];
query_rule = (location_rule % ';') | polyline_rule;
service_rule = +alpha_numeral; service_rule = +alpha_numeral;
version_rule = qi::uint_; version_rule = qi::uint_;
profile_rule = +alpha_numeral; profile_rule = +alpha_numeral;
options_rule = *all_chars; query_rule = +all_chars;
url_rule = qi::lit('/') >> service_rule[set_service] >> qi::lit('/') >> qi::lit('v') >> url_rule = qi::lit('/') >> service_rule[set_service] >> qi::lit('/') >> qi::lit('v') >>
version_rule[set_version] >> qi::lit('/') >> profile_rule[set_profile] >> version_rule[set_version] >> qi::lit('/') >> profile_rule[set_profile] >>
qi::lit('/') >> query_rule >> -(qi::lit('?') >> options_rule[set_options]); qi::lit('/') >> query_rule[set_query];
} }
ParsedURL parsed_url; ParsedURL parsed_url;
qi::rule<Iterator> url_rule; qi::rule<Iterator> url_rule;
qi::rule<Iterator, std::string()> options_rule, service_rule, profile_rule; qi::rule<Iterator, std::string()> service_rule, profile_rule, query_rule;
qi::rule<Iterator> query_rule, polyline_rule, location_rule;
qi::rule<Iterator, unsigned()> version_rule; qi::rule<Iterator, unsigned()> version_rule;
qi::rule<Iterator, char()> alpha_numeral, all_chars, polyline_chars; qi::rule<Iterator, char()> alpha_numeral, all_chars, polyline_chars;
}; };

View File

@ -45,8 +45,6 @@ void RequestHandler::HandleRequest(const http::request &current_request,
return; return;
} }
util::json::Object json_result;
// parse command // parse command
try try
{ {
@ -81,11 +79,14 @@ void RequestHandler::HandleRequest(const http::request &current_request,
auto api_iterator = request_string.begin(); auto api_iterator = request_string.begin();
auto maybe_parsed_url = api::parseURL(api_iterator, request_string.end());; auto maybe_parsed_url = api::parseURL(api_iterator, request_string.end());;
ServiceHandler::ResultT result;
// check if the was an error with the request // check if the was an error with the request
if (maybe_parsed_url && api_iterator == request_string.end()) if (maybe_parsed_url && api_iterator == request_string.end())
{ {
const engine::Status status = service_handler->RunQuery(std::move(*maybe_parsed_url), json_result);
const engine::Status status = service_handler->RunQuery(std::move(*maybe_parsed_url), result);
if (status != engine::Status::Ok) if (status != engine::Status::Ok)
{ {
// 4xx bad request return code // 4xx bad request return code
@ -104,20 +105,33 @@ void RequestHandler::HandleRequest(const http::request &current_request,
std::string context(context_begin, context_end); std::string context(context_begin, context_end);
current_reply.status = http::reply::bad_request; current_reply.status = http::reply::bad_request;
result = util::json::Object();
auto& json_result = result.get<util::json::Object>();
json_result.values["code"] = "invalid-url"; json_result.values["code"] = "invalid-url";
json_result.values["message"] = json_result.values["message"] =
"URL string malformed close to position " + std::to_string(position) + ": \"" + context + "\""; "URL string malformed close to position " + std::to_string(position) + ": \"" + context + "\"";
} }
current_reply.headers.emplace_back("Access-Control-Allow-Origin", "*"); current_reply.headers.emplace_back("Access-Control-Allow-Origin", "*");
current_reply.headers.emplace_back("Access-Control-Allow-Methods", "GET"); current_reply.headers.emplace_back("Access-Control-Allow-Methods", "GET");
current_reply.headers.emplace_back("Access-Control-Allow-Headers", current_reply.headers.emplace_back("Access-Control-Allow-Headers",
"X-Requested-With, Content-Type"); "X-Requested-With, Content-Type");
current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8"); if (result.is<util::json::Object>())
current_reply.headers.emplace_back("Content-Disposition", {
"inline; filename=\"response.json\""); current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
current_reply.headers.emplace_back("Content-Disposition",
"inline; filename=\"response.json\"");
util::json::render(current_reply.content, json_result); util::json::render(current_reply.content, result.get<util::json::Object>());
}
else
{
BOOST_ASSERT(result.is<std::string>());
std::copy(result.get<std::string>().cbegin(), result.get<std::string>().cend(), std::back_inserter(current_reply.content));
current_reply.headers.emplace_back("Content-Type", "application/x-protobuf");
}
// set headers // set headers
current_reply.headers.emplace_back("Content-Length", current_reply.headers.emplace_back("Content-Length",

View File

@ -40,34 +40,33 @@ std::string getWrongOptionHelp(const engine::api::MatchParameters &parameters)
} }
} // anon. ns } // anon. ns
engine::Status MatchService::RunQuery(std::vector<util::Coordinate> coordinates, engine::Status MatchService::RunQuery(std::string &query, ResultT &result)
std::string &options,
util::json::Object &result)
{ {
auto options_iterator = options.begin(); result = util::json::Object();
auto& json_result = result.get<util::json::Object>();
auto query_iterator = query.begin();
auto parameters = auto parameters =
api::parseParameters<engine::api::MatchParameters>(options_iterator, options.end()); api::parseParameters<engine::api::MatchParameters>(query_iterator, query.end());
if (!parameters || options_iterator != options.end()) if (!parameters || query_iterator != query.end())
{ {
const auto position = std::distance(options.begin(), options_iterator); const auto position = std::distance(query.begin(), query_iterator);
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-query";
result.values["message"] = json_result.values["message"] =
"Options string malformed close to position " + std::to_string(position); "Query string malformed close to position " + std::to_string(position);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters); BOOST_ASSERT(parameters);
parameters->coordinates = std::move(coordinates);
if (!parameters->IsValid()) if (!parameters->IsValid())
{ {
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-options";
result.values["message"] = getWrongOptionHelp(*parameters); json_result.values["message"] = getWrongOptionHelp(*parameters);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters->IsValid()); BOOST_ASSERT(parameters->IsValid());
return BaseService::routing_machine.Match(*parameters, result); return BaseService::routing_machine.Match(*parameters, json_result);
} }
} }
} }

View File

@ -39,35 +39,33 @@ std::string getWrongOptionHelp(const engine::api::NearestParameters &parameters)
} }
} // anon. ns } // anon. ns
engine::Status NearestService::RunQuery(std::vector<util::Coordinate> coordinates, engine::Status NearestService::RunQuery(std::string &query, ResultT &result)
std::string &options,
util::json::Object &result)
{ {
auto options_iterator = options.begin(); result = util::json::Object();
auto& json_result = result.get<util::json::Object>();
auto query_iterator = query.begin();
auto parameters = auto parameters =
api::parseParameters<engine::api::NearestParameters>(options_iterator, options.end()); api::parseParameters<engine::api::NearestParameters>(query_iterator, query.end());
if (!parameters || options_iterator != options.end()) if (!parameters || query_iterator != query.end())
{ {
const auto position = std::distance(options.begin(), options_iterator); const auto position = std::distance(query.begin(), query_iterator);
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-query";
result.values["message"] = json_result.values["message"] =
"Options string malformed close to position " + std::to_string(position); "Query string malformed close to position " + std::to_string(position);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters); BOOST_ASSERT(parameters);
parameters->coordinates = std::move(coordinates);
if (!parameters->IsValid()) if (!parameters->IsValid())
{ {
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-options";
result.values["message"] = getWrongOptionHelp(*parameters); json_result.values["message"] = getWrongOptionHelp(*parameters);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters->IsValid()); BOOST_ASSERT(parameters->IsValid());
return BaseService::routing_machine.Nearest(*parameters, result); return BaseService::routing_machine.Nearest(*parameters, json_result);
return Status::Error;
} }
} }
} }

View File

@ -38,34 +38,33 @@ std::string getWrongOptionHelp(const engine::api::RouteParameters &parameters)
} }
} // anon. ns } // anon. ns
engine::Status RouteService::RunQuery(std::vector<util::Coordinate> coordinates, engine::Status RouteService::RunQuery(std::string &query, ResultT &result)
std::string &options,
util::json::Object &result)
{ {
auto options_iterator = options.begin(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto query_iterator = query.begin();
auto parameters = auto parameters =
api::parseParameters<engine::api::RouteParameters>(options_iterator, options.end()); api::parseParameters<engine::api::RouteParameters>(query_iterator, query.end());
if (!parameters || options_iterator != options.end()) if (!parameters || query_iterator != query.end())
{ {
const auto position = std::distance(options.begin(), options_iterator); const auto position = std::distance(query.begin(), query_iterator);
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-query";
result.values["message"] = json_result.values["message"] =
"Options string malformed close to position " + std::to_string(position); "Query string malformed close to position " + std::to_string(position);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters); BOOST_ASSERT(parameters);
parameters->coordinates = std::move(coordinates);
if (!parameters->IsValid()) if (!parameters->IsValid())
{ {
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-options";
result.values["message"] = getWrongOptionHelp(*parameters); json_result.values["message"] = getWrongOptionHelp(*parameters);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters->IsValid()); BOOST_ASSERT(parameters->IsValid());
return BaseService::routing_machine.Route(*parameters, result); return BaseService::routing_machine.Route(*parameters, json_result);
} }
} }
} }

View File

@ -1,6 +1,6 @@
#include "server/service/table_service.hpp" #include "server/service/table_service.hpp"
#include "engine/api/route_parameters.hpp" #include "engine/api/table_parameters.hpp"
#include "server/api/parameters_parser.hpp" #include "server/api/parameters_parser.hpp"
#include "util/json_container.hpp" #include "util/json_container.hpp"
@ -57,35 +57,33 @@ std::string getWrongOptionHelp(const engine::api::TableParameters &parameters)
} }
} // anon. ns } // anon. ns
engine::Status TableService::RunQuery(std::vector<util::Coordinate> coordinates, engine::Status TableService::RunQuery(std::string &query, ResultT &result)
std::string &options,
util::json::Object &result)
{ {
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto options_iterator = options.begin(); auto query_iterator = query.begin();
auto parameters = auto parameters =
api::parseParameters<engine::api::TableParameters>(options_iterator, options.end()); api::parseParameters<engine::api::TableParameters>(query_iterator, query.end());
if (!parameters || options_iterator != options.end()) if (!parameters || query_iterator != query.end())
{ {
const auto position = std::distance(options.begin(), options_iterator); const auto position = std::distance(query.begin(), query_iterator);
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-query";
result.values["message"] = json_result.values["message"] =
"Options string malformed close to position " + std::to_string(position); "Query string malformed close to position " + std::to_string(position);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters); BOOST_ASSERT(parameters);
parameters->coordinates = std::move(coordinates);
if (!parameters->IsValid()) if (!parameters->IsValid())
{ {
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-options";
result.values["message"] = getWrongOptionHelp(*parameters); json_result.values["message"] = getWrongOptionHelp(*parameters);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters->IsValid()); BOOST_ASSERT(parameters->IsValid());
return BaseService::routing_machine.Table(*parameters, result); return BaseService::routing_machine.Table(*parameters, json_result);
} }
} }
} }

View File

@ -0,0 +1,51 @@
#include "server/service/tile_service.hpp"
#include "server/service/utils.hpp"
#include "engine/api/tile_parameters.hpp"
#include "server/api/parameters_parser.hpp"
#include "util/json_container.hpp"
#include <boost/format.hpp>
namespace osrm
{
namespace server
{
namespace service
{
engine::Status TileService::RunQuery(std::string &query, ResultT &result)
{
auto query_iterator = query.begin();
auto parameters =
api::parseParameters<engine::api::TileParameters>(query_iterator, query.end());
if (!parameters || query_iterator != query.end())
{
const auto position = std::distance(query.begin(), query_iterator);
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
json_result.values["code"] = "invalid-query";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(position);
return engine::Status::Error;
}
BOOST_ASSERT(parameters);
if (!parameters->IsValid())
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
json_result.values["code"] = "invalid-options";
json_result.values["message"] = "Invalid coodinates. Only zoomlevel 12+ is supported";
return engine::Status::Error;
}
BOOST_ASSERT(parameters->IsValid());
result = std::string();
auto &string_result = result.get<std::string>();
return BaseService::routing_machine.Tile(*parameters, string_result);
}
}
}
}

View File

@ -38,34 +38,35 @@ std::string getWrongOptionHelp(const engine::api::TripParameters &parameters)
} }
} // anon. ns } // anon. ns
engine::Status TripService::RunQuery(std::vector<util::Coordinate> coordinates, engine::Status TripService::RunQuery(std::string &query, ResultT &result)
std::string &options,
util::json::Object &result)
{ {
auto options_iterator = options.begin(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto query_iterator = query.begin();
auto parameters = auto parameters =
api::parseParameters<engine::api::TripParameters>(options_iterator, options.end()); api::parseParameters<engine::api::TripParameters>(query_iterator, query.end());
if (!parameters || options_iterator != options.end()) if (!parameters || query_iterator != query.end())
{ {
const auto position = std::distance(options.begin(), options_iterator); const auto position = std::distance(query.begin(), query_iterator);
result.values["code"] = "invalid-options"; result = util::json::Object();
result.values["message"] = auto &json_result = result.get<util::json::Object>();
"Options string malformed close to position " + std::to_string(position); json_result.values["code"] = "invalid-query";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(position);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters); BOOST_ASSERT(parameters);
parameters->coordinates = std::move(coordinates);
if (!parameters->IsValid()) if (!parameters->IsValid())
{ {
result.values["code"] = "invalid-options"; json_result.values["code"] = "invalid-options";
result.values["message"] = getWrongOptionHelp(*parameters); json_result.values["message"] = getWrongOptionHelp(*parameters);
return engine::Status::Error; return engine::Status::Error;
} }
BOOST_ASSERT(parameters->IsValid()); BOOST_ASSERT(parameters->IsValid());
return BaseService::routing_machine.Trip(*parameters, result); return BaseService::routing_machine.Trip(*parameters, json_result);
} }
} }
} }

View File

@ -5,6 +5,7 @@
#include "server/service/nearest_service.hpp" #include "server/service/nearest_service.hpp"
#include "server/service/trip_service.hpp" #include "server/service/trip_service.hpp"
#include "server/service/match_service.hpp" #include "server/service/match_service.hpp"
#include "server/service/tile_service.hpp"
#include "server/api/parsed_url.hpp" #include "server/api/parsed_url.hpp"
#include "util/json_util.hpp" #include "util/json_util.hpp"
@ -21,27 +22,32 @@ ServiceHandler::ServiceHandler(osrm::EngineConfig &config) : routing_machine(con
service_map["nearest"] = util::make_unique<service::NearestService>(routing_machine); service_map["nearest"] = util::make_unique<service::NearestService>(routing_machine);
service_map["trip"] = util::make_unique<service::TripService>(routing_machine); service_map["trip"] = util::make_unique<service::TripService>(routing_machine);
service_map["match"] = util::make_unique<service::MatchService>(routing_machine); service_map["match"] = util::make_unique<service::MatchService>(routing_machine);
service_map["tile"] = util::make_unique<service::TileService>(routing_machine);
} }
engine::Status ServiceHandler::RunQuery(api::ParsedURL parsed_url, util::json::Object &result) engine::Status ServiceHandler::RunQuery(api::ParsedURL parsed_url, service::BaseService::ResultT &result)
{ {
const auto &service_iter = service_map.find(parsed_url.service); const auto &service_iter = service_map.find(parsed_url.service);
if (service_iter == service_map.end()) if (service_iter == service_map.end())
{ {
result.values["code"] = "invalid-service"; result = util::json::Object();
result.values["message"] = "Service " + parsed_url.service + " not found!"; auto &json_result = result.get<util::json::Object>();
json_result.values["code"] = "invalid-service";
json_result.values["message"] = "Service " + parsed_url.service + " not found!";
return engine::Status::Error; return engine::Status::Error;
} }
auto &service = service_iter->second; auto &service = service_iter->second;
if (service->GetVersion() != parsed_url.version) if (service->GetVersion() != parsed_url.version)
{ {
result.values["code"] = "invalid-version"; result = util::json::Object();
result.values["message"] = "Service " + parsed_url.service + " not found!"; auto &json_result = result.get<util::json::Object>();
json_result.values["code"] = "invalid-version";
json_result.values["message"] = "Service " + parsed_url.service + " not found!";
return engine::Status::Error; return engine::Status::Error;
} }
return service->RunQuery(std::move(parsed_url.coordinates), parsed_url.options, result); return service->RunQuery(parsed_url.query, result);
} }
} }
} }

View File

@ -3,6 +3,9 @@
#include "engine/api/base_parameters.hpp" #include "engine/api/base_parameters.hpp"
#include "engine/api/route_parameters.hpp" #include "engine/api/route_parameters.hpp"
#include "engine/api/table_parameters.hpp" #include "engine/api/table_parameters.hpp"
#include "engine/api/match_parameters.hpp"
#include "engine/api/trip_parameters.hpp"
#include "engine/api/nearest_parameters.hpp"
#include <fstream> #include <fstream>
@ -77,37 +80,32 @@ template <typename ParameterT> std::size_t testInvalidOptions(std::string option
BOOST_AUTO_TEST_CASE(invalid_route_urls) BOOST_AUTO_TEST_CASE(invalid_route_urls)
{ {
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("overview=false&bla=foo"), BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&bla=foo"), 22UL);
14UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&bearings=foo"), 32UL);
BOOST_CHECK_EQUAL( BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&uturns=foo"), 30UL);
testInvalidOptions<engine::api::RouteParameters>("overview=false&bearings=foo"), 24UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&radiuses=foo"), 32UL);
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("overview=false&uturns=foo"), BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&hints=foo"), 22UL);
22UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&geometries=foo"), 22UL);
BOOST_CHECK_EQUAL( BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&overview=foo"), 22L);
testInvalidOptions<engine::api::RouteParameters>("overview=false&radiuses=foo"), 24UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("1,2;3,4?overview=false&alternative=foo"), 22UL);
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::RouteParameters>("overview=false&hints=foo"),
14UL);
BOOST_CHECK_EQUAL(
testInvalidOptions<engine::api::RouteParameters>("overview=false&geometries=foo"), 14UL);
BOOST_CHECK_EQUAL(
testInvalidOptions<engine::api::RouteParameters>("overview=false&overview=foo"), 14UL);
BOOST_CHECK_EQUAL(
testInvalidOptions<engine::api::RouteParameters>("overview=false&alternative=foo"), 14UL);
} }
BOOST_AUTO_TEST_CASE(invalid_table_urls) BOOST_AUTO_TEST_CASE(invalid_table_urls)
{ {
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("sources=1&bla=foo"), 9UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?sources=1&bla=foo"), 17UL);
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("destinations=1&bla=foo"), 14UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?destinations=1&bla=foo"), 22UL);
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("sources=1&destinations=1&bla=foo"), 24UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?sources=1&destinations=1&bla=foo"), 32UL);
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("sources=foo"), 8UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?sources=foo"), 7UL);
BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("destinations=foo"), 13UL); BOOST_CHECK_EQUAL(testInvalidOptions<engine::api::TableParameters>("1,2;3,4?destinations=foo"), 7UL);
} }
BOOST_AUTO_TEST_CASE(valid_route_urls) BOOST_AUTO_TEST_CASE(valid_route_urls)
{ {
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)}, {util::FloatLongitude(3), util::FloatLatitude(4)}};
engine::api::RouteParameters reference_1{}; engine::api::RouteParameters reference_1{};
auto result_1 = api::parseParameters<engine::api::RouteParameters>(""); reference_1.coordinates = coords_1;
auto result_1 = api::parseParameters<engine::api::RouteParameters>("1,2;3,4");
BOOST_CHECK(result_1); BOOST_CHECK(result_1);
BOOST_CHECK_EQUAL(reference_1.steps, result_1->steps); BOOST_CHECK_EQUAL(reference_1.steps, result_1->steps);
BOOST_CHECK_EQUAL(reference_1.alternative, result_1->alternative); BOOST_CHECK_EQUAL(reference_1.alternative, result_1->alternative);
@ -119,8 +117,9 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates); CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
engine::api::RouteParameters reference_2{}; engine::api::RouteParameters reference_2{};
reference_2.coordinates = coords_1;
auto result_2 = api::parseParameters<engine::api::RouteParameters>( auto result_2 = api::parseParameters<engine::api::RouteParameters>(
"steps=true&alternative=true&geometries=polyline&overview=simplified"); "1,2;3,4?steps=true&alternative=true&geometries=polyline&overview=simplified");
BOOST_CHECK(result_2); BOOST_CHECK(result_2);
BOOST_CHECK_EQUAL(reference_2.steps, result_2->steps); BOOST_CHECK_EQUAL(reference_2.steps, result_2->steps);
BOOST_CHECK_EQUAL(reference_2.alternative, result_2->alternative); BOOST_CHECK_EQUAL(reference_2.alternative, result_2->alternative);
@ -135,8 +134,9 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
engine::api::RouteParameters reference_3{ engine::api::RouteParameters reference_3{
false, false, engine::api::RouteParameters::GeometriesType::GeoJSON, false, false, engine::api::RouteParameters::GeometriesType::GeoJSON,
engine::api::RouteParameters::OverviewType::False, uturns_3}; engine::api::RouteParameters::OverviewType::False, uturns_3};
reference_3.coordinates = coords_1;
auto result_3 = api::parseParameters<engine::api::RouteParameters>( auto result_3 = api::parseParameters<engine::api::RouteParameters>(
"steps=false&alternative=false&geometries=geojson&overview=false&uturns=true;false;"); "1,2;3,4?steps=false&alternative=false&geometries=geojson&overview=false&uturns=true;false;");
BOOST_CHECK(result_3); BOOST_CHECK(result_3);
BOOST_CHECK_EQUAL(reference_3.steps, result_3->steps); BOOST_CHECK_EQUAL(reference_3.steps, result_3->steps);
BOOST_CHECK_EQUAL(reference_3.alternative, result_3->alternative); BOOST_CHECK_EQUAL(reference_3.alternative, result_3->alternative);
@ -160,12 +160,12 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
engine::api::RouteParameters::GeometriesType::Polyline, engine::api::RouteParameters::GeometriesType::Polyline,
engine::api::RouteParameters::OverviewType::Simplified, engine::api::RouteParameters::OverviewType::Simplified,
std::vector<boost::optional<bool>>{}, std::vector<boost::optional<bool>>{},
std::vector<util::Coordinate>{}, coords_1,
hints_4, hints_4,
std::vector<boost::optional<double>>{}, std::vector<boost::optional<double>>{},
std::vector<boost::optional<engine::api::BaseParameters::Bearing>>{}}; std::vector<boost::optional<engine::api::BaseParameters::Bearing>>{}};
auto result_4 = api::parseParameters<engine::api::RouteParameters>( auto result_4 = api::parseParameters<engine::api::RouteParameters>(
"steps=false&hints=rVghAzxMzABMAwAA5h4CAKMIAAAQAAAAGAAAAAYAAAAAAAAAch8BAJ4AAACpWCED_" "1,2;3,4?steps=false&hints=rVghAzxMzABMAwAA5h4CAKMIAAAQAAAAGAAAAAYAAAAAAAAAch8BAJ4AAACpWCED_"
"0vMAAEAAQGLSzmR;_4ghA4JuzAD_" "0vMAAEAAQGLSzmR;_4ghA4JuzAD_"
"IAAAo28BAOYAAAAzAAAAAgAAAEwAAAAAAAAAdIwAAJ4AAAAXiSEDfm7MAAEAAQGLSzmR;03AhA0vnzAA_SAAA_____" "IAAAo28BAOYAAAAzAAAAAgAAAEwAAAAAAAAAdIwAAJ4AAAAXiSEDfm7MAAEAAQGLSzmR;03AhA0vnzAA_SAAA_____"
"3wEAAAYAAAAQAAAAB4AAABAAAAAoUYBAJ4AAADlcCEDSefMAAMAAQGLSzmR"); "3wEAAAYAAAAQAAAAB4AAABAAAAAoUYBAJ4AAADlcCEDSefMAAMAAQGLSzmR");
@ -190,12 +190,12 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
engine::api::RouteParameters::GeometriesType::Polyline, engine::api::RouteParameters::GeometriesType::Polyline,
engine::api::RouteParameters::OverviewType::Simplified, engine::api::RouteParameters::OverviewType::Simplified,
std::vector<boost::optional<bool>>{}, std::vector<boost::optional<bool>>{},
std::vector<util::Coordinate>{}, coords_1,
std::vector<boost::optional<engine::Hint>> {}, std::vector<boost::optional<engine::Hint>> {},
std::vector<boost::optional<double>>{}, std::vector<boost::optional<double>>{},
bearings_4}; bearings_4};
auto result_5 = api::parseParameters<engine::api::RouteParameters>( auto result_5 = api::parseParameters<engine::api::RouteParameters>(
"steps=false&bearings=;200,10;100,5"); "1,2;3,4?steps=false&bearings=;200,10;100,5");
BOOST_CHECK(result_5); BOOST_CHECK(result_5);
BOOST_CHECK_EQUAL(reference_5.steps, result_5->steps); BOOST_CHECK_EQUAL(reference_5.steps, result_5->steps);
BOOST_CHECK_EQUAL(reference_5.alternative, result_5->alternative); BOOST_CHECK_EQUAL(reference_5.alternative, result_5->alternative);
@ -205,12 +205,31 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
CHECK_EQUAL_RANGE(reference_5.bearings, result_5->bearings); CHECK_EQUAL_RANGE(reference_5.bearings, result_5->bearings);
CHECK_EQUAL_RANGE(reference_5.radiuses, result_5->radiuses); CHECK_EQUAL_RANGE(reference_5.radiuses, result_5->radiuses);
CHECK_EQUAL_RANGE(reference_5.coordinates, result_5->coordinates); CHECK_EQUAL_RANGE(reference_5.coordinates, result_5->coordinates);
std::vector<util::Coordinate> coords_2 = {{util::FloatLongitude(0), util::FloatLatitude(1)}, {util::FloatLongitude(2), util::FloatLatitude(3)},
{util::FloatLongitude(4), util::FloatLatitude(5)}};
engine::api::RouteParameters reference_6{};
reference_6.coordinates = coords_2;
auto result_6 = api::parseParameters<engine::api::RouteParameters>("polyline(_ibE?_seK_seK_seK_seK)");
BOOST_CHECK(result_6);
BOOST_CHECK_EQUAL(reference_6.steps, result_6->steps);
BOOST_CHECK_EQUAL(reference_6.alternative, result_6->alternative);
BOOST_CHECK_EQUAL(reference_6.geometries, result_6->geometries);
BOOST_CHECK_EQUAL(reference_6.overview, result_6->overview);
CHECK_EQUAL_RANGE(reference_6.uturns, result_6->uturns);
CHECK_EQUAL_RANGE(reference_6.bearings, result_6->bearings);
CHECK_EQUAL_RANGE(reference_6.radiuses, result_6->radiuses);
CHECK_EQUAL_RANGE(reference_6.coordinates, result_6->coordinates);
} }
BOOST_AUTO_TEST_CASE(valid_table_urls) BOOST_AUTO_TEST_CASE(valid_table_urls)
{ {
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)}, {util::FloatLongitude(3), util::FloatLatitude(4)}};
engine::api::TableParameters reference_1{}; engine::api::TableParameters reference_1{};
auto result_1 = api::parseParameters<engine::api::TableParameters>(""); reference_1.coordinates = coords_1;
auto result_1 = api::parseParameters<engine::api::TableParameters>("1,2;3,4");
BOOST_CHECK(result_1); BOOST_CHECK(result_1);
CHECK_EQUAL_RANGE(reference_1.sources, result_1->sources); CHECK_EQUAL_RANGE(reference_1.sources, result_1->sources);
CHECK_EQUAL_RANGE(reference_1.destinations, result_1->destinations); CHECK_EQUAL_RANGE(reference_1.destinations, result_1->destinations);
@ -221,7 +240,8 @@ BOOST_AUTO_TEST_CASE(valid_table_urls)
std::vector<std::size_t> sources_2 = {1, 2, 3}; std::vector<std::size_t> sources_2 = {1, 2, 3};
std::vector<std::size_t> destinations_2 = {4, 5}; std::vector<std::size_t> destinations_2 = {4, 5};
engine::api::TableParameters reference_2{sources_2, destinations_2}; engine::api::TableParameters reference_2{sources_2, destinations_2};
auto result_2 = api::parseParameters<engine::api::TableParameters>("sources=1;2;3&destinations=4;5"); reference_2.coordinates = coords_1;
auto result_2 = api::parseParameters<engine::api::TableParameters>("1,2;3,4?sources=1;2;3&destinations=4;5");
BOOST_CHECK(result_2); BOOST_CHECK(result_2);
CHECK_EQUAL_RANGE(reference_2.sources, result_2->sources); CHECK_EQUAL_RANGE(reference_2.sources, result_2->sources);
CHECK_EQUAL_RANGE(reference_2.destinations, result_2->destinations); CHECK_EQUAL_RANGE(reference_2.destinations, result_2->destinations);
@ -230,4 +250,55 @@ BOOST_AUTO_TEST_CASE(valid_table_urls)
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates); CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
} }
BOOST_AUTO_TEST_CASE(valid_match_urls)
{
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)}, {util::FloatLongitude(3), util::FloatLatitude(4)}};
engine::api::MatchParameters reference_1{};
reference_1.coordinates = coords_1;
auto result_1 = api::parseParameters<engine::api::MatchParameters>("1,2;3,4");
BOOST_CHECK(result_1);
CHECK_EQUAL_RANGE(reference_1.timestamps, result_1->timestamps);
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
}
BOOST_AUTO_TEST_CASE(valid_nearest_urls)
{
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)}};
engine::api::NearestParameters reference_1{};
reference_1.coordinates = coords_1;
auto result_1 = api::parseParameters<engine::api::NearestParameters>("1,2");
BOOST_CHECK(result_1);
BOOST_CHECK_EQUAL(reference_1.number_of_results, result_1->number_of_results);
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
}
BOOST_AUTO_TEST_CASE(valid_tile_urls)
{
engine::api::TileParameters reference_1{1, 2, 3};
auto result_1 = api::parseParameters<engine::api::TileParameters>("tile(1,2,3).mvt");
BOOST_CHECK(result_1);
BOOST_CHECK_EQUAL(reference_1.x, result_1->x);
BOOST_CHECK_EQUAL(reference_1.y, result_1->y);
BOOST_CHECK_EQUAL(reference_1.z, result_1->z);
}
BOOST_AUTO_TEST_CASE(valid_trip_urls)
{
std::vector<util::Coordinate> coords_1 = {{util::FloatLongitude(1), util::FloatLatitude(2)}, {util::FloatLongitude(3), util::FloatLatitude(4)}};
engine::api::TripParameters reference_1{};
reference_1.coordinates = coords_1;
auto result_1 = api::parseParameters<engine::api::TripParameters>("1,2;3,4");
BOOST_CHECK(result_1);
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -9,14 +9,9 @@ namespace server
{ {
namespace api namespace api
{ {
std::ostream& operator<<(std::ostream& out, const osrm::server::api::ParsedURL& url) std::ostream &operator<<(std::ostream &out, const osrm::server::api::ParsedURL &url)
{ {
out << url.service << ", " << url.version << ", " << url.profile << ", "; out << url.service << ", " << url.version << ", " << url.profile << ", " << url.query;
for (auto c : url.coordinates)
{
out << c << " ";
}
out << ", " << url.options;
return out; return out;
} }
@ -24,12 +19,11 @@ std::ostream& operator<<(std::ostream& out, const osrm::server::api::ParsedURL&
} }
} }
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
#define CHECK_EQUAL_RANGE(R1, R2) \ #define CHECK_EQUAL_RANGE(R1, R2) \
BOOST_CHECK_EQUAL_COLLECTIONS(R1.begin(), R1.end(), R2.begin(), R2.end()); BOOST_CHECK_EQUAL_COLLECTIONS(R1.begin(), R1.end(), R2.begin(), R2.end());
BOOST_AUTO_TEST_SUITE(api_url_parser) BOOST_AUTO_TEST_SUITE(api_url_parser)
@ -57,53 +51,52 @@ BOOST_AUTO_TEST_CASE(invalid_urls)
BOOST_AUTO_TEST_CASE(valid_urls) BOOST_AUTO_TEST_CASE(valid_urls)
{ {
std::vector<util::Coordinate> coords_1 = { api::ParsedURL reference_1{"route", 1, "profile", "0,1;2,3;4,5?options=value&foo=bar"};
// lat,lon
util::Coordinate(util::FloatLongitude(0), util::FloatLatitude(1)),
util::Coordinate(util::FloatLongitude(2), util::FloatLatitude(3)),
util::Coordinate(util::FloatLongitude(4), util::FloatLatitude(5)),
};
api::ParsedURL reference_1{"route", 1, "profile", coords_1, "options=value&foo=bar"};
auto result_1 = api::parseURL("/route/v1/profile/0,1;2,3;4,5?options=value&foo=bar"); auto result_1 = api::parseURL("/route/v1/profile/0,1;2,3;4,5?options=value&foo=bar");
BOOST_CHECK(result_1); BOOST_CHECK(result_1);
BOOST_CHECK_EQUAL(reference_1.service, result_1->service); BOOST_CHECK_EQUAL(reference_1.service, result_1->service);
BOOST_CHECK_EQUAL(reference_1.version, result_1->version); BOOST_CHECK_EQUAL(reference_1.version, result_1->version);
BOOST_CHECK_EQUAL(reference_1.profile, result_1->profile); BOOST_CHECK_EQUAL(reference_1.profile, result_1->profile);
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates); CHECK_EQUAL_RANGE(reference_1.query, result_1->query);
BOOST_CHECK_EQUAL(reference_1.options, result_1->options);
// no options // no options
api::ParsedURL reference_2{"route", 1, "profile", coords_1, ""}; api::ParsedURL reference_2{"route", 1, "profile", "0,1;2,3;4,5"};
auto result_2 = api::parseURL("/route/v1/profile/0,1;2,3;4,5"); auto result_2 = api::parseURL("/route/v1/profile/0,1;2,3;4,5");
BOOST_CHECK(result_2); BOOST_CHECK(result_2);
BOOST_CHECK_EQUAL(reference_2.service, result_2->service); BOOST_CHECK_EQUAL(reference_2.service, result_2->service);
BOOST_CHECK_EQUAL(reference_2.version, result_2->version); BOOST_CHECK_EQUAL(reference_2.version, result_2->version);
BOOST_CHECK_EQUAL(reference_2.profile, result_2->profile); BOOST_CHECK_EQUAL(reference_2.profile, result_2->profile);
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates); CHECK_EQUAL_RANGE(reference_2.query, result_2->query);
BOOST_CHECK_EQUAL(reference_2.options, result_2->options);
// one coordinate // one coordinate
std::vector<util::Coordinate> coords_3 = { std::vector<util::Coordinate> coords_3 = {
util::Coordinate(util::FloatLongitude(0), util::FloatLatitude(1)), util::Coordinate(util::FloatLongitude(0), util::FloatLatitude(1)),
}; };
api::ParsedURL reference_3{"route", 1, "profile", coords_3, ""}; api::ParsedURL reference_3{"route", 1, "profile", "0,1"};
auto result_3 = api::parseURL("/route/v1/profile/0,1"); auto result_3 = api::parseURL("/route/v1/profile/0,1");
BOOST_CHECK(result_3); BOOST_CHECK(result_3);
BOOST_CHECK_EQUAL(reference_3.service, result_3->service); BOOST_CHECK_EQUAL(reference_3.service, result_3->service);
BOOST_CHECK_EQUAL(reference_3.version, result_3->version); BOOST_CHECK_EQUAL(reference_3.version, result_3->version);
BOOST_CHECK_EQUAL(reference_3.profile, result_3->profile); BOOST_CHECK_EQUAL(reference_3.profile, result_3->profile);
CHECK_EQUAL_RANGE(reference_3.coordinates, result_3->coordinates); CHECK_EQUAL_RANGE(reference_3.query, result_3->query);
BOOST_CHECK_EQUAL(reference_3.options, result_3->options);
// polyline // polyline
api::ParsedURL reference_5{"route", 1, "profile", coords_1, ""}; api::ParsedURL reference_5{"route", 1, "profile", "polyline(_ibE?_seK_seK_seK_seK)?"};
auto result_5 = api::parseURL("/route/v1/profile/polyline(_ibE?_seK_seK_seK_seK)?"); auto result_5 = api::parseURL("/route/v1/profile/polyline(_ibE?_seK_seK_seK_seK)?");
BOOST_CHECK(result_5); BOOST_CHECK(result_5);
BOOST_CHECK_EQUAL(reference_5.service, result_5->service); BOOST_CHECK_EQUAL(reference_5.service, result_5->service);
BOOST_CHECK_EQUAL(reference_5.version, result_5->version); BOOST_CHECK_EQUAL(reference_5.version, result_5->version);
BOOST_CHECK_EQUAL(reference_5.profile, result_5->profile); BOOST_CHECK_EQUAL(reference_5.profile, result_5->profile);
CHECK_EQUAL_RANGE(reference_5.coordinates, result_5->coordinates); CHECK_EQUAL_RANGE(reference_5.query, result_5->query);
BOOST_CHECK_EQUAL(reference_5.options, result_5->options);
// tile
api::ParsedURL reference_6{"route", 1, "profile", "tile(1,2,3).mvt"};
auto result_6 = api::parseURL("/route/v1/profile/tile(1,2,3).mvt");
BOOST_CHECK(result_5);
BOOST_CHECK_EQUAL(reference_6.service, result_6->service);
BOOST_CHECK_EQUAL(reference_6.version, result_6->version);
BOOST_CHECK_EQUAL(reference_6.profile, result_6->profile);
CHECK_EQUAL_RANGE(reference_6.query, result_6->query);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()