diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index f04a0049f5..2112e765c3 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -36,12 +36,6 @@ string GetFeatureCountryName(FeatureID const featureId) return countryName; return countryName.substr(0, pos); } - -inline bool PointsAlmostEqualAbs(const m2::PointD & pt1, const m2::PointD & pt2) -{ - double constexpr kEpsilon = 1e-6; - return my::AlmostEqualAbs(pt1.x, pt2.x, kEpsilon) && my::AlmostEqualAbs(pt1.y, pt2.y, kEpsilon); -} } // namespace diff --git a/routing/road_graph.cpp b/routing/road_graph.cpp index 26aa42cfef..475f4fa0a3 100644 --- a/routing/road_graph.cpp +++ b/routing/road_graph.cpp @@ -15,16 +15,8 @@ namespace routing { - namespace { - -inline bool PointsAlmostEqualAbs(const m2::PointD & pt1, const m2::PointD & pt2) -{ - double constexpr kEpsilon = 1e-6; - return my::AlmostEqualAbs(pt1.x, pt2.x, kEpsilon) && my::AlmostEqualAbs(pt1.y, pt2.y, kEpsilon); -} - vector::const_iterator FindEdgeContainingPoint(vector const & edges, m2::PointD const & pt) { // A P B @@ -166,62 +158,52 @@ IRoadGraph::RoadInfo::RoadInfo(bool bidirectional, double speedKMPH, initializer void IRoadGraph::CrossOutgoingLoader::LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) { - size_t const numPoints = roadInfo.m_points.size(); - - for (size_t i = 0; i < numPoints; ++i) + ForEachEdge(roadInfo, [&featureId, &roadInfo, this](size_t i, m2::PointD const & p) { - m2::PointD const & p = roadInfo.m_points[i]; - - if (!PointsAlmostEqualAbs(m_cross, p)) - continue; - + ASSERT_LESS(i, roadInfo.m_points.size(), ()); if (i > 0 && (roadInfo.m_bidirectional || m_mode == IRoadGraph::Mode::IgnoreOnewayTag)) { // p // o------------>o - m_edges.emplace_back(featureId, false /* forward */, i - 1, p, roadInfo.m_points[i - 1]); } - - if (i < numPoints - 1) + }, + [&featureId, &roadInfo, this](size_t i, m2::PointD const & p) + { + ASSERT_LESS(i, roadInfo.m_points.size(), ()); + if (i < roadInfo.m_points.size() - 1) { // p // o------------>o - m_edges.emplace_back(featureId, true /* forward */, i, p, roadInfo.m_points[i + 1]); } - } + }); } // IRoadGraph::CrossIngoingLoader ---------------------------------------------- void IRoadGraph::CrossIngoingLoader::LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) { - size_t const numPoints = roadInfo.m_points.size(); - - for (size_t i = 0; i < numPoints; ++i) + ForEachEdge(roadInfo, [&featureId, &roadInfo, this](size_t i, m2::PointD const & p) { - m2::PointD const & p = roadInfo.m_points[i]; - - if (!PointsAlmostEqualAbs(m_cross, p)) - continue; - + ASSERT_LESS(i, roadInfo.m_points.size(), ()); if (i > 0) { // p // o------------>o - m_edges.emplace_back(featureId, true /* forward */, i - 1, roadInfo.m_points[i - 1], p); } - - if (i < numPoints - 1 && (roadInfo.m_bidirectional || m_mode == IRoadGraph::Mode::IgnoreOnewayTag)) + }, + [&featureId, &roadInfo, this](size_t i, m2::PointD const & p) + { + ASSERT_LESS(i, roadInfo.m_points.size(), ()); + if (i < roadInfo.m_points.size() - 1 && (roadInfo.m_bidirectional || m_mode == IRoadGraph::Mode::IgnoreOnewayTag)) { // p // o------------>o - m_edges.emplace_back(featureId, false /* forward */, i, roadInfo.m_points[i + 1], p); } - } + }); } // IRoadGraph ------------------------------------------------------------------ diff --git a/routing/road_graph.hpp b/routing/road_graph.hpp index 192841a295..3ba86baff0 100644 --- a/routing/road_graph.hpp +++ b/routing/road_graph.hpp @@ -77,6 +77,12 @@ private: Junction m_endJunction; }; +inline bool PointsAlmostEqualAbs(const m2::PointD & pt1, const m2::PointD & pt2) +{ + double constexpr kEpsilon = 1e-6; + return my::AlmostEqualAbs(pt1.x, pt2.x, kEpsilon) && my::AlmostEqualAbs(pt1.y, pt2.y, kEpsilon); +} + class IRoadGraph { public: @@ -123,6 +129,21 @@ public: virtual void LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) = 0; protected: + template + void ForEachEdge(RoadInfo const & roadInfo, THeadFn && headFn, TTailFn && tailFn) + { + for (size_t i = 0; i < roadInfo.m_points.size(); ++i) + { + m2::PointD const & p = roadInfo.m_points[i]; + + if (!PointsAlmostEqualAbs(m_cross, p)) + continue; + + tailFn(i, p); + headFn(i, p); + } + } + m2::PointD const m_cross; IRoadGraph::Mode const m_mode; TEdgeVector & m_edges; @@ -136,6 +157,7 @@ public: { } + private: // ICrossEdgesLoader overrides: virtual void LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) override; }; @@ -147,6 +169,8 @@ public: : ICrossEdgesLoader(cross, mode, edges) { } + + private: // ICrossEdgesLoader overrides: virtual void LoadEdges(FeatureID const & featureId, RoadInfo const & roadInfo) override; };