diff --git a/routing/index_router.cpp b/routing/index_router.cpp index bb538216f..857a991b3 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -577,7 +577,7 @@ RouterResultCode IndexRouter::DoCalculateRoute(Checkpoints const & checkpoints, } } - if (!route.GetAbsentCountries().empty()) + if ((GetMode() == Mode::Navigation) && !route.GetAbsentCountries().empty()) return RouterResultCode::NeedMoreMaps; TrafficStash::Guard guard(m_trafficStash); @@ -1406,7 +1406,7 @@ bool IndexRouter::PointsOnEdgesSnapping::FindBestEdges( } // Removing all candidates which are fenced off by the road graph (|closestRoads|) from |checkpoint|. - return !m_router.IsFakeEndingSetSimplified() || !IsFencedOff(checkpoint, edgeProj, closestRoads); + return (m_router.GetMode() == Mode::Decoding) || !IsFencedOff(checkpoint, edgeProj, closestRoads); }; // Getting closest edges from |closestRoads| if they are correct according to isGood() function. diff --git a/routing/index_router.hpp b/routing/index_router.hpp index 9e6845b3e..ff561c3c5 100644 --- a/routing/index_router.hpp +++ b/routing/index_router.hpp @@ -41,6 +41,24 @@ class IndexGraphStarter; class IndexRouter : public IRouter { public: + /** + * @brief Indicates the mode in which the router is operating. + * + * The mode controls some aspects of router behavior, such as asking for additional maps or how + * checkpoints are matched to nearby segments. + */ + enum Mode + { + /** + * Router mode for navigation, i.e. user-initiated route guidance. + */ + Navigation, + /** + * Router mode for location decoding. + */ + Decoding + }; + class BestEdgeComparator final { public: @@ -138,21 +156,22 @@ protected: /** - * @brief Whether the set of fake endings generated for the check points is restricted. + * @brief Returns the mode in which the router is operating. * - * The return value is used internally when snapping checkpoints to edges. If this function - * returns true, this instructs the `PointsOnEdgesSnapping` instance to consider only edges which - * are not fenced off, i.e. can be reached from the respective checkpoint without crossing any - * other edges. If it returns false, this restriction does not apply, and all nearby edges are - * considered. - * - * Restricting the set of fake endings in this manner decreases the options considered for routing - * and thus processing time, which is desirable for regular routing and has no side effects. - * - * The `IndexRouter` implementation always returns true; subclasses may override this method and + * The `IndexRouter` always returns `Mode::Navigation`; subclasses may override this method and * return different values. + * + * In navigation mode, the router may exit with `RouterResultCode::NeedMoreMaps` if it determines + * that a better route can be calculated with additional maps. When snapping endpoints to edges, + * it will consider only edges which are not “fenced off” by other edges, i.e. which can be + * reached from the endpoint without crossing other edges. This decreases the number of fake + * endings and thus speeds up routing, without any undesirable side effects for that use case. + * + * In decoding mode, the router will never exit with `RouterResultCode::NeedMoreMaps`: it will try + * to find a route with the existing maps, or exit without finding a route. When snapping + * endpoints to edges, it considers all edges within the given radius, fenced off or not. */ - virtual bool IsFakeEndingSetSimplified() { return true; } + virtual Mode GetMode() { return Mode::Navigation; } private: RouterResultCode CalculateSubrouteJointsMode(IndexGraphStarter & starter, diff --git a/traffxml/traff_decoder.hpp b/traffxml/traff_decoder.hpp index 30189c43d..4207932bc 100644 --- a/traffxml/traff_decoder.hpp +++ b/traffxml/traff_decoder.hpp @@ -221,7 +221,39 @@ public: * * To avoid this, the `DecoderRouter` implementation always returns false. */ - bool IsFakeEndingSetSimplified() override { return false; } + /** + * @brief Returns the mode in which the router is operating. + * + * The `DecoderRouter` always returns `Mode::Decoding`. + * + * In navigation mode, the router may exit with `RouterResultCode::NeedMoreMaps` if it determines + * that a better route can be calculated with additional maps. When snapping endpoints to edges, + * it will consider only edges which are not “fenced off” by other edges, i.e. which can be + * reached from the endpoint without crossing other edges. This decreases the number of fake + * endings and thus speeds up routing, without any undesirable side effects for that use case. + * + * Asking the user to download extra maps is neither practical for a TraFF decoder which runs in + * the background and may decode many locations, one by one, nor is it needed (if maps are + * missing, we do not need to decode traffic reports for them). + * + * Eliminating fenced-off edges from the snapping candidates has an undesirable side effect for + * TraFF location decoding on dual-carriageway roads: if the reference points are outside the + * carriageways, only one direction gets considered for snapping, as the opposite direction is + * fenced off by it. This may lead to situations like these: + * + * ~~~ + * --<--<-+<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<+-<--<-- + * -->-->-+>==>==>==>==>==>==>-->-->-->-->-->-->-->-->-->-->-->==>==>==>==>==>==>==>==>+->-->-- + * |< <| + * + * (-- carriageway, + junction, < > direction, |< end point, <| start point, == route) + * ~~~ + * + * Therefore, in decoding mode, the router will never exit with `RouterResultCode::NeedMoreMaps` + * but tries to find a route with the existing maps, or exits without a route. When snapping + * endpoints to edges, it considers all edges within the given radius, fenced off or not. + */ + IndexRouter::Mode GetMode() { return IndexRouter::Mode::Decoding; } private: };