From 388fa362a4489b21eb8f0fb4f3d16741063d21cd Mon Sep 17 00:00:00 2001 From: Vladimir Byko-Ianko Date: Fri, 2 Dec 2016 14:41:43 +0300 Subject: [PATCH] Gathering all routing traffic information in CarEdgeEstimator. --- routing/edge_estimator.cpp | 37 ++++++++----- routing/edge_estimator.hpp | 9 +++- .../routing_test_tools.cpp | 5 +- .../routing_test_tools.hpp | 13 +---- .../routing_tests/applying_traffic_test.cpp | 54 +++++++++++++------ routing/routing_tests/index_graph_test.cpp | 15 ++++-- routing/routing_tests/index_graph_tools.cpp | 4 +- routing/routing_tests/index_graph_tools.hpp | 16 +++++- routing/single_mwm_router.cpp | 22 ++++++-- routing/single_mwm_router.hpp | 4 -- traffic/traffic_info.hpp | 4 +- 11 files changed, 122 insertions(+), 61 deletions(-) diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index 42f2c0df98..cdca30ae3e 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -1,5 +1,7 @@ #include "routing/edge_estimator.hpp" +#include "traffic/traffic_info.hpp" + #include "std/algorithm.hpp" namespace routing @@ -19,22 +21,32 @@ inline double TimeBetweenSec(m2::PointD const & from, m2::PointD const & to, dou class CarEdgeEstimator : public EdgeEstimator { public: - CarEdgeEstimator(IVehicleModel const & vehicleModel); + CarEdgeEstimator(IVehicleModel const & vehicleModel, traffic::TrafficInfoGetter const & getter); // EdgeEstimator overrides: + void Start(MwmSet::MwmId const & mwmId) override; double CalcEdgesWeight(uint32_t featureId, RoadGeometry const & road, uint32_t pointFrom, uint32_t pointTo) const override; double CalcHeuristic(m2::PointD const & from, m2::PointD const & to) const override; + void Finish() override; private: + TrafficInfoGetter const & m_trafficGetter; + shared_ptr m_trafficInfo; double const m_maxSpeedMPS; }; -CarEdgeEstimator::CarEdgeEstimator(IVehicleModel const & vehicleModel) - : m_maxSpeedMPS(vehicleModel.GetMaxSpeed() * kKMPH2MPS) +CarEdgeEstimator::CarEdgeEstimator(IVehicleModel const & vehicleModel, + traffic::TrafficInfoGetter const & getter) + : m_trafficGetter(getter), m_maxSpeedMPS(vehicleModel.GetMaxSpeed() * kKMPH2MPS) { } +void CarEdgeEstimator::Start(MwmSet::MwmId const & mwmId) +{ + m_trafficInfo = m_trafficGetter.GetTrafficInfo(mwmId); +} + double CarEdgeEstimator::CalcEdgesWeight(uint32_t featureId, RoadGeometry const & road, uint32_t pointFrom, uint32_t pointTo) const { @@ -44,8 +56,8 @@ double CarEdgeEstimator::CalcEdgesWeight(uint32_t featureId, RoadGeometry const double result = 0.0; double const speedMPS = road.GetSpeed() * kKMPH2MPS; - uint8_t const dir = pointFrom < pointTo ? TrafficInfo::RoadSegmentId::kForwardDirection - : TrafficInfo::RoadSegmentId::kReverseDirection; + auto const dir = pointFrom < pointTo ? TrafficInfo::RoadSegmentId::kForwardDirection + : TrafficInfo::RoadSegmentId::kReverseDirection; for (uint32_t i = start; i < finish; ++i) { double factor = 1.0; @@ -68,18 +80,19 @@ double CarEdgeEstimator::CalcHeuristic(m2::PointD const & from, m2::PointD const { return TimeBetweenSec(from, to, m_maxSpeedMPS); } + +void CarEdgeEstimator::Finish() +{ + m_trafficInfo.reset(); +} } // namespace namespace routing { -void EdgeEstimator::SetTrafficInfo(shared_ptr trafficInfo) -{ - m_trafficInfo = trafficInfo; -} - // static -shared_ptr EdgeEstimator::CreateForCar(IVehicleModel const & vehicleModel) +shared_ptr EdgeEstimator::CreateForCar(IVehicleModel const & vehicleModel, + traffic::TrafficInfoGetter const & getter) { - return make_shared(vehicleModel); + return make_shared(vehicleModel, getter); } } // namespace routing diff --git a/routing/edge_estimator.hpp b/routing/edge_estimator.hpp index d39090ed18..f1887502ef 100644 --- a/routing/edge_estimator.hpp +++ b/routing/edge_estimator.hpp @@ -5,6 +5,8 @@ #include "traffic/traffic_info.hpp" +#include "indexer/mwm_set.hpp" + #include "geometry/point2d.hpp" #include "std/cstdint.hpp" @@ -17,13 +19,16 @@ class EdgeEstimator public: virtual ~EdgeEstimator() = default; + virtual void Start(MwmSet::MwmId const & mwmId) = 0; + virtual double CalcEdgesWeight(uint32_t featureId, RoadGeometry const & road, uint32_t pointFrom, uint32_t pointTo) const = 0; virtual double CalcHeuristic(m2::PointD const & from, m2::PointD const & to) const = 0; - void SetTrafficInfo(shared_ptr trafficInfo); + virtual void Finish() = 0; - static shared_ptr CreateForCar(IVehicleModel const & vehicleModel); + static shared_ptr CreateForCar(IVehicleModel const & vehicleModel, + traffic::TrafficInfoGetter const & getter); protected: shared_ptr m_trafficInfo; diff --git a/routing/routing_integration_tests/routing_test_tools.cpp b/routing/routing_integration_tests/routing_test_tools.cpp index 7c065f03e9..1d7d166c22 100644 --- a/routing/routing_integration_tests/routing_test_tools.cpp +++ b/routing/routing_integration_tests/routing_test_tools.cpp @@ -1,5 +1,7 @@ #include "routing/routing_integration_tests/routing_test_tools.hpp" +#include "routing/routing_tests/index_graph_tools.hpp" + #include "testing/testing.hpp" #include "map/feature_vec_model.hpp" @@ -29,8 +31,8 @@ #include - using namespace routing; +using namespace routing_test; using TRouterFactory = function(Index & index, TCountryFileFn const & countryFileFn)>; @@ -112,6 +114,7 @@ namespace integration } IRouter * GetRouter() const override { return m_carRouter.get(); } + private: TrafficInfoGetterTest m_trafficGetter; unique_ptr m_carRouter; diff --git a/routing/routing_integration_tests/routing_test_tools.hpp b/routing/routing_integration_tests/routing_test_tools.hpp index fcfd8e8113..29fd3711fe 100644 --- a/routing/routing_integration_tests/routing_test_tools.hpp +++ b/routing/routing_integration_tests/routing_test_tools.hpp @@ -6,8 +6,6 @@ #include "map/feature_vec_model.hpp" -#include "traffic/traffic_info.hpp" - #include "platform/local_country_file.hpp" #include "std/set.hpp" @@ -65,21 +63,12 @@ public: virtual IRouter * GetRouter() const = 0; storage::CountryInfoGetter const & GetCountryInfoGetter() const noexcept { return *m_infoGetter; } + protected: shared_ptr m_featuresFetcher; unique_ptr m_infoGetter; }; -class TrafficInfoGetterTest : public traffic::TrafficInfoGetter -{ -public: - // TrafficInfoGetter overrides: - shared_ptr GetTrafficInfo(MwmSet::MwmId const & mwmId) const override - { - return shared_ptr(); - } -}; - void TestOnlineCrosses(ms::LatLon const & startPoint, ms::LatLon const & finalPoint, vector const & expected, IRouterComponents & routerComponents); void TestOnlineFetcher(ms::LatLon const & startPoint, ms::LatLon const & finalPoint, diff --git a/routing/routing_tests/applying_traffic_test.cpp b/routing/routing_tests/applying_traffic_test.cpp index bcb0568b26..293c9c8f15 100644 --- a/routing/routing_tests/applying_traffic_test.cpp +++ b/routing/routing_tests/applying_traffic_test.cpp @@ -85,22 +85,47 @@ unique_ptr BuildXXGraph(shared_ptr estimator) return graph; } +class TrafficInfoGetterTest : public TrafficInfoGetter +{ +public: + TrafficInfoGetterTest(shared_ptr trafficInfo = shared_ptr()) + : m_trafficInfo(trafficInfo) {} + + // TrafficInfoGetter overrides: + shared_ptr GetTrafficInfo(MwmSet::MwmId const &) const override + { + return m_trafficInfo; + } + +private: + shared_ptr m_trafficInfo; +}; + class ApplyingTrafficTest { public: - ApplyingTrafficTest() + ApplyingTrafficTest() { classificator::Load(); } + + void SetEstimator(TrafficInfo::Coloring && coloring) { - classificator::Load(); - m_estimator = EdgeEstimator::CreateForCar(*make_shared()->GetVehicleModel()); + m_trafficGetter = make_unique(make_shared(move(coloring))); + m_estimator = EdgeEstimator::CreateForCar(*make_shared()->GetVehicleModel(), + *m_trafficGetter); } + shared_ptr GetEstimator() const { return m_estimator; } + +private: + unique_ptr m_trafficGetter; shared_ptr m_estimator; }; // Route through XX graph without any traffic info. UNIT_CLASS_TEST(ApplyingTrafficTest, XXGraph_EmptyTrafficColoring) { - unique_ptr graph = BuildXXGraph(m_estimator); + SetEstimator({} /* coloring */); + + unique_ptr graph = BuildXXGraph(GetEstimator()); 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); @@ -112,13 +137,12 @@ UNIT_CLASS_TEST(ApplyingTrafficTest, XXGraph_G0onF3) TrafficInfo::Coloring coloring = { {{3 /* feature id */, 0 /* segment id */, TrafficInfo::RoadSegmentId::kForwardDirection}, SpeedGroup::G0}}; - shared_ptr trafficInfo = make_shared(); - trafficInfo->SetColoringForTesting(coloring); - m_estimator->SetTrafficInfo(trafficInfo); + SetEstimator(move(coloring)); - unique_ptr graph = BuildXXGraph(m_estimator); + unique_ptr graph = BuildXXGraph(GetEstimator()); 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}}; + GetEstimator()->Start(MwmSet::MwmId()); TestRouteGeometry(starter, AStarAlgorithm::Result::OK, expectedGeom); } @@ -128,13 +152,12 @@ UNIT_CLASS_TEST(ApplyingTrafficTest, XXGraph_G0onF3ReverseDir) TrafficInfo::Coloring coloring = { {{3 /* feature id */, 0 /* segment id */, TrafficInfo::RoadSegmentId::kReverseDirection}, SpeedGroup::G0}}; - shared_ptr trafficInfo = make_shared(); - trafficInfo->SetColoringForTesting(coloring); - m_estimator->SetTrafficInfo(trafficInfo); + SetEstimator(move(coloring)); - unique_ptr graph = BuildXXGraph(m_estimator); + unique_ptr graph = BuildXXGraph(GetEstimator()); IndexGraphStarter starter(*graph, RoadPoint(1, 0) /* start */, RoadPoint(6, 1) /* finish */); vector const expectedGeom = {{2 /* x */, 0 /* y */}, {1, 1}, {2, 2}, {3, 3}}; + GetEstimator()->Start(MwmSet::MwmId()); TestRouteGeometry(starter, AStarAlgorithm::Result::OK, expectedGeom); } @@ -150,13 +173,12 @@ UNIT_CLASS_TEST(ApplyingTrafficTest, XXGraph_G0onF3andF6andG4onF8andF4) SpeedGroup::G4}, {{7 /* feature id */, 0 /* segment id */, TrafficInfo::RoadSegmentId::kForwardDirection}, SpeedGroup::G4}}; - shared_ptr trafficInfo = make_shared(); - trafficInfo->SetColoringForTesting(coloring); - m_estimator->SetTrafficInfo(trafficInfo); + SetEstimator(move(coloring)); - unique_ptr graph = BuildXXGraph(m_estimator); + unique_ptr graph = BuildXXGraph(GetEstimator()); 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}}; + GetEstimator()->Start(MwmSet::MwmId()); TestRouteGeometry(starter, AStarAlgorithm::Result::OK, expectedGeom); } } // namespace diff --git a/routing/routing_tests/index_graph_test.cpp b/routing/routing_tests/index_graph_test.cpp index 3fde4305ae..1146f3f519 100644 --- a/routing/routing_tests/index_graph_test.cpp +++ b/routing/routing_tests/index_graph_test.cpp @@ -100,7 +100,8 @@ UNIT_TEST(EdgesTest) loader->AddRoad(4 /* featureId */, true, 1.0 /* speed */, RoadGeometry::Points({{3.0, -1.0}, {3.0, 0.0}, {3.0, 1.0}})); - IndexGraph graph(move(loader), CreateEstimator()); + TrafficInfoGetterTest const trafficGetter; + IndexGraph graph(move(loader), CreateEstimator(trafficGetter)); vector joints; joints.emplace_back(MakeJoint({{0, 1}, {3, 1}})); // J0 @@ -144,7 +145,8 @@ UNIT_TEST(FindPathCross) 1 /* featureId */, false, 1.0 /* speed */, RoadGeometry::Points({{0.0, -2.0}, {-1.0, 0.0}, {0.0, 0.0}, {0.0, 1.0}, {0.0, 2.0}})); - IndexGraph graph(move(loader), CreateEstimator()); + TrafficInfoGetterTest const trafficGetter; + IndexGraph graph(move(loader), CreateEstimator(trafficGetter)); graph.Import({MakeJoint({{0, 2}, {1, 2}})}); @@ -200,7 +202,8 @@ UNIT_TEST(FindPathManhattan) loader->AddRoad(i + kCitySize, false, 1.0 /* speed */, avenue); } - IndexGraph graph(move(loader), CreateEstimator()); + TrafficInfoGetterTest const trafficGetter; + IndexGraph graph(move(loader), CreateEstimator(trafficGetter)); vector joints; for (uint32_t i = 0; i < kCitySize; ++i) @@ -250,7 +253,8 @@ UNIT_TEST(RedressRace) 2 /* featureId */, false, 1.0 /* speed */, RoadGeometry::Points({{0.0, 0.0}, {1.0, 1.0}, {2.0, 1.0}, {3.0, 1.0}, {4.0, 0.0}})); - IndexGraph graph(move(loader), CreateEstimator()); + TrafficInfoGetterTest const trafficGetter; + IndexGraph graph(move(loader), CreateEstimator(trafficGetter)); vector joints; joints.emplace_back(MakeJoint({{0, 0}, {1, 0}, {2, 0}})); // J0 @@ -280,7 +284,8 @@ UNIT_TEST(RoadSpeed) loader->AddRoad(1 /* featureId */, false, 1.0 /* speed */, RoadGeometry::Points({{0.0, 0.0}, {2.0, 0.0}, {4.0, 0.0}})); - IndexGraph graph(move(loader), CreateEstimator()); + TrafficInfoGetterTest const trafficGetter; + IndexGraph graph(move(loader), CreateEstimator(trafficGetter)); vector joints; joints.emplace_back(MakeJoint({{0, 0}, {1, 0}})); // J0 diff --git a/routing/routing_tests/index_graph_tools.cpp b/routing/routing_tests/index_graph_tools.cpp index 8296ffe63a..2a1cc7752b 100644 --- a/routing/routing_tests/index_graph_tools.cpp +++ b/routing/routing_tests/index_graph_tools.cpp @@ -34,9 +34,9 @@ Joint MakeJoint(vector const & points) return joint; } -shared_ptr CreateEstimator() +shared_ptr CreateEstimator(TrafficInfoGetterTest const & trafficGetter) { - return EdgeEstimator::CreateForCar(*make_shared()->GetVehicleModel()); + return EdgeEstimator::CreateForCar(*make_shared()->GetVehicleModel(), trafficGetter); } AStarAlgorithm::Result CalculateRoute(IndexGraphStarter & starter, diff --git a/routing/routing_tests/index_graph_tools.hpp b/routing/routing_tests/index_graph_tools.hpp index 57f98d083f..33c2b91b47 100644 --- a/routing/routing_tests/index_graph_tools.hpp +++ b/routing/routing_tests/index_graph_tools.hpp @@ -7,6 +7,8 @@ #include "routing/base/astar_algorithm.hpp" +#include "traffic/traffic_info.hpp" + #include "geometry/point2d.hpp" #include "std/algorithm.hpp" @@ -30,9 +32,21 @@ private: unordered_map m_roads; }; +class TrafficInfoGetterTest : public traffic::TrafficInfoGetter +{ +public: + TrafficInfoGetterTest() {} + + // TrafficInfoGetter overrides: + shared_ptr GetTrafficInfo(MwmSet::MwmId const & mwmId) const override + { + return shared_ptr(); + } +}; + routing::Joint MakeJoint(vector const & points); -shared_ptr CreateEstimator(); +shared_ptr CreateEstimator(TrafficInfoGetterTest const & trafficGette); routing::AStarAlgorithm::Result CalculateRoute( routing::IndexGraphStarter & graph, vector & roadPoints); diff --git a/routing/single_mwm_router.cpp b/routing/single_mwm_router.cpp index 7fff098e56..c43c94c5a9 100644 --- a/routing/single_mwm_router.cpp +++ b/routing/single_mwm_router.cpp @@ -44,18 +44,30 @@ vector ConvertToJunctions(IndexGraphStarter & starter, vector vehicleModelFactory, shared_ptr estimator, unique_ptr directionsEngine) : m_name(name) , m_index(index) - , m_trafficInfoGetter(getter) , m_roadGraph(index, IRoadGraph::Mode::ObeyOnewayTag, vehicleModelFactory) , m_vehicleModelFactory(vehicleModelFactory) , m_estimator(estimator) @@ -108,7 +120,7 @@ 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()); - m_estimator->SetTrafficInfo(m_trafficInfoGetter.GetTrafficInfo(mwmId)); + EstimatorGuard guard(mwmId, *m_estimator); IndexGraph graph(GeometryLoader::Create( m_index, mwmId, m_vehicleModelFactory->GetVehicleModelForCountry(country)), @@ -221,9 +233,9 @@ unique_ptr SingleMwmRouter::CreateCarRouter( // @TODO Bicycle turn generation engine is used now. It's ok for the time being. // But later a special car turn generation engine should be implemented. auto directionsEngine = make_unique(index); - auto estimator = EdgeEstimator::CreateForCar(*vehicleModelFactory->GetVehicleModel()); + auto estimator = EdgeEstimator::CreateForCar(*vehicleModelFactory->GetVehicleModel(), getter); auto router = - make_unique("astar-bidirectional-car", index, getter, + make_unique("astar-bidirectional-car", index, move(vehicleModelFactory), estimator, move(directionsEngine)); return router; } diff --git a/routing/single_mwm_router.hpp b/routing/single_mwm_router.hpp index 1d68748e1f..90d91ce44d 100644 --- a/routing/single_mwm_router.hpp +++ b/routing/single_mwm_router.hpp @@ -6,8 +6,6 @@ #include "routing/router.hpp" #include "routing/vehicle_model.hpp" -#include "traffic/traffic_info.hpp" - #include "indexer/index.hpp" #include "indexer/mwm_set.hpp" @@ -23,7 +21,6 @@ class SingleMwmRouter { public: SingleMwmRouter(string const & name, Index const & index, - traffic::TrafficInfoGetter const & getter, shared_ptr vehicleModelFactory, shared_ptr estimator, unique_ptr directionsEngine); @@ -49,7 +46,6 @@ private: string const m_name; Index const & m_index; - traffic::TrafficInfoGetter const & m_trafficInfoGetter; FeaturesRoadGraph m_roadGraph; shared_ptr m_vehicleModelFactory; shared_ptr m_estimator; diff --git a/traffic/traffic_info.hpp b/traffic/traffic_info.hpp index acf35efa3e..7d96309edc 100644 --- a/traffic/traffic_info.hpp +++ b/traffic/traffic_info.hpp @@ -70,7 +70,9 @@ public: TrafficInfo(TrafficInfo && info) : m_coloring(move(info.m_coloring)), m_mwmId(info.m_mwmId) {} - void SetColoringForTesting(Coloring & coloring) { m_coloring = coloring; } + // For testing only. + TrafficInfo(Coloring && coloring) : m_coloring(move(coloring)) {} + // Fetches the latest traffic data from the server and updates the coloring. // Construct the url by passing an MwmId. // *NOTE* This method must not be called on the UI thread.