diff --git a/include/engine/api/base_api.hpp b/include/engine/api/base_api.hpp index ddf6b357a..b5ad0e121 100644 --- a/include/engine/api/base_api.hpp +++ b/include/engine/api/base_api.hpp @@ -72,6 +72,21 @@ class BaseAPI } } + flatbuffers::Offset>> MakeWaypoints(flatbuffers::FlatBufferBuilder& builder, const std::vector &segment_end_coordinates) const + { + BOOST_ASSERT(parameters.coordinates.size() > 0); + BOOST_ASSERT(parameters.coordinates.size() == segment_end_coordinates.size() + 1); + + std::vector> waypoints; + waypoints.resize(parameters.coordinates.size()); + waypoints[0] = MakeWaypoint(builder, segment_end_coordinates.front().source_phantom).Finish(); + + std::transform(segment_end_coordinates.begin(), segment_end_coordinates.end(), std::next(waypoints.begin()), [this, &builder](const PhantomNodes &phantom_pair) { + return MakeWaypoint(builder, phantom_pair.target_phantom).Finish(); + }); + return builder.CreateVector(waypoints); + } + // FIXME: gcc 4.9 does not like MakeWaypoints to be protected // protected: fbresult::WaypointBuilder MakeWaypoint(flatbuffers::FlatBufferBuilder& builder, const PhantomNode &phantom) const diff --git a/include/engine/api/flatbuffers/fbresult.fbs b/include/engine/api/flatbuffers/fbresult.fbs index af648d905..9584f9043 100644 --- a/include/engine/api/flatbuffers/fbresult.fbs +++ b/include/engine/api/flatbuffers/fbresult.fbs @@ -17,5 +17,6 @@ union ServiceResponse { table FBResult { code: string; message: string; + data_version: string; response: ServiceResponse; } \ No newline at end of file diff --git a/include/engine/api/flatbuffers/fbresult_generated.h b/include/engine/api/flatbuffers/fbresult_generated.h index 629b8a021..4caca54d9 100644 --- a/include/engine/api/flatbuffers/fbresult_generated.h +++ b/include/engine/api/flatbuffers/fbresult_generated.h @@ -33,8 +33,8 @@ struct LaneT; struct Intersection; struct IntersectionT; -struct Polyline; -struct PolylineT; +struct Geometry; +struct GeometryT; struct Step; struct StepT; @@ -186,91 +186,6 @@ inline const char *EnumNameTurn(Turn e) { return EnumNamesTurn()[index]; } -enum Geometry { - Geometry_NONE = 0, - Geometry_polyline = 1, - Geometry_polyline6 = 2, - Geometry_coordinates = 3, - Geometry_MIN = Geometry_NONE, - Geometry_MAX = Geometry_coordinates -}; - -inline const Geometry (&EnumValuesGeometry())[4] { - static const Geometry values[] = { - Geometry_NONE, - Geometry_polyline, - Geometry_polyline6, - Geometry_coordinates - }; - return values; -} - -inline const char * const *EnumNamesGeometry() { - static const char * const names[5] = { - "NONE", - "polyline", - "polyline6", - "coordinates", - nullptr - }; - return names; -} - -inline const char *EnumNameGeometry(Geometry e) { - if (e < Geometry_NONE || e > Geometry_coordinates) return ""; - const size_t index = static_cast(e); - return EnumNamesGeometry()[index]; -} - -struct GeometryUnion { - Geometry type; - void *value; - - GeometryUnion() : type(Geometry_NONE), value(nullptr) {} - GeometryUnion(GeometryUnion&& u) FLATBUFFERS_NOEXCEPT : - type(Geometry_NONE), value(nullptr) - { std::swap(type, u.type); std::swap(value, u.value); } - GeometryUnion(const GeometryUnion &) FLATBUFFERS_NOEXCEPT; - GeometryUnion &operator=(const GeometryUnion &u) FLATBUFFERS_NOEXCEPT - { GeometryUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; } - GeometryUnion &operator=(GeometryUnion &&u) FLATBUFFERS_NOEXCEPT - { std::swap(type, u.type); std::swap(value, u.value); return *this; } - ~GeometryUnion() { Reset(); } - - void Reset(); - - static void *UnPack(const void *obj, Geometry type, const flatbuffers::resolver_function_t *resolver); - flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const; - - std::string *Aspolyline() { - return type == Geometry_polyline ? - reinterpret_cast(value) : nullptr; - } - const std::string *Aspolyline() const { - return type == Geometry_polyline ? - reinterpret_cast(value) : nullptr; - } - std::string *Aspolyline6() { - return type == Geometry_polyline6 ? - reinterpret_cast(value) : nullptr; - } - const std::string *Aspolyline6() const { - return type == Geometry_polyline6 ? - reinterpret_cast(value) : nullptr; - } - osrm::engine::api::fbresult::PolylineT *Ascoordinates() { - return type == Geometry_coordinates ? - reinterpret_cast(value) : nullptr; - } - const osrm::engine::api::fbresult::PolylineT *Ascoordinates() const { - return type == Geometry_coordinates ? - reinterpret_cast(value) : nullptr; - } -}; - -bool VerifyGeometry(flatbuffers::Verifier &verifier, const void *obj, Geometry type); -bool VerifyGeometryVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types); - enum ServiceResponse { ServiceResponse_NONE = 0, ServiceResponse_match = 1, @@ -1041,7 +956,7 @@ flatbuffers::Offset CreateLane(flatbuffers::FlatBufferBuilder &_fbb, const struct IntersectionT : public flatbuffers::NativeTable { typedef Intersection TableType; std::unique_ptr location; - std::vector bearings; + std::vector bearings; std::vector classes; std::vector entry; uint32_t in; @@ -1067,8 +982,8 @@ struct Intersection FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const osrm::engine::api::fbresult::Position *location() const { return GetStruct(VT_LOCATION); } - const flatbuffers::Vector *bearings() const { - return GetPointer *>(VT_BEARINGS); + const flatbuffers::Vector *bearings() const { + return GetPointer *>(VT_BEARINGS); } const flatbuffers::Vector> *classes() const { return GetPointer> *>(VT_CLASSES); @@ -1113,7 +1028,7 @@ struct IntersectionBuilder { void add_location(const osrm::engine::api::fbresult::Position *location) { fbb_.AddStruct(Intersection::VT_LOCATION, location); } - void add_bearings(flatbuffers::Offset> bearings) { + void add_bearings(flatbuffers::Offset> bearings) { fbb_.AddOffset(Intersection::VT_BEARINGS, bearings); } void add_classes(flatbuffers::Offset>> classes) { @@ -1146,7 +1061,7 @@ struct IntersectionBuilder { inline flatbuffers::Offset CreateIntersection( flatbuffers::FlatBufferBuilder &_fbb, const osrm::engine::api::fbresult::Position *location = 0, - flatbuffers::Offset> bearings = 0, + flatbuffers::Offset> bearings = 0, flatbuffers::Offset>> classes = 0, flatbuffers::Offset> entry = 0, uint32_t in = 0, @@ -1166,13 +1081,13 @@ inline flatbuffers::Offset CreateIntersection( inline flatbuffers::Offset CreateIntersectionDirect( flatbuffers::FlatBufferBuilder &_fbb, const osrm::engine::api::fbresult::Position *location = 0, - const std::vector *bearings = nullptr, + const std::vector *bearings = nullptr, const std::vector> *classes = nullptr, const std::vector *entry = nullptr, uint32_t in = 0, uint32_t out = 0, const std::vector> *lanes = nullptr) { - auto bearings__ = bearings ? _fbb.CreateVector(*bearings) : 0; + auto bearings__ = bearings ? _fbb.CreateVector(*bearings) : 0; auto classes__ = classes ? _fbb.CreateVector>(*classes) : 0; auto entry__ = entry ? _fbb.CreateVector(*entry) : 0; auto lanes__ = lanes ? _fbb.CreateVector>(*lanes) : 0; @@ -1189,79 +1104,110 @@ inline flatbuffers::Offset CreateIntersectionDirect( flatbuffers::Offset CreateIntersection(flatbuffers::FlatBufferBuilder &_fbb, const IntersectionT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); -struct PolylineT : public flatbuffers::NativeTable { - typedef Polyline TableType; - std::vector polyline; - PolylineT() { +struct GeometryT : public flatbuffers::NativeTable { + typedef Geometry TableType; + std::string polyline; + std::string polyline6; + std::vector coordinates; + GeometryT() { } }; -struct Polyline FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef PolylineT NativeTableType; +struct Geometry FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef GeometryT NativeTableType; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_POLYLINE = 4 + VT_POLYLINE = 4, + VT_POLYLINE6 = 6, + VT_COORDINATES = 8 }; - const flatbuffers::Vector *polyline() const { - return GetPointer *>(VT_POLYLINE); + const flatbuffers::String *polyline() const { + return GetPointer(VT_POLYLINE); + } + const flatbuffers::String *polyline6() const { + return GetPointer(VT_POLYLINE6); + } + const flatbuffers::Vector *coordinates() const { + return GetPointer *>(VT_COORDINATES); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_POLYLINE) && - verifier.VerifyVector(polyline()) && + verifier.VerifyString(polyline()) && + VerifyOffset(verifier, VT_POLYLINE6) && + verifier.VerifyString(polyline6()) && + VerifyOffset(verifier, VT_COORDINATES) && + verifier.VerifyVector(coordinates()) && verifier.EndTable(); } - PolylineT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; - void UnPackTo(PolylineT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; - static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const PolylineT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + GeometryT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(GeometryT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const GeometryT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); }; -struct PolylineBuilder { +struct GeometryBuilder { flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_polyline(flatbuffers::Offset> polyline) { - fbb_.AddOffset(Polyline::VT_POLYLINE, polyline); + void add_polyline(flatbuffers::Offset polyline) { + fbb_.AddOffset(Geometry::VT_POLYLINE, polyline); } - explicit PolylineBuilder(flatbuffers::FlatBufferBuilder &_fbb) + void add_polyline6(flatbuffers::Offset polyline6) { + fbb_.AddOffset(Geometry::VT_POLYLINE6, polyline6); + } + void add_coordinates(flatbuffers::Offset> coordinates) { + fbb_.AddOffset(Geometry::VT_COORDINATES, coordinates); + } + explicit GeometryBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - PolylineBuilder &operator=(const PolylineBuilder &); - flatbuffers::Offset Finish() { + GeometryBuilder &operator=(const GeometryBuilder &); + flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); + auto o = flatbuffers::Offset(end); return o; } }; -inline flatbuffers::Offset CreatePolyline( +inline flatbuffers::Offset CreateGeometry( flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset> polyline = 0) { - PolylineBuilder builder_(_fbb); + flatbuffers::Offset polyline = 0, + flatbuffers::Offset polyline6 = 0, + flatbuffers::Offset> coordinates = 0) { + GeometryBuilder builder_(_fbb); + builder_.add_coordinates(coordinates); + builder_.add_polyline6(polyline6); builder_.add_polyline(polyline); return builder_.Finish(); } -inline flatbuffers::Offset CreatePolylineDirect( +inline flatbuffers::Offset CreateGeometryDirect( flatbuffers::FlatBufferBuilder &_fbb, - const std::vector *polyline = nullptr) { - auto polyline__ = polyline ? _fbb.CreateVectorOfStructs(*polyline) : 0; - return osrm::engine::api::fbresult::CreatePolyline( + const char *polyline = nullptr, + const char *polyline6 = nullptr, + const std::vector *coordinates = nullptr) { + auto polyline__ = polyline ? _fbb.CreateString(polyline) : 0; + auto polyline6__ = polyline6 ? _fbb.CreateString(polyline6) : 0; + auto coordinates__ = coordinates ? _fbb.CreateVectorOfStructs(*coordinates) : 0; + return osrm::engine::api::fbresult::CreateGeometry( _fbb, - polyline__); + polyline__, + polyline6__, + coordinates__); } -flatbuffers::Offset CreatePolyline(flatbuffers::FlatBufferBuilder &_fbb, const PolylineT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +flatbuffers::Offset CreateGeometry(flatbuffers::FlatBufferBuilder &_fbb, const GeometryT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); struct StepT : public flatbuffers::NativeTable { typedef Step TableType; double distance; double duration; - GeometryUnion geometry; + std::unique_ptr geometry; + double weight; std::string name; - uint32_t ref; + std::string ref; std::string pronunciation; - std::vector destinations; - std::vector exits; + std::string destinations; + std::string exits; std::string mode; std::unique_ptr maneuver; std::vector> intersections; @@ -1271,7 +1217,7 @@ struct StepT : public flatbuffers::NativeTable { StepT() : distance(0.0), duration(0.0), - ref(0), + weight(0.0), driving_side(false) { } }; @@ -1281,8 +1227,8 @@ struct Step FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_DISTANCE = 4, VT_DURATION = 6, - VT_GEOMETRY_TYPE = 8, - VT_GEOMETRY = 10, + VT_GEOMETRY = 8, + VT_WEIGHT = 10, VT_NAME = 12, VT_REF = 14, VT_PRONUNCIATION = 16, @@ -1301,35 +1247,26 @@ struct Step FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { double duration() const { return GetField(VT_DURATION, 0.0); } - osrm::engine::api::fbresult::Geometry geometry_type() const { - return static_cast(GetField(VT_GEOMETRY_TYPE, 0)); + const osrm::engine::api::fbresult::Geometry *geometry() const { + return GetPointer(VT_GEOMETRY); } - const void *geometry() const { - return GetPointer(VT_GEOMETRY); - } - const flatbuffers::String *geometry_as_polyline() const { - return geometry_type() == osrm::engine::api::fbresult::Geometry_polyline ? static_cast(geometry()) : nullptr; - } - const flatbuffers::String *geometry_as_polyline6() const { - return geometry_type() == osrm::engine::api::fbresult::Geometry_polyline6 ? static_cast(geometry()) : nullptr; - } - const osrm::engine::api::fbresult::Polyline *geometry_as_coordinates() const { - return geometry_type() == osrm::engine::api::fbresult::Geometry_coordinates ? static_cast(geometry()) : nullptr; + double weight() const { + return GetField(VT_WEIGHT, 0.0); } const flatbuffers::String *name() const { return GetPointer(VT_NAME); } - uint32_t ref() const { - return GetField(VT_REF, 0); + const flatbuffers::String *ref() const { + return GetPointer(VT_REF); } const flatbuffers::String *pronunciation() const { return GetPointer(VT_PRONUNCIATION); } - const flatbuffers::Vector> *destinations() const { - return GetPointer> *>(VT_DESTINATIONS); + const flatbuffers::String *destinations() const { + return GetPointer(VT_DESTINATIONS); } - const flatbuffers::Vector> *exits() const { - return GetPointer> *>(VT_EXITS); + const flatbuffers::String *exits() const { + return GetPointer(VT_EXITS); } const flatbuffers::String *mode() const { return GetPointer(VT_MODE); @@ -1353,20 +1290,19 @@ struct Step FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { return VerifyTableStart(verifier) && VerifyField(verifier, VT_DISTANCE) && VerifyField(verifier, VT_DURATION) && - VerifyField(verifier, VT_GEOMETRY_TYPE) && VerifyOffset(verifier, VT_GEOMETRY) && - VerifyGeometry(verifier, geometry(), geometry_type()) && + verifier.VerifyTable(geometry()) && + VerifyField(verifier, VT_WEIGHT) && VerifyOffset(verifier, VT_NAME) && verifier.VerifyString(name()) && - VerifyField(verifier, VT_REF) && + VerifyOffset(verifier, VT_REF) && + verifier.VerifyString(ref()) && VerifyOffset(verifier, VT_PRONUNCIATION) && verifier.VerifyString(pronunciation()) && VerifyOffset(verifier, VT_DESTINATIONS) && - verifier.VerifyVector(destinations()) && - verifier.VerifyVectorOfStrings(destinations()) && + verifier.VerifyString(destinations()) && VerifyOffset(verifier, VT_EXITS) && - verifier.VerifyVector(exits()) && - verifier.VerifyVectorOfStrings(exits()) && + verifier.VerifyString(exits()) && VerifyOffset(verifier, VT_MODE) && verifier.VerifyString(mode()) && VerifyOffset(verifier, VT_MANEUVER) && @@ -1395,25 +1331,25 @@ struct StepBuilder { void add_duration(double duration) { fbb_.AddElement(Step::VT_DURATION, duration, 0.0); } - void add_geometry_type(osrm::engine::api::fbresult::Geometry geometry_type) { - fbb_.AddElement(Step::VT_GEOMETRY_TYPE, static_cast(geometry_type), 0); - } - void add_geometry(flatbuffers::Offset geometry) { + void add_geometry(flatbuffers::Offset geometry) { fbb_.AddOffset(Step::VT_GEOMETRY, geometry); } + void add_weight(double weight) { + fbb_.AddElement(Step::VT_WEIGHT, weight, 0.0); + } void add_name(flatbuffers::Offset name) { fbb_.AddOffset(Step::VT_NAME, name); } - void add_ref(uint32_t ref) { - fbb_.AddElement(Step::VT_REF, ref, 0); + void add_ref(flatbuffers::Offset ref) { + fbb_.AddOffset(Step::VT_REF, ref); } void add_pronunciation(flatbuffers::Offset pronunciation) { fbb_.AddOffset(Step::VT_PRONUNCIATION, pronunciation); } - void add_destinations(flatbuffers::Offset>> destinations) { + void add_destinations(flatbuffers::Offset destinations) { fbb_.AddOffset(Step::VT_DESTINATIONS, destinations); } - void add_exits(flatbuffers::Offset>> exits) { + void add_exits(flatbuffers::Offset exits) { fbb_.AddOffset(Step::VT_EXITS, exits); } void add_mode(flatbuffers::Offset mode) { @@ -1450,13 +1386,13 @@ inline flatbuffers::Offset CreateStep( flatbuffers::FlatBufferBuilder &_fbb, double distance = 0.0, double duration = 0.0, - osrm::engine::api::fbresult::Geometry geometry_type = osrm::engine::api::fbresult::Geometry_NONE, - flatbuffers::Offset geometry = 0, + flatbuffers::Offset geometry = 0, + double weight = 0.0, flatbuffers::Offset name = 0, - uint32_t ref = 0, + flatbuffers::Offset ref = 0, flatbuffers::Offset pronunciation = 0, - flatbuffers::Offset>> destinations = 0, - flatbuffers::Offset>> exits = 0, + flatbuffers::Offset destinations = 0, + flatbuffers::Offset exits = 0, flatbuffers::Offset mode = 0, flatbuffers::Offset maneuver = 0, flatbuffers::Offset>> intersections = 0, @@ -1464,6 +1400,7 @@ inline flatbuffers::Offset CreateStep( flatbuffers::Offset rotary_pronunciation = 0, bool driving_side = false) { StepBuilder builder_(_fbb); + builder_.add_weight(weight); builder_.add_duration(duration); builder_.add_distance(distance); builder_.add_rotary_pronunciation(rotary_pronunciation); @@ -1478,7 +1415,6 @@ inline flatbuffers::Offset CreateStep( builder_.add_name(name); builder_.add_geometry(geometry); builder_.add_driving_side(driving_side); - builder_.add_geometry_type(geometry_type); return builder_.Finish(); } @@ -1486,13 +1422,13 @@ inline flatbuffers::Offset CreateStepDirect( flatbuffers::FlatBufferBuilder &_fbb, double distance = 0.0, double duration = 0.0, - osrm::engine::api::fbresult::Geometry geometry_type = osrm::engine::api::fbresult::Geometry_NONE, - flatbuffers::Offset geometry = 0, + flatbuffers::Offset geometry = 0, + double weight = 0.0, const char *name = nullptr, - uint32_t ref = 0, + const char *ref = nullptr, const char *pronunciation = nullptr, - const std::vector> *destinations = nullptr, - const std::vector> *exits = nullptr, + const char *destinations = nullptr, + const char *exits = nullptr, const char *mode = nullptr, flatbuffers::Offset maneuver = 0, const std::vector> *intersections = nullptr, @@ -1500,9 +1436,10 @@ inline flatbuffers::Offset CreateStepDirect( const char *rotary_pronunciation = nullptr, bool driving_side = false) { auto name__ = name ? _fbb.CreateString(name) : 0; + auto ref__ = ref ? _fbb.CreateString(ref) : 0; auto pronunciation__ = pronunciation ? _fbb.CreateString(pronunciation) : 0; - auto destinations__ = destinations ? _fbb.CreateVector>(*destinations) : 0; - auto exits__ = exits ? _fbb.CreateVector>(*exits) : 0; + auto destinations__ = destinations ? _fbb.CreateString(destinations) : 0; + auto exits__ = exits ? _fbb.CreateString(exits) : 0; auto mode__ = mode ? _fbb.CreateString(mode) : 0; auto intersections__ = intersections ? _fbb.CreateVector>(*intersections) : 0; auto rotary_name__ = rotary_name ? _fbb.CreateString(rotary_name) : 0; @@ -1511,10 +1448,10 @@ inline flatbuffers::Offset CreateStepDirect( _fbb, distance, duration, - geometry_type, geometry, + weight, name__, - ref, + ref__, pronunciation__, destinations__, exits__, @@ -1670,7 +1607,7 @@ struct RouteObjectT : public flatbuffers::NativeTable { double weight; std::string weight_name; double confidence; - GeometryUnion geometry; + std::unique_ptr geometry; std::vector> legs; RouteObjectT() : distance(0.0), @@ -1688,9 +1625,8 @@ struct RouteObject FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_WEIGHT = 8, VT_WEIGHT_NAME = 10, VT_CONFIDENCE = 12, - VT_GEOMETRY_TYPE = 14, - VT_GEOMETRY = 16, - VT_LEGS = 18 + VT_GEOMETRY = 14, + VT_LEGS = 16 }; double distance() const { return GetField(VT_DISTANCE, 0.0); @@ -1707,20 +1643,8 @@ struct RouteObject FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { double confidence() const { return GetField(VT_CONFIDENCE, 0.0); } - osrm::engine::api::fbresult::Geometry geometry_type() const { - return static_cast(GetField(VT_GEOMETRY_TYPE, 0)); - } - const void *geometry() const { - return GetPointer(VT_GEOMETRY); - } - const flatbuffers::String *geometry_as_polyline() const { - return geometry_type() == osrm::engine::api::fbresult::Geometry_polyline ? static_cast(geometry()) : nullptr; - } - const flatbuffers::String *geometry_as_polyline6() const { - return geometry_type() == osrm::engine::api::fbresult::Geometry_polyline6 ? static_cast(geometry()) : nullptr; - } - const osrm::engine::api::fbresult::Polyline *geometry_as_coordinates() const { - return geometry_type() == osrm::engine::api::fbresult::Geometry_coordinates ? static_cast(geometry()) : nullptr; + const osrm::engine::api::fbresult::Geometry *geometry() const { + return GetPointer(VT_GEOMETRY); } const flatbuffers::Vector> *legs() const { return GetPointer> *>(VT_LEGS); @@ -1733,9 +1657,8 @@ struct RouteObject FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffset(verifier, VT_WEIGHT_NAME) && verifier.VerifyString(weight_name()) && VerifyField(verifier, VT_CONFIDENCE) && - VerifyField(verifier, VT_GEOMETRY_TYPE) && VerifyOffset(verifier, VT_GEOMETRY) && - VerifyGeometry(verifier, geometry(), geometry_type()) && + verifier.VerifyTable(geometry()) && VerifyOffset(verifier, VT_LEGS) && verifier.VerifyVector(legs()) && verifier.VerifyVectorOfTables(legs()) && @@ -1764,10 +1687,7 @@ struct RouteObjectBuilder { void add_confidence(double confidence) { fbb_.AddElement(RouteObject::VT_CONFIDENCE, confidence, 0.0); } - void add_geometry_type(osrm::engine::api::fbresult::Geometry geometry_type) { - fbb_.AddElement(RouteObject::VT_GEOMETRY_TYPE, static_cast(geometry_type), 0); - } - void add_geometry(flatbuffers::Offset geometry) { + void add_geometry(flatbuffers::Offset geometry) { fbb_.AddOffset(RouteObject::VT_GEOMETRY, geometry); } void add_legs(flatbuffers::Offset>> legs) { @@ -1792,8 +1712,7 @@ inline flatbuffers::Offset CreateRouteObject( double weight = 0.0, flatbuffers::Offset weight_name = 0, double confidence = 0.0, - osrm::engine::api::fbresult::Geometry geometry_type = osrm::engine::api::fbresult::Geometry_NONE, - flatbuffers::Offset geometry = 0, + flatbuffers::Offset geometry = 0, flatbuffers::Offset>> legs = 0) { RouteObjectBuilder builder_(_fbb); builder_.add_confidence(confidence); @@ -1803,7 +1722,6 @@ inline flatbuffers::Offset CreateRouteObject( builder_.add_legs(legs); builder_.add_geometry(geometry); builder_.add_weight_name(weight_name); - builder_.add_geometry_type(geometry_type); return builder_.Finish(); } @@ -1814,8 +1732,7 @@ inline flatbuffers::Offset CreateRouteObjectDirect( double weight = 0.0, const char *weight_name = nullptr, double confidence = 0.0, - osrm::engine::api::fbresult::Geometry geometry_type = osrm::engine::api::fbresult::Geometry_NONE, - flatbuffers::Offset geometry = 0, + flatbuffers::Offset geometry = 0, const std::vector> *legs = nullptr) { auto weight_name__ = weight_name ? _fbb.CreateString(weight_name) : 0; auto legs__ = legs ? _fbb.CreateVector>(*legs) : 0; @@ -1826,7 +1743,6 @@ inline flatbuffers::Offset CreateRouteObjectDirect( weight, weight_name__, confidence, - geometry_type, geometry, legs__); } @@ -2296,6 +2212,7 @@ struct FBResultT : public flatbuffers::NativeTable { typedef FBResult TableType; std::string code; std::string message; + std::string data_version; ServiceResponseUnion response; FBResultT() { } @@ -2306,8 +2223,9 @@ struct FBResult FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_CODE = 4, VT_MESSAGE = 6, - VT_RESPONSE_TYPE = 8, - VT_RESPONSE = 10 + VT_DATA_VERSION = 8, + VT_RESPONSE_TYPE = 10, + VT_RESPONSE = 12 }; const flatbuffers::String *code() const { return GetPointer(VT_CODE); @@ -2315,6 +2233,9 @@ struct FBResult FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::String *message() const { return GetPointer(VT_MESSAGE); } + const flatbuffers::String *data_version() const { + return GetPointer(VT_DATA_VERSION); + } osrm::engine::api::fbresult::ServiceResponse response_type() const { return static_cast(GetField(VT_RESPONSE_TYPE, 0)); } @@ -2343,6 +2264,8 @@ struct FBResult FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyString(code()) && VerifyOffset(verifier, VT_MESSAGE) && verifier.VerifyString(message()) && + VerifyOffset(verifier, VT_DATA_VERSION) && + verifier.VerifyString(data_version()) && VerifyField(verifier, VT_RESPONSE_TYPE) && VerifyOffset(verifier, VT_RESPONSE) && VerifyServiceResponse(verifier, response(), response_type()) && @@ -2382,6 +2305,9 @@ struct FBResultBuilder { void add_message(flatbuffers::Offset message) { fbb_.AddOffset(FBResult::VT_MESSAGE, message); } + void add_data_version(flatbuffers::Offset data_version) { + fbb_.AddOffset(FBResult::VT_DATA_VERSION, data_version); + } void add_response_type(osrm::engine::api::fbresult::ServiceResponse response_type) { fbb_.AddElement(FBResult::VT_RESPONSE_TYPE, static_cast(response_type), 0); } @@ -2404,10 +2330,12 @@ inline flatbuffers::Offset CreateFBResult( flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset code = 0, flatbuffers::Offset message = 0, + flatbuffers::Offset data_version = 0, osrm::engine::api::fbresult::ServiceResponse response_type = osrm::engine::api::fbresult::ServiceResponse_NONE, flatbuffers::Offset response = 0) { FBResultBuilder builder_(_fbb); builder_.add_response(response); + builder_.add_data_version(data_version); builder_.add_message(message); builder_.add_code(code); builder_.add_response_type(response_type); @@ -2418,14 +2346,17 @@ inline flatbuffers::Offset CreateFBResultDirect( flatbuffers::FlatBufferBuilder &_fbb, const char *code = nullptr, const char *message = nullptr, + const char *data_version = nullptr, osrm::engine::api::fbresult::ServiceResponse response_type = osrm::engine::api::fbresult::ServiceResponse_NONE, flatbuffers::Offset response = 0) { auto code__ = code ? _fbb.CreateString(code) : 0; auto message__ = message ? _fbb.CreateString(message) : 0; + auto data_version__ = data_version ? _fbb.CreateString(data_version) : 0; return osrm::engine::api::fbresult::CreateFBResult( _fbb, code__, message__, + data_version__, response_type, response); } @@ -2666,30 +2597,36 @@ inline flatbuffers::Offset CreateIntersection(flatbuffers::FlatBuf _lanes); } -inline PolylineT *Polyline::UnPack(const flatbuffers::resolver_function_t *_resolver) const { - auto _o = new PolylineT(); +inline GeometryT *Geometry::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = new GeometryT(); UnPackTo(_o, _resolver); return _o; } -inline void Polyline::UnPackTo(PolylineT *_o, const flatbuffers::resolver_function_t *_resolver) const { +inline void Geometry::UnPackTo(GeometryT *_o, const flatbuffers::resolver_function_t *_resolver) const { (void)_o; (void)_resolver; - { auto _e = polyline(); if (_e) { _o->polyline.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->polyline[_i] = *_e->Get(_i); } } }; + { auto _e = polyline(); if (_e) _o->polyline = _e->str(); }; + { auto _e = polyline6(); if (_e) _o->polyline6 = _e->str(); }; + { auto _e = coordinates(); if (_e) { _o->coordinates.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->coordinates[_i] = *_e->Get(_i); } } }; } -inline flatbuffers::Offset Polyline::Pack(flatbuffers::FlatBufferBuilder &_fbb, const PolylineT* _o, const flatbuffers::rehasher_function_t *_rehasher) { - return CreatePolyline(_fbb, _o, _rehasher); +inline flatbuffers::Offset Geometry::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GeometryT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateGeometry(_fbb, _o, _rehasher); } -inline flatbuffers::Offset CreatePolyline(flatbuffers::FlatBufferBuilder &_fbb, const PolylineT *_o, const flatbuffers::rehasher_function_t *_rehasher) { +inline flatbuffers::Offset CreateGeometry(flatbuffers::FlatBufferBuilder &_fbb, const GeometryT *_o, const flatbuffers::rehasher_function_t *_rehasher) { (void)_rehasher; (void)_o; - struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const PolylineT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; - auto _polyline = _o->polyline.size() ? _fbb.CreateVectorOfStructs(_o->polyline) : 0; - return osrm::engine::api::fbresult::CreatePolyline( + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GeometryT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _polyline = _o->polyline.empty() ? 0 : _fbb.CreateString(_o->polyline); + auto _polyline6 = _o->polyline6.empty() ? 0 : _fbb.CreateString(_o->polyline6); + auto _coordinates = _o->coordinates.size() ? _fbb.CreateVectorOfStructs(_o->coordinates) : 0; + return osrm::engine::api::fbresult::CreateGeometry( _fbb, - _polyline); + _polyline, + _polyline6, + _coordinates); } inline StepT *Step::UnPack(const flatbuffers::resolver_function_t *_resolver) const { @@ -2703,13 +2640,13 @@ inline void Step::UnPackTo(StepT *_o, const flatbuffers::resolver_function_t *_r (void)_resolver; { auto _e = distance(); _o->distance = _e; }; { auto _e = duration(); _o->duration = _e; }; - { auto _e = geometry_type(); _o->geometry.type = _e; }; - { auto _e = geometry(); if (_e) _o->geometry.value = GeometryUnion::UnPack(_e, geometry_type(), _resolver); }; + { auto _e = geometry(); if (_e) _o->geometry = std::unique_ptr(_e->UnPack(_resolver)); }; + { auto _e = weight(); _o->weight = _e; }; { auto _e = name(); if (_e) _o->name = _e->str(); }; - { auto _e = ref(); _o->ref = _e; }; + { auto _e = ref(); if (_e) _o->ref = _e->str(); }; { auto _e = pronunciation(); if (_e) _o->pronunciation = _e->str(); }; - { auto _e = destinations(); if (_e) { _o->destinations.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->destinations[_i] = _e->Get(_i)->str(); } } }; - { auto _e = exits(); if (_e) { _o->exits.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->exits[_i] = _e->Get(_i)->str(); } } }; + { auto _e = destinations(); if (_e) _o->destinations = _e->str(); }; + { auto _e = exits(); if (_e) _o->exits = _e->str(); }; { auto _e = mode(); if (_e) _o->mode = _e->str(); }; { auto _e = maneuver(); if (_e) _o->maneuver = std::unique_ptr(_e->UnPack(_resolver)); }; { auto _e = intersections(); if (_e) { _o->intersections.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->intersections[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } }; @@ -2728,13 +2665,13 @@ inline flatbuffers::Offset CreateStep(flatbuffers::FlatBufferBuilder &_fbb struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StepT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; auto _distance = _o->distance; auto _duration = _o->duration; - auto _geometry_type = _o->geometry.type; - auto _geometry = _o->geometry.Pack(_fbb); + auto _geometry = _o->geometry ? CreateGeometry(_fbb, _o->geometry.get(), _rehasher) : 0; + auto _weight = _o->weight; auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name); - auto _ref = _o->ref; + auto _ref = _o->ref.empty() ? 0 : _fbb.CreateString(_o->ref); auto _pronunciation = _o->pronunciation.empty() ? 0 : _fbb.CreateString(_o->pronunciation); - auto _destinations = _o->destinations.size() ? _fbb.CreateVectorOfStrings(_o->destinations) : 0; - auto _exits = _o->exits.size() ? _fbb.CreateVectorOfStrings(_o->exits) : 0; + auto _destinations = _o->destinations.empty() ? 0 : _fbb.CreateString(_o->destinations); + auto _exits = _o->exits.empty() ? 0 : _fbb.CreateString(_o->exits); auto _mode = _o->mode.empty() ? 0 : _fbb.CreateString(_o->mode); auto _maneuver = _o->maneuver ? CreateStepManeuver(_fbb, _o->maneuver.get(), _rehasher) : 0; auto _intersections = _o->intersections.size() ? _fbb.CreateVector> (_o->intersections.size(), [](size_t i, _VectorArgs *__va) { return CreateIntersection(*__va->__fbb, __va->__o->intersections[i].get(), __va->__rehasher); }, &_va ) : 0; @@ -2745,8 +2682,8 @@ inline flatbuffers::Offset CreateStep(flatbuffers::FlatBufferBuilder &_fbb _fbb, _distance, _duration, - _geometry_type, _geometry, + _weight, _name, _ref, _pronunciation, @@ -2815,8 +2752,7 @@ inline void RouteObject::UnPackTo(RouteObjectT *_o, const flatbuffers::resolver_ { auto _e = weight(); _o->weight = _e; }; { auto _e = weight_name(); if (_e) _o->weight_name = _e->str(); }; { auto _e = confidence(); _o->confidence = _e; }; - { auto _e = geometry_type(); _o->geometry.type = _e; }; - { auto _e = geometry(); if (_e) _o->geometry.value = GeometryUnion::UnPack(_e, geometry_type(), _resolver); }; + { auto _e = geometry(); if (_e) _o->geometry = std::unique_ptr(_e->UnPack(_resolver)); }; { auto _e = legs(); if (_e) { _o->legs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->legs[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } }; } @@ -2833,8 +2769,7 @@ inline flatbuffers::Offset CreateRouteObject(flatbuffers::FlatBuffe auto _weight = _o->weight; auto _weight_name = _o->weight_name.empty() ? 0 : _fbb.CreateString(_o->weight_name); auto _confidence = _o->confidence; - auto _geometry_type = _o->geometry.type; - auto _geometry = _o->geometry.Pack(_fbb); + auto _geometry = _o->geometry ? CreateGeometry(_fbb, _o->geometry.get(), _rehasher) : 0; auto _legs = _o->legs.size() ? _fbb.CreateVector> (_o->legs.size(), [](size_t i, _VectorArgs *__va) { return CreateLeg(*__va->__fbb, __va->__o->legs[i].get(), __va->__rehasher); }, &_va ) : 0; return osrm::engine::api::fbresult::CreateRouteObject( _fbb, @@ -2843,7 +2778,6 @@ inline flatbuffers::Offset CreateRouteObject(flatbuffers::FlatBuffe _weight, _weight_name, _confidence, - _geometry_type, _geometry, _legs); } @@ -3016,6 +2950,7 @@ inline void FBResult::UnPackTo(FBResultT *_o, const flatbuffers::resolver_functi (void)_resolver; { auto _e = code(); if (_e) _o->code = _e->str(); }; { auto _e = message(); if (_e) _o->message = _e->str(); }; + { auto _e = data_version(); if (_e) _o->data_version = _e->str(); }; { auto _e = response_type(); _o->response.type = _e; }; { auto _e = response(); if (_e) _o->response.value = ServiceResponseUnion::UnPack(_e, response_type(), _resolver); }; } @@ -3030,127 +2965,18 @@ inline flatbuffers::Offset CreateFBResult(flatbuffers::FlatBufferBuild struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FBResultT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; auto _code = _o->code.empty() ? 0 : _fbb.CreateString(_o->code); auto _message = _o->message.empty() ? 0 : _fbb.CreateString(_o->message); + auto _data_version = _o->data_version.empty() ? 0 : _fbb.CreateString(_o->data_version); auto _response_type = _o->response.type; auto _response = _o->response.Pack(_fbb); return osrm::engine::api::fbresult::CreateFBResult( _fbb, _code, _message, + _data_version, _response_type, _response); } -inline bool VerifyGeometry(flatbuffers::Verifier &verifier, const void *obj, Geometry type) { - switch (type) { - case Geometry_NONE: { - return true; - } - case Geometry_polyline: { - auto ptr = reinterpret_cast(obj); - return verifier.VerifyString(ptr); - } - case Geometry_polyline6: { - auto ptr = reinterpret_cast(obj); - return verifier.VerifyString(ptr); - } - case Geometry_coordinates: { - auto ptr = reinterpret_cast(obj); - return verifier.VerifyTable(ptr); - } - default: return false; - } -} - -inline bool VerifyGeometryVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types) { - if (!values || !types) return !values && !types; - if (values->size() != types->size()) return false; - for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { - if (!VerifyGeometry( - verifier, values->Get(i), types->GetEnum(i))) { - return false; - } - } - return true; -} - -inline void *GeometryUnion::UnPack(const void *obj, Geometry type, const flatbuffers::resolver_function_t *resolver) { - switch (type) { - case Geometry_polyline: { - auto ptr = reinterpret_cast(obj); - return new std::string(ptr->c_str(), ptr->size()); - } - case Geometry_polyline6: { - auto ptr = reinterpret_cast(obj); - return new std::string(ptr->c_str(), ptr->size()); - } - case Geometry_coordinates: { - auto ptr = reinterpret_cast(obj); - return ptr->UnPack(resolver); - } - default: return nullptr; - } -} - -inline flatbuffers::Offset GeometryUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const { - switch (type) { - case Geometry_polyline: { - auto ptr = reinterpret_cast(value); - return _fbb.CreateString(*ptr).Union(); - } - case Geometry_polyline6: { - auto ptr = reinterpret_cast(value); - return _fbb.CreateString(*ptr).Union(); - } - case Geometry_coordinates: { - auto ptr = reinterpret_cast(value); - return CreatePolyline(_fbb, ptr, _rehasher).Union(); - } - default: return 0; - } -} - -inline GeometryUnion::GeometryUnion(const GeometryUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) { - switch (type) { - case Geometry_polyline: { - value = new std::string(*reinterpret_cast(u.value)); - break; - } - case Geometry_polyline6: { - value = new std::string(*reinterpret_cast(u.value)); - break; - } - case Geometry_coordinates: { - FLATBUFFERS_ASSERT(false); // osrm::engine::api::fbresult::PolylineT not copyable. - break; - } - default: - break; - } -} - -inline void GeometryUnion::Reset() { - switch (type) { - case Geometry_polyline: { - auto ptr = reinterpret_cast(value); - delete ptr; - break; - } - case Geometry_polyline6: { - auto ptr = reinterpret_cast(value); - delete ptr; - break; - } - case Geometry_coordinates: { - auto ptr = reinterpret_cast(value); - delete ptr; - break; - } - default: break; - } - value = nullptr; - type = Geometry_NONE; -} - inline bool VerifyServiceResponse(flatbuffers::Verifier &verifier, const void *obj, ServiceResponse type) { switch (type) { case ServiceResponse_NONE: { diff --git a/include/engine/api/flatbuffers/route.fbs b/include/engine/api/flatbuffers/route.fbs index 105541c83..b2e590c81 100644 --- a/include/engine/api/flatbuffers/route.fbs +++ b/include/engine/api/flatbuffers/route.fbs @@ -62,7 +62,7 @@ table Lane { table Intersection { location: Position; - bearings: [ushort]; + bearings: [short]; classes: [string]; entry: [bool]; in: uint; @@ -70,31 +70,28 @@ table Intersection { lanes: [Lane]; } -table Polyline { - polyline: [Position]; -} - -union Geometry { - polyline: string, - polyline6: string, - coordinates: Polyline +table Geometry { + polyline: string; + polyline6: string; + coordinates: [Position]; } table Step { distance: double; duration: double; geometry: Geometry; + weight: double; name: string; - ref: uint; + ref: string; pronunciation: string; - destinations: [string]; - exits: [string]; + destinations: string; + exits: string; mode: string; maneuver: StepManeuver; intersections: [Intersection]; rotary_name: string; rotary_pronunciation: string; - driving_side: bool; //Where true stands for the right side. + driving_side: bool; //Where true stands for the left side. } table Leg { diff --git a/include/engine/api/json_factory.hpp b/include/engine/api/json_factory.hpp index db30ecc9e..0ec505703 100644 --- a/include/engine/api/json_factory.hpp +++ b/include/engine/api/json_factory.hpp @@ -33,6 +33,18 @@ namespace json namespace detail { +// Check whether to include a modifier in the result of the API +inline bool isValidModifier(const guidance::StepManeuver maneuver) +{ + return (maneuver.waypoint_type == guidance::WaypointType::None || + maneuver.instruction.direction_modifier != osrm::guidance::DirectionModifier::UTurn); +} + +inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection) +{ + return intersection.lanes.lanes_in_turn > 0; +} + util::json::Array coordinateToLonLat(const util::Coordinate &coordinate); /** diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp index caaa92eb3..f32527867 100644 --- a/include/engine/api/route_api.hpp +++ b/include/engine/api/route_api.hpp @@ -36,22 +36,73 @@ namespace engine namespace api { -class RouteAPI : public BaseAPI -{ - public: +class RouteAPI : public BaseAPI { +public: RouteAPI(const datafacade::BaseDataFacade &facade_, const RouteParameters ¶meters_) - : BaseAPI(facade_, parameters_), parameters(parameters_) - { + : BaseAPI(facade_, parameters_), parameters(parameters_) { } + virtual void + MakeResponse(const InternalManyRoutesResult &raw_routes, + const std::vector + &all_start_end_points, // all used coordinates, ignoring waypoints= parameter + osrm::engine::api::ResultT &response) const { + BOOST_ASSERT(!raw_routes.routes.empty()); + + if (response.is()) { + auto &fb_result = response.get(); + MakeResponse(raw_routes, all_start_end_points, fb_result); + } else { + auto &json_result = response.get(); + MakeResponse(raw_routes, all_start_end_points, json_result); + } + } + + void + MakeResponse(const InternalManyRoutesResult &raw_routes, + const std::vector + &all_start_end_points, // all used coordinates, ignoring waypoints= parameter + flatbuffers::FlatBufferBuilder &fb_result) const + { + + fbresult::FBResultBuilder response(fb_result); + response.add_code(fb_result.CreateString("Ok")); + response.add_response_type(osrm::engine::api::fbresult::ServiceResponse::ServiceResponse_route); + + fbresult::RouteBuilder route(fb_result); + std::vector> routes; + for (const auto &raw_route : raw_routes.routes) + { + if (!raw_route.is_valid()) + continue; + + routes.push_back(MakeRoute(fb_result, + raw_route.segment_end_coordinates, + raw_route.unpacked_path_segments, + raw_route.source_traversed_in_reverse, + raw_route.target_traversed_in_reverse)); + } + + auto routes_vector = fb_result.CreateVector(routes); + route.add_routes(routes_vector); + route.add_waypoints(BaseAPI::MakeWaypoints(fb_result, all_start_end_points)); + response.add_response(route.Finish().Union()); + + auto data_timestamp = facade.GetTimestamp(); + if (!data_timestamp.empty()) + { + auto data_version_string = fb_result.CreateString(data_timestamp); + response.add_data_version(data_version_string); + } + + fb_result.Finish(response.Finish()); + } void MakeResponse(const InternalManyRoutesResult &raw_routes, const std::vector &all_start_end_points, // all used coordinates, ignoring waypoints= parameter util::json::Object &response) const { - BOOST_ASSERT(!raw_routes.routes.empty()); - util::json::Array jsRoutes; for (const auto &route : raw_routes.routes) @@ -77,20 +128,60 @@ class RouteAPI : public BaseAPI protected: template - util::json::Value MakeGeometry(ForwardIter begin, ForwardIter end) const + flatbuffers::Offset MakeGeometry(flatbuffers::FlatBufferBuilder& builder, ForwardIter begin, ForwardIter end) const { - if (parameters.geometries == RouteParameters::GeometriesType::Polyline) + fbresult::GeometryBuilder geometry(builder); + if (parameters.geometries == RouteParameters::GeometriesType::Polyline) { + auto polyline_string = builder.CreateString(encodePolyline<100000>(begin, end)); + geometry.add_polyline(polyline_string); + } else if (parameters.geometries == RouteParameters::GeometriesType::Polyline6) { + auto polyline_string = builder.CreateString(encodePolyline<1000000>(begin, end)); + geometry.add_polyline6(polyline_string); + } else { + std::vector coordinates; + coordinates.resize(std::distance(begin, end)); + std::transform(begin, end, coordinates.begin(), [](const Coordinate &c) { + return fbresult::Position{static_cast(util::toFloating(c.lon)), + static_cast(util::toFloating(c.lat))}; + }); + auto coordinates_vector = builder.CreateVectorOfStructs(coordinates); + geometry.add_coordinates(coordinates_vector); + } + return geometry.Finish(); + } + + boost::optional MakeGeometry(boost::optional>&& annotations) const + { + boost::optional json_geometry; + if (annotations) { + auto begin = annotations->begin(); + auto end = annotations->end(); + if (parameters.geometries == RouteParameters::GeometriesType::Polyline) + { + json_geometry = json::makePolyline<100000>(begin, end); + } else if (parameters.geometries == RouteParameters::GeometriesType::Polyline6) + { + json_geometry = json::makePolyline<1000000>(begin, end); + } else { + BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON); + json_geometry = json::makeGeoJSONGeometry(begin, end); + } + } + return json_geometry; + } + + template + flatbuffers::Offset> GetAnnotations(flatbuffers::FlatBufferBuilder& fb_result, guidance::LegGeometry &leg, GetFn Get) const + { + std::vector annotations_store; + annotations_store.reserve(leg.annotations.size()); + + for (const auto &step : leg.annotations) { - return json::makePolyline<100000>(begin, end); + annotations_store.push_back(Get(step)); } - if (parameters.geometries == RouteParameters::GeometriesType::Polyline6) - { - return json::makePolyline<1000000>(begin, end); - } - - BOOST_ASSERT(parameters.geometries == RouteParameters::GeometriesType::GeoJSON); - return json::makeGeoJSONGeometry(begin, end); + return fb_result.CreateVector(annotations_store); } template @@ -107,118 +198,364 @@ class RouteAPI : public BaseAPI return annotations_store; } + fbresult::ManeuverType WaypointTypeToFB(guidance::WaypointType type) const { + switch(type) { + case guidance::WaypointType::Arrive: + return fbresult::ManeuverType_Arrive; + case guidance::WaypointType::Depart: + return fbresult::ManeuverType_Depart; + default: + return fbresult::ManeuverType_Notification; + } + } + + fbresult::ManeuverType TurnTypeToFB(osrm::guidance::TurnType::Enum turn) const { + static std::map mappings={ + {osrm::guidance::TurnType::Invalid, fbresult::ManeuverType_Notification}, + {osrm::guidance::TurnType::NewName, fbresult::ManeuverType_NewName}, + {osrm::guidance::TurnType::Continue, fbresult::ManeuverType_Continue}, + {osrm::guidance::TurnType::Turn, fbresult::ManeuverType_Turn}, + {osrm::guidance::TurnType::Merge, fbresult::ManeuverType_Merge}, + {osrm::guidance::TurnType::OnRamp, fbresult::ManeuverType_OnRamp}, + {osrm::guidance::TurnType::OffRamp, fbresult::ManeuverType_OffRamp}, + {osrm::guidance::TurnType::Fork, fbresult::ManeuverType_Fork}, + {osrm::guidance::TurnType::EndOfRoad, fbresult::ManeuverType_EndOfRoad}, + {osrm::guidance::TurnType::Notification, fbresult::ManeuverType_Notification}, + {osrm::guidance::TurnType::EnterRoundabout, fbresult::ManeuverType_Roundabout}, + {osrm::guidance::TurnType::EnterAndExitRoundabout, fbresult::ManeuverType_ExitRoundabout}, + {osrm::guidance::TurnType::EnterRotary, fbresult::ManeuverType_Rotary}, + {osrm::guidance::TurnType::EnterAndExitRotary, fbresult::ManeuverType_ExitRotary}, + {osrm::guidance::TurnType::EnterRoundaboutIntersection, fbresult::ManeuverType_Roundabout}, + {osrm::guidance::TurnType::EnterAndExitRoundaboutIntersection, fbresult::ManeuverType_ExitRoundabout}, + {osrm::guidance::TurnType::NoTurn, fbresult::ManeuverType_Notification}, + {osrm::guidance::TurnType::Suppressed, fbresult::ManeuverType_Notification}, + {osrm::guidance::TurnType::EnterRoundaboutAtExit, fbresult::ManeuverType_Roundabout}, + {osrm::guidance::TurnType::ExitRoundabout, fbresult::ManeuverType_ExitRoundabout}, + {osrm::guidance::TurnType::EnterRotaryAtExit, fbresult::ManeuverType_Rotary}, + {osrm::guidance::TurnType::ExitRotary, fbresult::ManeuverType_ExitRotary}, + {osrm::guidance::TurnType::EnterRoundaboutIntersectionAtExit, fbresult::ManeuverType_Roundabout}, + {osrm::guidance::TurnType::ExitRoundaboutIntersection, fbresult::ManeuverType_ExitRoundabout}, + {osrm::guidance::TurnType::StayOnRoundabout, fbresult::ManeuverType_RoundaboutTurn}, + {osrm::guidance::TurnType::Sliproad, fbresult::ManeuverType_Notification}, + {osrm::guidance::TurnType::MaxTurnType, fbresult::ManeuverType_Notification} + }; + return mappings[turn]; + } + + fbresult::Turn TurnModifierToFB(osrm::guidance::DirectionModifier::Enum modifier) const { + static std::map mappings={ + {osrm::guidance::DirectionModifier::UTurn, fbresult::Turn_UTurn}, + {osrm::guidance::DirectionModifier::SharpRight, fbresult::Turn_SharpRight}, + {osrm::guidance::DirectionModifier::Right, fbresult::Turn_Right}, + {osrm::guidance::DirectionModifier::SlightRight, fbresult::Turn_SlightRight}, + {osrm::guidance::DirectionModifier::Straight, fbresult::Turn_Straight}, + {osrm::guidance::DirectionModifier::SlightLeft, fbresult::Turn_SlightLeft}, + {osrm::guidance::DirectionModifier::Left, fbresult::Turn_Left}, + {osrm::guidance::DirectionModifier::SharpLeft, fbresult::Turn_SharpLeft}, + }; + return mappings[modifier]; + } + + std::vector TurnLaneTypeToFB(const extractor::TurnLaneType::Mask lane_type) const { + const static fbresult::Turn mapping[] = {fbresult::Turn_None, + fbresult::Turn_Straight, + fbresult::Turn_SharpLeft, + fbresult::Turn_Left, + fbresult::Turn_SlightLeft, + fbresult::Turn_SlightRight, + fbresult::Turn_Right, + fbresult::Turn_SharpRight, + fbresult::Turn_UTurn, + fbresult::Turn_SlightLeft, + fbresult::Turn_SlightRight}; + std::vector result; + std::bitset<8 * sizeof(extractor::TurnLaneType::Mask)> mask(lane_type); + for (auto index : util::irange(0, extractor::TurnLaneType::NUM_TYPES)) + { + if (mask[index]) + { + result.push_back(mapping[index]); + } + } + return result; + + } + flatbuffers::Offset + MakeRoute(flatbuffers::FlatBufferBuilder &fb_result, + const std::vector &segment_end_coordinates, + const std::vector> &unpacked_path_segments, + const std::vector &source_traversed_in_reverse, + const std::vector &target_traversed_in_reverse) const + { + fbresult::RouteObjectBuilder routeObject(fb_result); + + auto legs_info = MakeLegs(segment_end_coordinates, unpacked_path_segments, source_traversed_in_reverse, target_traversed_in_reverse); + std::vector legs = legs_info.first; + std::vector leg_geometries = legs_info.second; + + //Fill basix route info + auto route = guidance::assembleRoute(legs); + auto weight_name_string = fb_result.CreateString(facade.GetWeightName()); + routeObject.add_weight_name(weight_name_string); + routeObject.add_distance(route.distance); + routeObject.add_duration(route.duration); + routeObject.add_weight(route.weight); + + //Fill geometry + auto overview = MakeOverview(leg_geometries); + if(overview) { + auto geometry = MakeGeometry(fb_result, overview->begin(), overview->end()); + routeObject.add_geometry(geometry); + } + + //Fill legs + std::vector> routeLegs; + routeLegs.reserve(legs.size()); + for (const auto idx : util::irange(0UL, legs.size())) { + auto leg = legs[idx]; + auto &leg_geometry = leg_geometries[idx]; + fbresult::LegBuilder legBuilder(fb_result); + legBuilder.add_distance(leg.distance); + legBuilder.add_duration(leg.duration); + legBuilder.add_weight(leg.weight); + if (!leg.summary.empty()) { + auto summary_string = fb_result.CreateString(leg.summary); + legBuilder.add_summary(summary_string); + } + + //Fill steps + if (!leg.steps.empty()) { + std::vector> legSteps; + legSteps.resize(leg.steps.size()); + std::transform(leg.steps.begin(), leg.steps.end(), legSteps.begin(), [this, &leg_geometry, &fb_result](const guidance::RouteStep& step) { + fbresult::StepBuilder stepBuilder(fb_result); + stepBuilder.add_duration(step.duration); + stepBuilder.add_distance(step.distance); + stepBuilder.add_weight(step.weight); + auto name_string = fb_result.CreateString(step.name); + stepBuilder.add_name(name_string); + if (!step.ref.empty()) { + auto ref_string = fb_result.CreateString(step.ref); + stepBuilder.add_ref(ref_string); + } + if (!step.pronunciation.empty()) { + auto pronunciation_string = fb_result.CreateString(step.pronunciation); + stepBuilder.add_pronunciation(pronunciation_string); + } + if (!step.destinations.empty()) { + auto destinations_string = fb_result.CreateString(step.destinations); + stepBuilder.add_destinations(destinations_string); + } + if (!step.exits.empty()) { + auto exists_string = fb_result.CreateString(step.exits); + stepBuilder.add_exits(exists_string); + } + if(!step.rotary_name.empty()) { + auto rotary_name_string = fb_result.CreateString(step.rotary_name); + stepBuilder.add_rotary_name(rotary_name_string); + if (!step.rotary_pronunciation.empty()) { + auto rotary_pronunciation_string = fb_result.CreateString(step.rotary_pronunciation); + stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string); + } + } + auto mode_string = fb_result.CreateString(extractor::travelModeToString(step.mode)); + stepBuilder.add_mode(mode_string); + stepBuilder.add_driving_side(step.is_left_hand_driving); + + //Geometry + auto geometry = MakeGeometry(fb_result, leg_geometry.locations.begin() + step.geometry_begin, leg_geometry.locations.begin() + step.geometry_end); + stepBuilder.add_geometry(geometry); + //Maneuver + fbresult::StepManeuverBuilder maneuver(fb_result); + fbresult::Position maneuverPosition{static_cast(util::toFloating(step.maneuver.location.lon)), + static_cast(util::toFloating(step.maneuver.location.lat))}; + maneuver.add_location(&maneuverPosition); + maneuver.add_bearing_before(step.maneuver.bearing_before); + maneuver.add_bearing_after(step.maneuver.bearing_after); + if (step.maneuver.waypoint_type == guidance::WaypointType::None) + maneuver.add_type(TurnTypeToFB(step.maneuver.instruction.type)); + else + maneuver.add_type(WaypointTypeToFB(step.maneuver.waypoint_type)); + if (osrm::engine::api::json::detail::isValidModifier(step.maneuver)) { + maneuver.add_modifier(TurnModifierToFB(step.maneuver.instruction.direction_modifier)); + } + if (step.maneuver.exit != 0) { + maneuver.add_exit(step.maneuver.exit); + } + + //intersections + std::vector> intersections; + intersections.resize(step.intersections.size()); + std::transform(step.intersections.begin(), step.intersections.end(), intersections.begin(), [&fb_result, this](const guidance::IntermediateIntersection& intersection) { + fbresult::IntersectionBuilder intersectionBuilder(fb_result); + fbresult::Position maneuverPosition{static_cast(util::toFloating(intersection.location.lon)), + static_cast(util::toFloating(intersection.location.lat))}; + intersectionBuilder.add_location(&maneuverPosition); + auto bearings_vector = fb_result.CreateVector(intersection.bearings); + intersectionBuilder.add_bearings(bearings_vector); + std::vector> classes; + classes.resize(intersection.classes.size()); + std::transform(intersection.classes.begin(), intersection.classes.end(), classes.begin(), [&fb_result](const std::string cls) { + return fb_result.CreateString(cls); + }); + auto classes_vector = fb_result.CreateVector(classes); + intersectionBuilder.add_classes(classes_vector); + auto entry_vector = fb_result.CreateVector(intersection.entry); + intersectionBuilder.add_entry(entry_vector); + intersectionBuilder.add_in(intersection.in); + intersectionBuilder.add_out(intersection.out); + if (api::json::detail::hasValidLanes(intersection)) { + BOOST_ASSERT(intersection.lanes.lanes_in_turn >= 1); + std::vector> lanes; + lanes.resize(intersection.lane_description.size()); + LaneID lane_id = intersection.lane_description.size(); + + for (const auto &lane_desc : intersection.lane_description) + { + --lane_id; + fbresult::LaneBuilder laneBuilder(fb_result); + auto indications_vector = fb_result.CreateVector(TurnLaneTypeToFB(lane_desc)); + laneBuilder.add_indications(indications_vector); + if (lane_id >= intersection.lanes.first_lane_from_the_right && + lane_id < + intersection.lanes.first_lane_from_the_right + intersection.lanes.lanes_in_turn) + laneBuilder.add_valid(true); + else + laneBuilder.add_valid(false); + + lanes.emplace_back(laneBuilder.Finish()); + } + auto lanes_vector = fb_result.CreateVector(lanes); + intersectionBuilder.add_lanes(lanes_vector); + } + + return intersectionBuilder.Finish(); + }); + auto intersections_vector = fb_result.CreateVector(intersections); + stepBuilder.add_intersections(intersections_vector); + return stepBuilder.Finish(); + }); + auto steps_vector = fb_result.CreateVector(legSteps); + legBuilder.add_steps(steps_vector); + } + + //Fill annotations + // To maintain support for uses of the old default constructors, we check + // if annotations property was set manually after default construction + auto requested_annotations = parameters.annotations_type; + if ((parameters.annotations == true) && + (parameters.annotations_type == RouteParameters::AnnotationsType::None)) + { + requested_annotations = RouteParameters::AnnotationsType::All; + } + + if (requested_annotations != RouteParameters::AnnotationsType::None) + { + fbresult::AnnotationBuilder annotation(fb_result); + + // AnnotationsType uses bit flags, & operator checks if a property is set + if (parameters.annotations_type & RouteParameters::AnnotationsType::Speed) + { + double prev_speed = 0; + auto speed = GetAnnotations( + fb_result, leg_geometry, [&prev_speed](const guidance::LegGeometry::Annotation &anno) { + if (anno.duration < std::numeric_limits::min()) + { + return prev_speed; + } + else + { + auto speed = std::round(anno.distance / anno.duration * 10.) / 10.; + prev_speed = speed; + return util::json::clamp_float(speed); + } + }); + annotation.add_speed(speed); + } + + if (requested_annotations & RouteParameters::AnnotationsType::Duration) + { + auto duration = GetAnnotations( + fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) { + return anno.duration; + }); + annotation.add_duration(duration); + } + if (requested_annotations & RouteParameters::AnnotationsType::Distance) + { + auto distance = GetAnnotations( + fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) { + return anno.distance; + }); + annotation.add_distance(distance); + } + if (requested_annotations & RouteParameters::AnnotationsType::Weight) + { + auto weight = GetAnnotations( + fb_result, leg_geometry, + [](const guidance::LegGeometry::Annotation &anno) { return anno.weight; }); + annotation.add_weight(weight); + } + if (requested_annotations & RouteParameters::AnnotationsType::Datasources) + { + auto datasources = GetAnnotations( + fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) { + return anno.datasource; + }); + annotation.add_datasources(datasources); + } + if (requested_annotations & RouteParameters::AnnotationsType::Nodes) + { + std::vector nodes; + nodes.reserve(leg_geometry.osm_node_ids.size()); + for (const auto node_id : leg_geometry.osm_node_ids) + { + nodes.emplace_back(static_cast(node_id)); + } + auto nodes_vector = fb_result.CreateVector(nodes); + annotation.add_nodes(nodes_vector); + } + // Add any supporting metadata, if needed + if (requested_annotations & RouteParameters::AnnotationsType::Datasources) + { + const auto MAX_DATASOURCE_ID = 255u; + fbresult::MetadataBuilder metadata(fb_result); + std::vector> names; + for (auto i = 0u; i < MAX_DATASOURCE_ID; i++) + { + const auto name = facade.GetDatasourceName(i); + // Length of 0 indicates the first empty name, so we can stop here + if (name.size() == 0) + break; + names.emplace_back(fb_result.CreateString(std::string(facade.GetDatasourceName(i)))); + } + auto datasource_names_vector = fb_result.CreateVector(names); + metadata.add_datasource_names(datasource_names_vector); + annotation.add_metadata(metadata.Finish()); + } + + legBuilder.add_annotations(annotation.Finish()); + } + + routeLegs.emplace_back(legBuilder.Finish()); + } + auto legs_vector = fb_result.CreateVector(routeLegs); + routeObject.add_legs(legs_vector); + + return routeObject.Finish(); + } + util::json::Object MakeRoute(const std::vector &segment_end_coordinates, const std::vector> &unpacked_path_segments, const std::vector &source_traversed_in_reverse, const std::vector &target_traversed_in_reverse) const { - std::vector legs; - std::vector leg_geometries; - auto number_of_legs = segment_end_coordinates.size(); - legs.reserve(number_of_legs); - leg_geometries.reserve(number_of_legs); - - for (auto idx : util::irange(0UL, number_of_legs)) - { - const auto &phantoms = segment_end_coordinates[idx]; - const auto &path_data = unpacked_path_segments[idx]; - - const bool reversed_source = source_traversed_in_reverse[idx]; - const bool reversed_target = target_traversed_in_reverse[idx]; - - auto leg_geometry = guidance::assembleGeometry(BaseAPI::facade, - path_data, - phantoms.source_phantom, - phantoms.target_phantom, - reversed_source, - reversed_target); - auto leg = guidance::assembleLeg(facade, - path_data, - leg_geometry, - phantoms.source_phantom, - phantoms.target_phantom, - reversed_target, - parameters.steps); - - util::Log(logDEBUG) << "Assembling steps " << std::endl; - if (parameters.steps) - { - auto steps = guidance::assembleSteps(BaseAPI::facade, - path_data, - leg_geometry, - phantoms.source_phantom, - phantoms.target_phantom, - reversed_source, - reversed_target); - - // Apply maneuver overrides before any other post - // processing is performed - guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry); - - // Collapse segregated steps before others - steps = guidance::collapseSegregatedTurnInstructions(std::move(steps)); - - /* Perform step-based post-processing. - * - * Using post-processing on basis of route-steps for a single leg at a time - * comes at the cost that we cannot count the correct exit for roundabouts. - * We can only emit the exit nr/intersections up to/starting at a part of the leg. - * If a roundabout is not terminated in a leg, we will end up with a - *enter-roundabout - * and exit-roundabout-nr where the exit nr is out of sync with the previous enter. - * - * | S | - * * * - * ----* * ---- - * T - * ----* * ---- - * V * * - * | | - * | | - * - * Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to - *take - * the second exit, even though counting from S it would be the third. - * For S, we only emit `roundabout` without an exit number, showing that we enter a - *roundabout - * to find a via point. - * The same exit will be emitted, though, if we should start routing at S, making - * the overall response consistent. - * - * ⚠ CAUTION: order of post-processing steps is important - * - handleRoundabouts must be called before collapseTurnInstructions that - * expects post-processed roundabouts - */ - - guidance::trimShortSegments(steps, leg_geometry); - leg.steps = guidance::handleRoundabouts(std::move(steps)); - leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps)); - leg.steps = guidance::anticipateLaneChange(std::move(leg.steps)); - leg.steps = guidance::buildIntersections(std::move(leg.steps)); - leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps)); - leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), - leg_geometry, - phantoms.source_phantom, - phantoms.target_phantom); - leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps); - } - - leg_geometries.push_back(std::move(leg_geometry)); - legs.push_back(std::move(leg)); - } + auto legs_info = MakeLegs(segment_end_coordinates, unpacked_path_segments, source_traversed_in_reverse, target_traversed_in_reverse); + std::vector legs = legs_info.first; + std::vector leg_geometries = legs_info.second; auto route = guidance::assembleRoute(legs); - boost::optional json_overview; - if (parameters.overview != RouteParameters::OverviewType::False) - { - const auto use_simplification = - parameters.overview == RouteParameters::OverviewType::Simplified; - BOOST_ASSERT(use_simplification || - parameters.overview == RouteParameters::OverviewType::Full); - - auto overview = guidance::assembleOverview(leg_geometries, use_simplification); - json_overview = MakeGeometry(overview.begin(), overview.end()); - } + boost::optional json_overview = MakeGeometry(MakeOverview(leg_geometries)); std::vector step_geometries; const auto total_step_count = @@ -364,6 +701,123 @@ class RouteAPI : public BaseAPI } const RouteParameters ¶meters; + + std::pair, std::vector> + MakeLegs(const std::vector &segment_end_coordinates, + const std::vector> &unpacked_path_segments, + const std::vector &source_traversed_in_reverse, + const std::vector &target_traversed_in_reverse) const { + auto result = std::make_pair(std::vector(), std::vector()); + auto& legs = result.first; + auto& leg_geometries = result.second; + auto number_of_legs = segment_end_coordinates.size(); + legs.reserve(number_of_legs); + leg_geometries.reserve(number_of_legs); + + for (auto idx : util::irange(0UL, number_of_legs)) + { + const auto &phantoms = segment_end_coordinates[idx]; + const auto &path_data = unpacked_path_segments[idx]; + + const bool reversed_source = source_traversed_in_reverse[idx]; + const bool reversed_target = target_traversed_in_reverse[idx]; + + auto leg_geometry = guidance::assembleGeometry(BaseAPI::facade, + path_data, + phantoms.source_phantom, + phantoms.target_phantom, + reversed_source, + reversed_target); + auto leg = guidance::assembleLeg(facade, + path_data, + leg_geometry, + phantoms.source_phantom, + phantoms.target_phantom, + reversed_target, + parameters.steps); + + util::Log(logDEBUG) << "Assembling steps " << std::endl; + if (parameters.steps) + { + auto steps = guidance::assembleSteps(BaseAPI::facade, + path_data, + leg_geometry, + phantoms.source_phantom, + phantoms.target_phantom, + reversed_source, + reversed_target); + + // Apply maneuver overrides before any other post + // processing is performed + guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry); + + // Collapse segregated steps before others + steps = guidance::collapseSegregatedTurnInstructions(std::move(steps)); + + /* Perform step-based post-processing. + * + * Using post-processing on basis of route-steps for a single leg at a time + * comes at the cost that we cannot count the correct exit for roundabouts. + * We can only emit the exit nr/intersections up to/starting at a part of the leg. + * If a roundabout is not terminated in a leg, we will end up with a + *enter-roundabout + * and exit-roundabout-nr where the exit nr is out of sync with the previous enter. + * + * | S | + * * * + * ----* * ---- + * T + * ----* * ---- + * V * * + * | | + * | | + * + * Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to + *take + * the second exit, even though counting from S it would be the third. + * For S, we only emit `roundabout` without an exit number, showing that we enter a + *roundabout + * to find a via point. + * The same exit will be emitted, though, if we should start routing at S, making + * the overall response consistent. + * + * ⚠ CAUTION: order of post-processing steps is important + * - handleRoundabouts must be called before collapseTurnInstructions that + * expects post-processed roundabouts + */ + + guidance::trimShortSegments(steps, leg_geometry); + leg.steps = guidance::handleRoundabouts(std::move(steps)); + leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps)); + leg.steps = guidance::anticipateLaneChange(std::move(leg.steps)); + leg.steps = guidance::buildIntersections(std::move(leg.steps)); + leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps)); + leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), + leg_geometry, + phantoms.source_phantom, + phantoms.target_phantom); + leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps); + } + + leg_geometries.push_back(std::move(leg_geometry)); + legs.push_back(std::move(leg)); + } + return result; + } + + boost::optional> MakeOverview(const std::vector& leg_geometries) const { + boost::optional> overview; + if (parameters.overview != RouteParameters::OverviewType::False) + { + const auto use_simplification = + parameters.overview == RouteParameters::OverviewType::Simplified; + BOOST_ASSERT(use_simplification || + parameters.overview == RouteParameters::OverviewType::Full); + + overview = guidance::assembleOverview(leg_geometries, use_simplification); + } + return overview; + } }; } // ns api diff --git a/src/engine/api/json_factory.cpp b/src/engine/api/json_factory.cpp index dc887f853..8df45c94c 100644 --- a/src/engine/api/json_factory.cpp +++ b/src/engine/api/json_factory.cpp @@ -20,7 +20,6 @@ #include namespace TurnType = osrm::guidance::TurnType; -namespace DirectionModifier = osrm::guidance::DirectionModifier; using TurnInstruction = osrm::guidance::TurnInstruction; namespace osrm @@ -34,18 +33,6 @@ namespace json namespace detail { -// Check whether to include a modifier in the result of the API -inline bool isValidModifier(const guidance::StepManeuver maneuver) -{ - return (maneuver.waypoint_type == guidance::WaypointType::None || - maneuver.instruction.direction_modifier != DirectionModifier::UTurn); -} - -inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection) -{ - return intersection.lanes.lanes_in_turn > 0; -} - inline util::json::Array toJSON(const extractor::TurnLaneType::Mask lane_type) { util::json::Array result; diff --git a/src/engine/plugins/viaroute.cpp b/src/engine/plugins/viaroute.cpp index 807a33174..379ac6d46 100644 --- a/src/engine/plugins/viaroute.cpp +++ b/src/engine/plugins/viaroute.cpp @@ -32,8 +32,6 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm { BOOST_ASSERT(route_parameters.IsValid()); - auto& json_result = result.get(); - if (!algorithms.HasShortestPathSearch() && route_parameters.coordinates.size() > 2) { return Error("NotImplemented", @@ -164,7 +162,7 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm } } - route_api.MakeResponse(routes, start_end_nodes, json_result); + route_api.MakeResponse(routes, start_end_nodes, result); } else { diff --git a/src/server/service/route_service.cpp b/src/server/service/route_service.cpp index ae6a69126..a56164ffe 100644 --- a/src/server/service/route_service.cpp +++ b/src/server/service/route_service.cpp @@ -66,6 +66,12 @@ RouteService::RunQuery(std::size_t prefix_length, std::string &query, osrm::engi } BOOST_ASSERT(parameters->IsValid()); + if (parameters->format) + { + if (parameters->format == engine::api::BaseParameters::OutputFormatType::FLATBUFFERS) { + result = flatbuffers::FlatBufferBuilder(); + } + } return BaseService::routing_machine.Route(*parameters, result); } }