diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index f819cde3d7..fc98327786 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -15,6 +15,8 @@ #include "base/logging.hpp" #include "base/macros.hpp" +#include "std/limits.hpp" + namespace routing { @@ -127,17 +129,13 @@ public: if (!m_graph.IsRoad(ft)) return; - // Note. RoadInfo::m_speedKMPH is not used in ICrossEdgesLoader::operator(). - // @TODO(bykoianko) The code below should be rewritten to get rid of m_graph.GetSpeedKMpHFromFt(). - double const speedKMpH = m_graph.GetSpeedKMpHFromFt(ft, false /* in city */); - if (speedKMpH <= 0.0) - return; - FeatureID const featureId = ft.GetID(); - IRoadGraph::RoadInfo const & roadInfo = m_graph.GetCachedRoadInfo(featureId, ft, speedKMpH); + auto constexpr invalidSpeed = numeric_limits::max(); + IRoadGraph::RoadInfo const & roadInfo = m_graph.GetCachedRoadInfo(featureId, ft, invalidSpeed); + CHECK_EQUAL(roadInfo.m_speedKMPH, invalidSpeed, ()); - m_edgesLoader(featureId, roadInfo); + m_edgesLoader(featureId, roadInfo.m_junctions, roadInfo.m_bidirectional); } private: @@ -179,17 +177,13 @@ void FeaturesRoadGraph::FindClosestEdges(m2::PointD const & point, uint32_t coun if (!m_vehicleModel.IsRoad(ft)) return; - // Note. RoadInfo::m_speedKMPH is not used in NearestEdgeFinder. - double const speedKMpH = m_vehicleModel.GetSpeed(ft, false /* in city */).m_weight; - if (speedKMpH <= 0.0) - return; - FeatureID const featureId = ft.GetID(); - IRoadGraph::RoadInfo const & roadInfo = GetCachedRoadInfo(featureId, ft, speedKMpH); + auto constexpr invalidSpeed = numeric_limits::max(); + IRoadGraph::RoadInfo const & roadInfo = GetCachedRoadInfo(featureId, ft, invalidSpeed); + CHECK_EQUAL(roadInfo.m_speedKMPH, invalidSpeed, ()); - // @TODO(bykoianko) Rewrite the code to get rid of call m_vehicleModel.GetSpeed() - finder.AddInformationSource(featureId, roadInfo); + finder.AddInformationSource(featureId, roadInfo.m_junctions, roadInfo.m_bidirectional); }; m_dataSource.ForEachInRect( diff --git a/routing/nearest_edge_finder.cpp b/routing/nearest_edge_finder.cpp index 2c6a0a15a5..e6267c7ad5 100644 --- a/routing/nearest_edge_finder.cpp +++ b/routing/nearest_edge_finder.cpp @@ -15,24 +15,26 @@ NearestEdgeFinder::NearestEdgeFinder(m2::PointD const & point) { } -void NearestEdgeFinder::AddInformationSource(FeatureID const & featureId, IRoadGraph::RoadInfo const & roadInfo) +void NearestEdgeFinder::AddInformationSource(FeatureID const & featureId, + IRoadGraph::JunctionVec const & junctions, + bool bidirectional) { Candidate res; - size_t const count = roadInfo.m_junctions.size(); + size_t const count = junctions.size(); ASSERT_GREATER(count, 1, ()); for (size_t i = 1; i < count; ++i) { /// @todo Probably, we need to get exact projection distance in meters. - m2::ParametrizedSegment segment(roadInfo.m_junctions[i - 1].GetPoint(), - roadInfo.m_junctions[i].GetPoint()); + m2::ParametrizedSegment segment(junctions[i - 1].GetPoint(), + junctions[i].GetPoint()); m2::PointD const pt = segment.ClosestPointTo(m_point); double const d = m_point.SquaredLength(pt); if (d < res.m_dist) { - Junction const & segStart = roadInfo.m_junctions[i - 1]; - Junction const & segEnd = roadInfo.m_junctions[i]; + Junction const & segStart = junctions[i - 1]; + Junction const & segEnd = junctions[i]; feature::TAltitude const startAlt = segStart.GetAltitude(); feature::TAltitude const endAlt = segEnd.GetAltitude(); @@ -54,7 +56,7 @@ void NearestEdgeFinder::AddInformationSource(FeatureID const & featureId, IRoadG res.m_segId = static_cast(i - 1); res.m_segStart = segStart; res.m_segEnd = segEnd; - res.m_bidirectional = roadInfo.m_bidirectional; + res.m_bidirectional = bidirectional; ASSERT_NOT_EQUAL(res.m_segStart.GetAltitude() , feature::kInvalidAltitude, ()); ASSERT_NOT_EQUAL(res.m_segEnd.GetAltitude(), feature::kInvalidAltitude, ()); diff --git a/routing/nearest_edge_finder.hpp b/routing/nearest_edge_finder.hpp index 536c1507bc..1374ae2c81 100644 --- a/routing/nearest_edge_finder.hpp +++ b/routing/nearest_edge_finder.hpp @@ -42,7 +42,9 @@ public: inline bool HasCandidates() const { return !m_candidates.empty(); } - void AddInformationSource(FeatureID const & featureId, IRoadGraph::RoadInfo const & roadInfo); + void AddInformationSource(FeatureID const & featureId, + IRoadGraph::JunctionVec const & junctions, + bool bidirectiona); void MakeResult(std::vector> & res, size_t const maxCountFeatures); }; diff --git a/routing/road_graph.cpp b/routing/road_graph.cpp index 4b14f91dd9..aba03024d4 100644 --- a/routing/road_graph.cpp +++ b/routing/road_graph.cpp @@ -169,11 +169,12 @@ IRoadGraph::RoadInfo::RoadInfo(bool bidirectional, double speedKMPH, {} // IRoadGraph::CrossOutgoingLoader --------------------------------------------- -void IRoadGraph::CrossOutgoingLoader::LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) +void IRoadGraph::CrossOutgoingLoader::LoadEdges(FeatureID const & featureId, + JunctionVec const & junctions, bool bidirectional) { - ForEachEdge(roadInfo, [&featureId, &roadInfo, this](size_t segId, Junction const & endJunction, - bool forward) { - if (forward || roadInfo.m_bidirectional || m_mode == IRoadGraph::Mode::IgnoreOnewayTag) + ForEachEdge(junctions, [&featureId, bidirectional, this]( + size_t segId, Junction const & endJunction, bool forward) { + if (forward || bidirectional || m_mode == IRoadGraph::Mode::IgnoreOnewayTag) { m_edges.push_back(Edge::MakeReal(featureId, forward, base::asserted_cast(segId), m_cross, endJunction)); @@ -182,11 +183,12 @@ void IRoadGraph::CrossOutgoingLoader::LoadEdges(FeatureID const & featureId, Roa } // IRoadGraph::CrossIngoingLoader ---------------------------------------------- -void IRoadGraph::CrossIngoingLoader::LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) +void IRoadGraph::CrossIngoingLoader::LoadEdges(FeatureID const & featureId, + JunctionVec const & junctions, bool bidirectional) { - ForEachEdge(roadInfo, [&featureId, &roadInfo, this](size_t segId, Junction const & endJunction, - bool forward) { - if (!forward || roadInfo.m_bidirectional || m_mode == IRoadGraph::Mode::IgnoreOnewayTag) + ForEachEdge(junctions, [&featureId, bidirectional, this]( + size_t segId, Junction const & endJunction, bool forward) { + if (!forward || bidirectional || m_mode == IRoadGraph::Mode::IgnoreOnewayTag) { m_edges.push_back(Edge::MakeReal(featureId, !forward, base::asserted_cast(segId), endJunction, m_cross)); diff --git a/routing/road_graph.hpp b/routing/road_graph.hpp index f76190690d..d13108f691 100644 --- a/routing/road_graph.hpp +++ b/routing/road_graph.hpp @@ -156,6 +156,7 @@ public: using Vertex = Junction; using Edge = routing::Edge; using Weight = double; + using JunctionVec = buffer_vector; enum class Mode { @@ -173,7 +174,7 @@ public: RoadInfo(RoadInfo const &) = default; RoadInfo & operator=(RoadInfo const &) = default; - buffer_vector m_junctions; + JunctionVec m_junctions; double m_speedKMPH; bool m_bidirectional; }; @@ -189,39 +190,38 @@ public: virtual ~ICrossEdgesLoader() = default; - void operator()(FeatureID const & featureId, RoadInfo const & roadInfo) + void operator()(FeatureID const & featureId, JunctionVec const & junctions, + bool bidirectional) { - LoadEdges(featureId, roadInfo); + LoadEdges(featureId, junctions, bidirectional); } private: - virtual void LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) = 0; + virtual void LoadEdges(FeatureID const & featureId, JunctionVec const & junctions, + bool bidirectional) = 0; protected: template - void ForEachEdge(RoadInfo const & roadInfo, TFn && fn) + void ForEachEdge(JunctionVec const & junctions, TFn && fn) { - for (size_t i = 0; i < roadInfo.m_junctions.size(); ++i) + for (size_t i = 0; i < junctions.size(); ++i) { - if (!base::AlmostEqualAbs(m_cross.GetPoint(), roadInfo.m_junctions[i].GetPoint(), - kPointsEqualEpsilon)) - { + if (!base::AlmostEqualAbs(m_cross.GetPoint(), junctions[i].GetPoint(), kPointsEqualEpsilon)) continue; - } - if (i + 1 < roadInfo.m_junctions.size()) + if (i + 1 < junctions.size()) { // Head of the edge. // m_cross // o------------>o - fn(i, roadInfo.m_junctions[i + 1], true /* forward */); + fn(i, junctions[i + 1], true /* forward */); } if (i > 0) { // Tail of the edge. // m_cross // o------------>o - fn(i - 1, roadInfo.m_junctions[i - 1], false /* backward */); + fn(i - 1, junctions[i - 1], false /* backward */); } } } @@ -241,7 +241,8 @@ public: private: // ICrossEdgesLoader overrides: - virtual void LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) override; + void LoadEdges(FeatureID const & featureId, JunctionVec const & junctions, + bool bidirectional) override; }; class CrossIngoingLoader : public ICrossEdgesLoader @@ -254,14 +255,15 @@ public: private: // ICrossEdgesLoader overrides: - virtual void LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) override; + void LoadEdges(FeatureID const & featureId, JunctionVec const & junctions, + bool bidirectional) override; }; virtual ~IRoadGraph() = default; - virtual void GetOutgoingEdges(Junction const & junction, TEdgeVector & edges) const override; + void GetOutgoingEdges(Junction const & junction, TEdgeVector & edges) const override; - virtual void GetIngoingEdges(Junction const & junction, TEdgeVector & edges) const override; + void GetIngoingEdges(Junction const & junction, TEdgeVector & edges) const override; /// Removes all fake turns and vertices from the graph. void ResetFakes(); diff --git a/routing/routing_tests/nearest_edge_finder_tests.cpp b/routing/routing_tests/nearest_edge_finder_tests.cpp index 74f7fd1a49..7a27c5cc42 100644 --- a/routing/routing_tests/nearest_edge_finder_tests.cpp +++ b/routing/routing_tests/nearest_edge_finder_tests.cpp @@ -19,7 +19,8 @@ void TestNearestOnMock1(m2::PointD const & point, size_t const candidatesCount, for (size_t i = 0; i < graph->GetRoadCount(); ++i) { FeatureID const featureId = MakeTestFeatureID(base::checked_cast(i)); - finder.AddInformationSource(featureId, graph->GetRoadInfo(featureId, false /* in city */)); + auto const & roadInfo = graph->GetRoadInfo(featureId, false /* in city */); + finder.AddInformationSource(featureId, roadInfo.m_junctions, roadInfo.m_bidirectional); } vector> result; diff --git a/routing/routing_tests/road_graph_builder.cpp b/routing/routing_tests/road_graph_builder.cpp index 57b38f0148..f613ece475 100644 --- a/routing/routing_tests/road_graph_builder.cpp +++ b/routing/routing_tests/road_graph_builder.cpp @@ -87,7 +87,10 @@ void RoadGraphMockSource::ForEachFeatureClosestToCross(m2::PointD const & /* cro ICrossEdgesLoader & edgesLoader) const { for (size_t roadId = 0; roadId < m_roads.size(); ++roadId) - edgesLoader(MakeTestFeatureID(base::checked_cast(roadId)), m_roads[roadId]); + { + edgesLoader(MakeTestFeatureID(base::checked_cast(roadId)), m_roads[roadId] + .m_junctions, m_roads[roadId].m_bidirectional); + } } void RoadGraphMockSource::FindClosestEdges(m2::PointD const & point, uint32_t count,