diff --git a/map/framework.cpp b/map/framework.cpp index 9fcc720e9c..0eae3f8a07 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -356,7 +356,12 @@ Framework::Framework() , m_isRenderingEnabled(true) , m_trackingReporter(platform::CreateSocket(), TRACKING_REALTIME_HOST, TRACKING_REALTIME_PORT, tracking::Reporter::kPushDelayMs) - , m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1), kMaxTrafficCacheSizeBytes) + , m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1), + // Note. |m_routingSession| should be declared before |m_trafficManager|. + {bind(&RoutingSession::AddTrafficInfo, &m_routingSession, _1), + bind(&RoutingSession::RemoveTrafficInfo, &m_routingSession, _1), + bind(&RoutingSession::EnableTraffic, &m_routingSession, _1)}, + kMaxTrafficCacheSizeBytes) , m_displacementModeManager([this](bool show) { int const mode = show ? dp::displacement::kHotelMode : dp::displacement::kDefaultMode; CallDrapeFunction(bind(&df::DrapeEngine::SetDisplacementMode, _1, mode)); @@ -2493,7 +2498,9 @@ void Framework::SetRouterImpl(RouterType type) router.reset( new CarRouter(m_model.GetIndex(), countryFileGetter, - SingleMwmRouter::CreateCarRouter(m_model.GetIndex()))); + SingleMwmRouter::CreateCarRouter(m_model.GetIndex(), + bind(&RoutingSession::GetTrafficColoring, + &m_routingSession, _1)))); fetcher.reset(new OnlineAbsentCountriesFetcher(countryFileGetter, localFileChecker)); m_routingSession.SetRoutingSettings(routing::GetCarRoutingSettings()); } diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index be2c9b4e3e..d24bcdb9e7 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -37,8 +37,11 @@ TrafficManager::CacheEntry::CacheEntry(time_point const & requestT , m_lastAvailability(traffic::TrafficInfo::Availability::Unknown) {} -TrafficManager::TrafficManager(GetMwmsByRectFn const & getMwmsByRectFn, size_t maxCacheSizeBytes) +TrafficManager::TrafficManager(GetMwmsByRectFn const & getMwmsByRectFn, + RoutingFns const & routingFns, + size_t maxCacheSizeBytes) : m_getMwmsByRectFn(getMwmsByRectFn) + , m_routingFns(routingFns) , m_currentDataVersion(0) , m_state(TrafficState::Disabled) , m_maxCacheSizeBytes(maxCacheSizeBytes) @@ -92,6 +95,8 @@ void TrafficManager::SetEnabled(bool enabled) if (m_currentPosition.second) UpdateMyPosition(m_currentPosition.first); } + + m_routingFns.m_enableTrafficFn(enabled); } void TrafficManager::Clear() @@ -320,12 +325,15 @@ void TrafficManager::OnTrafficDataResponse(traffic::TrafficInfo const & info) it->second.m_dataSize = dataSize; CheckCacheSize(); - // Update traffic colors. + // Update traffic colors for drape. df::TrafficSegmentsColoring coloring; coloring[info.GetMwmId()] = info.GetColoring(); m_drapeEngine->UpdateTraffic(coloring); UpdateState(); + + // Update traffic colors for routing. + m_routingFns.m_addTrafficInfoFn(info); } void TrafficManager::CheckCacheSize() @@ -346,6 +354,7 @@ void TrafficManager::CheckCacheSize() { m_currentCacheSizeBytes -= it->second.m_dataSize; m_drapeEngine->ClearTrafficCache(mwmId); + m_routingFns.m_removeTrafficInfoFn(mwmId); } m_mwmCache.erase(it); ++itSeen; diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index b14cac579a..c128b291a2 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -56,8 +56,19 @@ public: using TrafficStateChangedFn = function; using GetMwmsByRectFn = function(m2::RectD const &)>; + using AddTrafficInfoToRoutingFn = function; + using RemoveTrafficInfoFromRoutingFn = function; + using EnableTrafficInRoutingFn = function; - TrafficManager(GetMwmsByRectFn const & getMwmsByRectFn, size_t maxCacheSizeBytes); + struct RoutingFns + { + AddTrafficInfoToRoutingFn m_addTrafficInfoFn; + RemoveTrafficInfoFromRoutingFn m_removeTrafficInfoFn; + EnableTrafficInRoutingFn m_enableTrafficFn; + }; + + TrafficManager(GetMwmsByRectFn const & getMwmsByRectFn, RoutingFns const & routingFns, + size_t maxCacheSizeBytes); ~TrafficManager(); void SetStateListener(TrafficStateChangedFn const & onStateChangedFn); @@ -94,6 +105,7 @@ private: bool IsEnabled() const; GetMwmsByRectFn m_getMwmsByRectFn; + RoutingFns m_routingFns; ref_ptr m_drapeEngine; atomic m_currentDataVersion; diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index 52cb10905a..458085bf62 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -4,6 +4,8 @@ namespace routing { +using namespace traffic; + double constexpr kKMPH2MPS = 1000.0 / (60 * 60); inline double TimeBetweenSec(m2::PointD const & from, m2::PointD const & to, double speedMPS) @@ -20,7 +22,7 @@ public: CarEdgeEstimator(IVehicleModel const & vehicleModel); // EdgeEstimator overrides: - double CalcEdgesWeight(RoadGeometry const & road, uint32_t pointFrom, + double CalcEdgesWeight(RoadGeometry const & road, uint32_t featureId, uint32_t pointFrom, uint32_t pointTo) const override; double CalcHeuristic(m2::PointD const & from, m2::PointD const & to) const override; @@ -33,8 +35,8 @@ CarEdgeEstimator::CarEdgeEstimator(IVehicleModel const & vehicleModel) { } -double CarEdgeEstimator::CalcEdgesWeight(RoadGeometry const & road, uint32_t pointFrom, - uint32_t pointTo) const +double CarEdgeEstimator::CalcEdgesWeight(RoadGeometry const & road, uint32_t featureId, + uint32_t pointFrom, uint32_t pointTo) const { uint32_t const start = min(pointFrom, pointTo); uint32_t const finish = max(pointFrom, pointTo); @@ -42,8 +44,23 @@ double CarEdgeEstimator::CalcEdgesWeight(RoadGeometry const & road, uint32_t poi double result = 0.0; double const speedMPS = road.GetSpeed() * kKMPH2MPS; + uint8_t const dir = start < finish ? TrafficInfo::RoadSegmentId::kForwardDirection + : TrafficInfo::RoadSegmentId::kReverseDirection; for (uint32_t i = start; i < finish; ++i) - result += TimeBetweenSec(road.GetPoint(i), road.GetPoint(i + 1), speedMPS); + { + double factor = 1.0; + if (m_trafficColoring) + { + auto const it = m_trafficColoring->find(TrafficInfo::RoadSegmentId(featureId, i, dir)); + if (it != m_trafficColoring->cend()) + { + SpeedGroup speedGroup = it->second; + CHECK_LESS(speedGroup, SpeedGroup::Count, ()); + factor /= static_cast(kSpeedGroupThresholdPercentage[static_cast(speedGroup)]) / 100.0; + } + } + result += factor * TimeBetweenSec(road.GetPoint(i), road.GetPoint(i + 1), speedMPS); + } return result; } @@ -61,4 +78,9 @@ shared_ptr EdgeEstimator::CreateForCar(IVehicleModel const & vehi { return make_shared(vehicleModel); } + +void EdgeEstimator::SetTrafficColoring(shared_ptr coloring) +{ + m_trafficColoring = coloring; +} } // namespace routing diff --git a/routing/edge_estimator.hpp b/routing/edge_estimator.hpp index 0a6ec2d1e0..ed74c8bffa 100644 --- a/routing/edge_estimator.hpp +++ b/routing/edge_estimator.hpp @@ -3,6 +3,8 @@ #include "routing/geometry.hpp" #include "routing/vehicle_model.hpp" +#include "traffic/traffic_info.hpp" + #include "geometry/point2d.hpp" #include "std/cstdint.hpp" @@ -15,10 +17,15 @@ class EdgeEstimator public: virtual ~EdgeEstimator() = default; - virtual double CalcEdgesWeight(RoadGeometry const & road, uint32_t pointFrom, - uint32_t pointTo) const = 0; + virtual double CalcEdgesWeight(RoadGeometry const & road, uint32_t featureId, + uint32_t pointFrom, uint32_t pointTo) const = 0; virtual double CalcHeuristic(m2::PointD const & from, m2::PointD const & to) const = 0; + void SetTrafficColoring(shared_ptr coloring); + static shared_ptr CreateForCar(IVehicleModel const & vehicleModel); + +protected: + shared_ptr m_trafficColoring; }; } // namespace routing diff --git a/routing/index_graph.cpp b/routing/index_graph.cpp index 39e8cd30ce..6fe0fb7fe4 100644 --- a/routing/index_graph.cpp +++ b/routing/index_graph.cpp @@ -72,7 +72,8 @@ void IndexGraph::GetNeighboringEdge(RoadGeometry const & road, RoadPoint const & pair const & neighbor = m_roadIndex.FindNeighbor(rp, forward); if (neighbor.first != Joint::kInvalidId) { - double const distance = m_estimator->CalcEdgesWeight(road, rp.GetPointId(), neighbor.second); + double const distance = m_estimator->CalcEdgesWeight(road, rp.GetFeatureId(), + rp.GetPointId(), neighbor.second); edges.push_back({neighbor.first, distance}); } } @@ -87,7 +88,7 @@ void IndexGraph::GetDirectedEdge(uint32_t featureId, uint32_t pointFrom, uint32_ if (road.IsOneWay() && forward != (pointFrom < pointTo)) return; - double const distance = m_estimator->CalcEdgesWeight(road, pointFrom, pointTo); + double const distance = m_estimator->CalcEdgesWeight(road, featureId, pointFrom, pointTo); edges.emplace_back(target, distance); } } // namespace routing diff --git a/routing/index_graph_starter.cpp b/routing/index_graph_starter.cpp index 5ae00512d6..f380ea2028 100644 --- a/routing/index_graph_starter.cpp +++ b/routing/index_graph_starter.cpp @@ -154,12 +154,12 @@ void IndexGraphStarter::FindPointsWithCommonFeature(Joint::Id jointId0, Joint::I // CalcEdgesWeight is very expensive. // So calculate it only if second common feature found. RoadGeometry const & prevRoad = m_graph.GetGeometry().GetRoad(result0.GetFeatureId()); - minWeight = m_graph.GetEstimator().CalcEdgesWeight(prevRoad, result0.GetPointId(), - result1.GetPointId()); + minWeight = m_graph.GetEstimator().CalcEdgesWeight(prevRoad, rp0.GetFeatureId(), + result0.GetPointId(), result1.GetPointId()); } - double const weight = - m_graph.GetEstimator().CalcEdgesWeight(road, rp0.GetPointId(), rp1.GetPointId()); + double const weight = m_graph.GetEstimator().CalcEdgesWeight(road, rp0.GetFeatureId(), + rp0.GetPointId(), rp1.GetPointId()); if (weight < minWeight) { minWeight = weight; diff --git a/routing/routing_integration_tests/routing_test_tools.cpp b/routing/routing_integration_tests/routing_test_tools.cpp index a982361670..36d79aad3d 100644 --- a/routing/routing_integration_tests/routing_test_tools.cpp +++ b/routing/routing_integration_tests/routing_test_tools.cpp @@ -83,7 +83,7 @@ namespace integration }; auto carRouter = make_unique( - index, countryFileGetter, SingleMwmRouter::CreateCarRouter(index)); + index, countryFileGetter, SingleMwmRouter::CreateCarRouter(index, nullptr)); return carRouter; } diff --git a/routing/routing_session.cpp b/routing/routing_session.cpp index cca937ec48..b365d12e36 100644 --- a/routing/routing_session.cpp +++ b/routing/routing_session.cpp @@ -10,9 +10,12 @@ #include "coding/internal/file_data.hpp" +#include "std/utility.hpp" + #include "3party/Alohalytics/src/alohalytics.h" using namespace location; +using namespace traffic; namespace { @@ -577,6 +580,42 @@ shared_ptr const RoutingSession::GetRoute() const return m_route; } +void RoutingSession::EnableTraffic(bool enable) +{ + threads::MutexGuard guard(m_routeSessionMutex); + UNUSED_VALUE(guard); + m_trafficInfo.clear(); +} + +void RoutingSession::AddTrafficInfo(TrafficInfo const & info) +{ + threads::MutexGuard guard(m_routeSessionMutex); + UNUSED_VALUE(guard); + // @TODO(bykoianko) It's worth considering moving a big |info.GetColoring()| + // not copying as it's done now. + m_trafficInfo.insert(make_pair(info.GetMwmId(), + make_shared(info.GetColoring()))); +} + +shared_ptr RoutingSession::GetTrafficColoring( + MwmSet::MwmId const & mwmId) +{ + threads::MutexGuard guard(m_routeSessionMutex); + UNUSED_VALUE(guard); + auto it = m_trafficInfo.find(mwmId); + + if (it == m_trafficInfo.cend()) + return nullptr; + return it->second; +} + +void RoutingSession::RemoveTrafficInfo(MwmSet::MwmId const & mwmId) +{ + threads::MutexGuard guard(m_routeSessionMutex); + UNUSED_VALUE(guard); + m_trafficInfo.erase(mwmId); +} + string DebugPrint(RoutingSession::State state) { switch (state) diff --git a/routing/routing_session.hpp b/routing/routing_session.hpp index b4fa257416..3063973e3f 100644 --- a/routing/routing_session.hpp +++ b/routing/routing_session.hpp @@ -6,6 +6,8 @@ #include "routing/turns.hpp" #include "routing/turns_notification_manager.hpp" +#include "traffic/traffic_info.hpp" + #include "platform/location.hpp" #include "platform/measurement_utils.hpp" @@ -16,6 +18,7 @@ #include "std/atomic.hpp" #include "std/limits.hpp" +#include "std/map.hpp" #include "std/shared_ptr.hpp" #include "std/unique_ptr.hpp" @@ -150,6 +153,11 @@ public: void EmitCloseRoutingEvent() const; + void EnableTraffic(bool enable); + void AddTrafficInfo(traffic::TrafficInfo const & info); + shared_ptr GetTrafficColoring(MwmSet::MwmId const & mwmId); + void RemoveTrafficInfo(MwmSet::MwmId const & mwmId); + private: struct DoReadyCallback { @@ -214,6 +222,8 @@ private: // Rerouting count int m_routingRebuildCount; mutable double m_lastCompletionPercent; + + map> m_trafficInfo; }; string DebugPrint(RoutingSession::State state); diff --git a/routing/routing_tests/applying_traffic_test.cpp b/routing/routing_tests/applying_traffic_test.cpp new file mode 100644 index 0000000000..724526ce49 --- /dev/null +++ b/routing/routing_tests/applying_traffic_test.cpp @@ -0,0 +1,198 @@ +#include "testing/testing.hpp" + +#include "routing/car_model.hpp" +#include "routing/geometry.hpp" +#include "routing/index_graph.hpp" +#include "routing/index_graph_starter.hpp" + +#include "traffic/traffic_info.hpp" + +#include "geometry/point2d.hpp" + +#include "routing/base/astar_algorithm.hpp" + +#include "std/shared_ptr.hpp" +#include "std/unique_ptr.hpp" +#include "std/vector.hpp" + +namespace +{ +using namespace routing; +using namespace traffic; + +// @TODO(bykoianko) When PR with applying restricions is merged all the helper method +// should be used from "routing/routing_tests/index_graph_tools.hpp". +class TestGeometryLoader final : public routing::GeometryLoader +{ +public: + // GeometryLoader overrides: + void Load(uint32_t featureId, routing::RoadGeometry & road) const override; + + void AddRoad(uint32_t featureId, bool oneWay, float speed, + routing::RoadGeometry::Points const & points); + +private: + unordered_map m_roads; +}; + +void TestGeometryLoader::Load(uint32_t featureId, RoadGeometry & road) const +{ + auto it = m_roads.find(featureId); + if (it == m_roads.cend()) + return; + + road = it->second; +} + +void TestGeometryLoader::AddRoad(uint32_t featureId, bool oneWay, float speed, + RoadGeometry::Points const & points) +{ + auto it = m_roads.find(featureId); + CHECK(it == m_roads.end(), ("Already contains feature", featureId)); + m_roads[featureId] = RoadGeometry(oneWay, speed, points); +} + +Joint MakeJoint(vector const & points) +{ + Joint joint; + for (auto const & point : points) + joint.AddPoint(point); + + return joint; +} + +AStarAlgorithm::Result CalculateRoute(IndexGraphStarter & starter, + vector & roadPoints) +{ + AStarAlgorithm algorithm; + RoutingResult routingResult; + auto const resultCode = algorithm.FindPath( + starter, starter.GetStartJoint(), starter.GetFinishJoint(), routingResult, {}, {}); + + starter.RedressRoute(routingResult.path, roadPoints); + return resultCode; +} + +void TestRouteGeometry(IndexGraphStarter & starter, + AStarAlgorithm::Result expectedRouteResult, + vector const & expectedRouteGeom) +{ + vector route; + auto const resultCode = CalculateRoute(starter, route); + TEST_EQUAL(resultCode, expectedRouteResult, ()); + TEST_EQUAL(route.size(), expectedRouteGeom.size(), ()); + for (size_t i = 0; i < route.size(); ++i) + { + RoadGeometry roadGeom = starter.GetGraph().GetGeometry().GetRoad(route[i].GetFeatureId()); + CHECK_LESS(route[i].GetPointId(), roadGeom.GetPointsCount(), ()); + TEST_EQUAL(expectedRouteGeom[i], roadGeom.GetPoint(route[i].GetPointId()), ()); + } +} + +// @TODO(bykoianko) When PR with applying restricions is merged BuildXXGraph() +// should be moved to "routing/routing_tests/index_graph_tools.hpp" and it should +// be used by applying_traffic_test.cpp and cumulative_restriction_test.cpp. + +// Finish +// 3 * * +// ↖ ↗ +// F5 F6 +// ↖ ↗ +// 2 * * +// ↖ ↗ ↖ +// F2 F3 F4 +// ↖ ↗ ↖ +// 1 * * +// ↗ ↖ ^ +// F0 F1 F8 +// ↗ ↖ | +// 0 * *--F7--->* +// 0 1 2 3 +// Start +// Note. This graph contains of 9 one segment directed features. +unique_ptr BuildXXGraph(shared_ptr estimator) +{ + unique_ptr loader = make_unique(); + loader->AddRoad(0 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{0.0, 0.0}, {1.0, 1.0}})); + loader->AddRoad(1 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{2.0, 0.0}, {1.0, 1.0}})); + loader->AddRoad(2 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{1.0, 1.0}, {0.0, 2.0}})); + loader->AddRoad(3 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{1.0, 1.0}, {2.0, 2.0}})); + loader->AddRoad(4 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{3.0, 1.0}, {2.0, 2.0}})); + loader->AddRoad(5 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{2.0, 2.0}, {1.0, 3.0}})); + loader->AddRoad(6 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{2.0, 2.0}, {3.0, 3.0}})); + loader->AddRoad(7 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{2.0, 0.0}, {3.0, 0.0}})); + loader->AddRoad(8 /* featureId */, true /* oneWay */, 1.0 /* speed */, + RoadGeometry::Points({{3.0, 0.0}, {3.0, 1.0}})); + + vector const joints = { + MakeJoint({{0 /* feature id */, 0 /* point id */}}), /* joint at point (0, 0) */ + MakeJoint({{1, 0}, {7, 0}}), /* joint at point (2, 0) */ + MakeJoint({{0, 1}, {1, 1}, {2, 0}, {3, 0}}), /* joint at point (1, 1) */ + MakeJoint({{2, 1}}), /* joint at point (0, 2) */ + MakeJoint({{3, 1}, {4, 1}, {5, 0}, {6, 0}}), /* joint at point (2, 2) */ + MakeJoint({{4, 0}, {8, 1}}), /* joint at point (3, 1) */ + MakeJoint({{5, 1}}), /* joint at point (1, 3) */ + MakeJoint({{6, 1}}), /* joint at point (3, 3) */ + MakeJoint({{7, 1}, {8, 0}}), /* joint at point (3, 0) */ + }; + + unique_ptr graph = make_unique(move(loader), estimator); + graph->Import(joints); + return graph; +} + +// Route through XX graph without any traffic info. +UNIT_TEST(XXGraph_EmptyTrafficColoring) +{ + shared_ptr estimator = + EdgeEstimator::CreateForCar(*make_shared()->GetVehicleModel()); + + unique_ptr graph = BuildXXGraph(estimator); + IndexGraphStarter starter(*graph, RoadPoint(1, 0) /* start */, RoadPoint(6, 1) /* finish */); + vector const expectedGeom = {{2 /* x */, 0 /* y */}, {1, 1}, {2, 2}, {3, 3}}; + TestRouteGeometry(starter, AStarAlgorithm::Result::OK, expectedGeom); +} + +// Route through XX graph with SpeedGroup::G0 on F3. +UNIT_TEST(XXGraph_G0onF3) +{ + shared_ptr estimator = + EdgeEstimator::CreateForCar(*make_shared()->GetVehicleModel()); + shared_ptr coloring = + make_shared(TrafficInfo::Coloring( + {{{3 /* feature id */, 0 /* segment id */, TrafficInfo::RoadSegmentId::kForwardDirection}, SpeedGroup::G0}})); + estimator->SetTrafficColoring(coloring); + + unique_ptr graph = BuildXXGraph(estimator); + IndexGraphStarter starter(*graph, RoadPoint(1, 0) /* start */, RoadPoint(6, 1) /* finish */); + vector const expectedGeom = {{2 /* x */, 0 /* y */}, {3, 0}, {3, 1}, {2, 2}, {3, 3}}; + TestRouteGeometry(starter, AStarAlgorithm::Result::OK, expectedGeom); +} + +// Route through XX graph SpeedGroup::G1 on F3 and F6, SpeedGroup::G4 on F8 and F4. +UNIT_TEST(XXGraph_G0onF3andF6andG4onF8andF4) +{ + shared_ptr estimator = + EdgeEstimator::CreateForCar(*make_shared()->GetVehicleModel()); + shared_ptr coloring = + make_shared(TrafficInfo::Coloring( + {{{3 /* feature id */, 0 /* segment id */, TrafficInfo::RoadSegmentId::kForwardDirection}, SpeedGroup::G0}, + {{6 /* feature id */, 0 /* segment id */, TrafficInfo::RoadSegmentId::kForwardDirection}, SpeedGroup::G0}, + {{8 /* feature id */, 0 /* segment id */, TrafficInfo::RoadSegmentId::kForwardDirection}, SpeedGroup::G4}, + {{7 /* feature id */, 0 /* segment id */, TrafficInfo::RoadSegmentId::kForwardDirection}, SpeedGroup::G4}})); + estimator->SetTrafficColoring(coloring); + + unique_ptr graph = BuildXXGraph(estimator); + IndexGraphStarter starter(*graph, RoadPoint(1, 0) /* start */, RoadPoint(6, 1) /* finish */); + vector const expectedGeom = {{2 /* x */, 0 /* y */}, {3, 0}, {3, 1}, {2, 2}, {3, 3}}; + TestRouteGeometry(starter, AStarAlgorithm::Result::OK, expectedGeom); +} +} // namespace diff --git a/routing/single_mwm_router.cpp b/routing/single_mwm_router.cpp index 95461b857f..b04d3f3a4a 100644 --- a/routing/single_mwm_router.cpp +++ b/routing/single_mwm_router.cpp @@ -49,11 +49,13 @@ vector ConvertToJunctions(IndexGraphStarter & starter, vector vehicleModelFactory, shared_ptr estimator, unique_ptr directionsEngine) : m_name(name) , m_index(index) + , m_getTrafficColoringFn(getTrafficColoringFn) , m_roadGraph(index, IRoadGraph::Mode::ObeyOnewayTag, vehicleModelFactory) , m_vehicleModelFactory(vehicleModelFactory) , m_estimator(estimator) @@ -106,6 +108,11 @@ IRouter::ResultCode SingleMwmRouter::DoCalculateRoute(MwmSet::MwmId const & mwmI RoadPoint const start(startEdge.GetFeatureId().m_index, startEdge.GetSegId()); RoadPoint const finish(finishEdge.GetFeatureId().m_index, finishEdge.GetSegId()); + if (m_getTrafficColoringFn) + m_estimator->SetTrafficColoring(m_getTrafficColoringFn(mwmId)); + else + m_estimator->SetTrafficColoring(nullptr); + IndexGraph graph(GeometryLoader::Create( m_index, mwmId, m_vehicleModelFactory->GetVehicleModelForCountry(country)), m_estimator); @@ -210,7 +217,8 @@ bool SingleMwmRouter::LoadIndex(MwmSet::MwmId const & mwmId, string const & coun } // static -unique_ptr SingleMwmRouter::CreateCarRouter(Index const & index) +unique_ptr SingleMwmRouter::CreateCarRouter(Index const & index, + GetTrafficColoringFn const & getTrafficColoringFn) { auto vehicleModelFactory = make_shared(); // @TODO Bicycle turn generation engine is used now. It's ok for the time being. @@ -218,8 +226,8 @@ unique_ptr SingleMwmRouter::CreateCarRouter(Index const & index auto directionsEngine = make_unique(index); auto estimator = EdgeEstimator::CreateForCar(*vehicleModelFactory->GetVehicleModel()); auto router = - make_unique("astar-bidirectional-car", index, move(vehicleModelFactory), - estimator, move(directionsEngine)); + make_unique("astar-bidirectional-car", index, getTrafficColoringFn, + move(vehicleModelFactory), estimator, move(directionsEngine)); return router; } } // namespace routing diff --git a/routing/single_mwm_router.hpp b/routing/single_mwm_router.hpp index 96cd241453..01839a38a0 100644 --- a/routing/single_mwm_router.hpp +++ b/routing/single_mwm_router.hpp @@ -6,7 +6,10 @@ #include "routing/router.hpp" #include "routing/vehicle_model.hpp" +#include "traffic/traffic_info.hpp" + #include "indexer/index.hpp" +#include "indexer/mwm_set.hpp" #include "std/shared_ptr.hpp" #include "std/unique_ptr.hpp" @@ -19,7 +22,10 @@ class IndexGraph; class SingleMwmRouter { public: + using GetTrafficColoringFn = function(MwmSet::MwmId const &)>; + SingleMwmRouter(string const & name, Index const & index, + GetTrafficColoringFn const & getTrafficColoringFn, shared_ptr vehicleModelFactory, shared_ptr estimator, unique_ptr directionsEngine); @@ -31,7 +37,8 @@ public: m2::PointD const & finalPoint, RouterDelegate const & delegate, Route & route); - static unique_ptr CreateCarRouter(Index const & index); + static unique_ptr CreateCarRouter(Index const & index, + GetTrafficColoringFn const & getTrafficColoringFn); private: IRouter::ResultCode DoCalculateRoute(MwmSet::MwmId const & mwmId, m2::PointD const & startPoint, @@ -44,6 +51,7 @@ private: string const m_name; Index const & m_index; + GetTrafficColoringFn const & m_getTrafficColoringFn; FeaturesRoadGraph m_roadGraph; shared_ptr m_vehicleModelFactory; shared_ptr m_estimator;