diff --git a/routing/base/astar_algorithm.hpp b/routing/base/astar_algorithm.hpp index ed148ab947..1c753701b3 100644 --- a/routing/base/astar_algorithm.hpp +++ b/routing/base/astar_algorithm.hpp @@ -2,7 +2,6 @@ #include "base/assert.hpp" #include "base/cancellable.hpp" - #include "std/algorithm.hpp" #include "std/functional.hpp" #include "std/iostream.hpp" diff --git a/routing/car_router.cpp b/routing/car_router.cpp index a89d392bc6..ba99f2dc96 100644 --- a/routing/car_router.cpp +++ b/routing/car_router.cpp @@ -401,7 +401,6 @@ CarRouter::ResultCode CarRouter::CalculateRoute(m2::PointD const & startPoint, m2::PointD const & finalPoint, RouterDelegate const & delegate, Route & route) { -// TODO uncomment this to activate cross mwm index router. if (AllMwmsHaveRoutingIndex()) return m_router->CalculateRoute(startPoint, startDirection, finalPoint, delegate, route); diff --git a/routing/cross_mwm_index_graph.cpp b/routing/cross_mwm_index_graph.cpp index 44b142071a..4c146b1bb7 100644 --- a/routing/cross_mwm_index_graph.cpp +++ b/routing/cross_mwm_index_graph.cpp @@ -1,4 +1,5 @@ #include "routing/cross_mwm_index_graph.hpp" + #include "routing/cross_mwm_road_graph.hpp" #include "routing/osrm_path_segment_factory.hpp" @@ -14,29 +15,36 @@ using namespace std; namespace { +struct NodeIds +{ + TOsrmNodeId m_directNodeId; + TOsrmNodeId m_reverseNodeId; +}; + /// \returns FtSeg by |segment|. OsrmMappingTypes::FtSeg GetFtSeg(Segment const & segment) { - uint32_t const startPnt = segment.IsForward() ? segment.GetPointId(false /* front */) - : segment.GetPointId(true /* front */); - uint32_t const endPnt = segment.IsForward() ? segment.GetPointId(true /* front */) - : segment.GetPointId(false /* front */); - return OsrmMappingTypes::FtSeg(segment.GetFeatureId(), startPnt, endPnt); + return OsrmMappingTypes::FtSeg(segment.GetFeatureId(), segment.GetMinPointId(), + segment.GetMaxPointId()); } /// \returns a pair of direct and reverse(backward) node id by |segment|. /// The first member of the pair is direct node id and the second is reverse node id. -pair GetDirectAndReverseNodeId( - OsrmFtSegMapping const & segMapping, Segment const & segment) +NodeIds GetDirectAndReverseNodeId(OsrmFtSegMapping const & segMapping, Segment const & segment) { OsrmFtSegMapping::TFtSegVec const ftSegs = {GetFtSeg(segment)}; - OsrmFtSegMapping::OsrmNodesT nodeIds; - segMapping.GetOsrmNodes(ftSegs, nodeIds); - CHECK_LESS(nodeIds.size(), 2, ()); - return nodeIds.empty() ? make_pair(INVALID_NODE_ID, INVALID_NODE_ID) - : segment.IsForward() ? nodeIds.begin()->second - : std::make_pair(nodeIds.begin()->second.second, - nodeIds.begin()->second.first); + OsrmFtSegMapping::OsrmNodesT osrmNodes; + segMapping.GetOsrmNodes(ftSegs, osrmNodes); + CHECK_LESS(osrmNodes.size(), 2, ()); + if (osrmNodes.empty()) + return {INVALID_NODE_ID, INVALID_NODE_ID}; + + NodeIds const forwardNodeIds = {osrmNodes.begin()->second.first, + osrmNodes.begin()->second.second}; + NodeIds const backwardNodeIds = {osrmNodes.begin()->second.second, + osrmNodes.begin()->second.first}; + + return segment.IsForward() ? forwardNodeIds : backwardNodeIds; } bool GetFirstValidSegment(OsrmFtSegMapping const & segMapping, NumMwmId numMwmId, @@ -57,8 +65,8 @@ bool GetFirstValidSegment(OsrmFtSegMapping const & segMapping, NumMwmId numMwmId segment = Segment(numMwmId, seg.m_fid, min(seg.m_pointStart, seg.m_pointEnd), seg.IsForward()); return true; } - LOG(LDEBUG, ("No valid segments in the range returned by OsrmFtSegMapping::GetSegmentsRange(", nodeId, - "). Num mwm id:", numMwmId)); + LOG(LDEBUG, ("No valid segments in the range returned by OsrmFtSegMapping::GetSegmentsRange(", + nodeId, "). Num mwm id:", numMwmId)); return false; } @@ -72,7 +80,7 @@ void AddFirstValidSegment(OsrmFtSegMapping const & segMapping, NumMwmId numMwmId void FillTransitionSegments(OsrmFtSegMapping const & segMapping, TWrittenNodeId nodeId, NumMwmId numMwmId, ms::LatLon const & latLon, - std::map> & transitionSegments) + map> & transitionSegments) { Segment key; if (!GetFirstValidSegment(segMapping, numMwmId, nodeId, key)) @@ -81,7 +89,7 @@ void FillTransitionSegments(OsrmFtSegMapping const & segMapping, TWrittenNodeId transitionSegments[key].push_back(latLon); } -vector const & GetLatLon(std::map> const & segMap, +vector const & GetLatLon(map> const & segMap, Segment const & s) { auto it = segMap.find(s); @@ -99,33 +107,37 @@ void AddSegmentEdge(NumMwmIds const & numMwmIds, OsrmFtSegMapping const & segMap if (!crossNode.mwmId.IsAlive()) return; - NumMwmId const crossNodeMwmId = numMwmIds.GetId(crossNode.mwmId.GetInfo()->GetLocalFile().GetCountryFile()); + NumMwmId const crossNodeMwmId = + numMwmIds.GetId(crossNode.mwmId.GetInfo()->GetLocalFile().GetCountryFile()); CHECK_EQUAL(numMwmId, crossNodeMwmId, ()); Segment segment; if (!GetFirstValidSegment(segMapping, crossNodeMwmId, crossNode.node, segment)) return; - // OSRM and AStar have different car models, therefore AStar heuristic doen't work for OSRM edges. - // This factor makes AStar heuristic much smaller then OSRM egdes. + // OSRM and AStar have different car models, therefore AStar heuristic doesn't work for OSRM node + // ids (edges). + // This factor makes index graph (used in AStar) edge weight smaller then node ids weight. // - // As a result large cross mwm routes mith leap works as Dijkstra, but short and medium routes without leaps works as AStar. - // Most of routes doen't use leaps, therefore it is important to keep AStar performance. + // As a result large cross mwm routes with connectors works as Dijkstra, but short and medium routes + // without connectors works as AStar. + // Most of routes don't use leaps, therefore it is important to keep AStar performance. double constexpr kAstarHeuristicFactor = 100000; - edges.emplace_back(segment, osrmEdge.GetWeight() * kOSRMWeightToSecondsMultiplier * kAstarHeuristicFactor); + edges.emplace_back(segment, + osrmEdge.GetWeight() * kOSRMWeightToSecondsMultiplier * kAstarHeuristicFactor); } } // namespace namespace routing { -CrossMwmIndexGraph::CrossMwmIndexGraph(shared_ptr numMwmIds, RoutingIndexManager & indexManager) +CrossMwmIndexGraph::CrossMwmIndexGraph(shared_ptr numMwmIds, + RoutingIndexManager & indexManager) : m_indexManager(indexManager), m_numMwmIds(numMwmIds) { - InitCrossMwmGraph(); + ResetCrossMwmGraph(); } CrossMwmIndexGraph::~CrossMwmIndexGraph() {} - bool CrossMwmIndexGraph::IsTransition(Segment const & s, bool isOutgoing) { // @TODO(bykoianko) It's necessary to check if mwm of |s| contains an A* cross mwm section @@ -141,9 +153,10 @@ bool CrossMwmIndexGraph::IsTransition(Segment const & s, bool isOutgoing) void CrossMwmIndexGraph::GetTwins(Segment const & s, bool isOutgoing, vector & twins) { - CHECK(IsTransition(s, isOutgoing), ("The segment is not a transition segment.")); + CHECK(IsTransition(s, isOutgoing), ("The segment", s, "is not a transition segment for isOutgoing ==", isOutgoing)); // Note. There's an extremely rare case when a segment is ingoing and outgoing at the same time. - // |twins| is not filled for such cases. For details please see a note in rossMwmIndexGraph::GetEdgeList(). + // |twins| is not filled for such cases. For details please see a note in + // rossMwmIndexGraph::GetEdgeList(). if (IsTransition(s, !isOutgoing)) return; @@ -151,8 +164,7 @@ void CrossMwmIndexGraph::GetTwins(Segment const & s, bool isOutgoing, vector const & neighboringMwm = segMapping->m_crossContext.GetNeighboringMwmList(); for (string const & name : neighboringMwm) @@ -161,30 +173,32 @@ void CrossMwmIndexGraph::GetTwins(Segment const & s, bool isOutgoing, vector const & latLons = isOutgoing ? GetLatLon(it->second.m_outgoing, s) - : GetLatLon(it->second.m_ingoing, s); + vector const & latLons = + isOutgoing ? GetLatLon(it->second.m_outgoing, s) : GetLatLon(it->second.m_ingoing, s); for (string const & name : neighboringMwm) { - auto const addFirstValidSegment = [&](NumMwmId numMwmId, TRoutingMappingPtr const & mapping) - { - for (ms::LatLon const & ll : latLons) + NumMwmId const numMwmId = m_numMwmIds->GetId(CountryFile(name)); + auto const addFirstValidSegment = [&](TRoutingMappingPtr const & mapping) { + for (auto const & ll : latLons) { if (isOutgoing) { - mapping->m_crossContext.ForEachIngoingNodeNearPoint(ll, [&](IngoingCrossNode const & node){ - AddFirstValidSegment(mapping->m_segMapping, numMwmId, node.m_nodeId, twins); - }); + mapping->m_crossContext.ForEachIngoingNodeNearPoint( + ll, [&](IngoingCrossNode const & node) { + AddFirstValidSegment(mapping->m_segMapping, numMwmId, node.m_nodeId, twins); + }); } else { - mapping->m_crossContext.ForEachOutgoingNodeNearPoint(ll, [&](OutgoingCrossNode const & node){ - AddFirstValidSegment(mapping->m_segMapping, numMwmId, node.m_nodeId, twins); - }); + mapping->m_crossContext.ForEachOutgoingNodeNearPoint( + ll, [&](OutgoingCrossNode const & node) { + AddFirstValidSegment(mapping->m_segMapping, numMwmId, node.m_nodeId, twins); + }); } } }; - if (!LoadWith(m_numMwmIds->GetId(CountryFile(name)), addFirstValidSegment)) + if (!LoadWith(numMwmId, addFirstValidSegment)) continue; // mwm was not loaded. } }; @@ -196,29 +210,34 @@ void CrossMwmIndexGraph::GetTwins(Segment const & s, bool isOutgoing, vector & edges) +void CrossMwmIndexGraph::GetEdgeList(Segment const & s, bool isOutgoing, + vector & edges) { // @TODO(bykoianko) It's necessary to check if mwm of |s| contains an A* cross mwm section // and if so to use it. If not, osrm cross mwm sections should be used. - CHECK(IsTransition(s, !isOutgoing), ()); + CHECK(IsTransition(s, !isOutgoing), ("The segment is not a transition segment. IsTransition(", + s, ",", !isOutgoing, ") returns false.")); // Note. According to cross-mwm OSRM sections there're node id which could be ingoing and outgoing - // at the same time. For example in Berlin mwm on Nordlicher Berliner Ring (A10) near crossing with A11 + // at the same time. For example in Berlin mwm on Nordlicher Berliner Ring (A10) near crossing + // with A11 // there's such node id. It's an extremely rare case. There're probably several such node id - // for the whole Europe. Such cases are not processed in WorldGraph::GetEdgeList() for the time being. - // To prevent filling |edges| with twins instead of leap edges and vice versa in WorldGraph::GetEdgeList() + // for the whole Europe. Such cases are not processed in WorldGraph::GetEdgeList() for the time + // being. + // To prevent filling |edges| with twins instead of leap edges and vice versa in + // WorldGraph::GetEdgeList() // CrossMwmIndexGraph::GetEdgeList() does not fill |edges| if |s| is a transition segment which // corresponces node id described above. if (IsTransition(s, isOutgoing)) return; edges.clear(); - auto const fillEdgeList = [&](NumMwmId /* numMwmId */, TRoutingMappingPtr const & mapping){ + auto const fillEdgeList = [&](TRoutingMappingPtr const & mapping) { vector borderCrosses; GetBorderCross(mapping, s, isOutgoing, borderCrosses); - for (BorderCross const v : borderCrosses) + for (BorderCross const & v : borderCrosses) { vector adj; if (isOutgoing) @@ -226,8 +245,8 @@ void CrossMwmIndexGraph::GetEdgeList(Segment const & s, bool isOutgoing, vector< else m_crossMwmGraph->GetIngoingEdgesList(v, adj); - for (CrossWeightedEdge const & a : adj) - AddSegmentEdge(*m_numMwmIds, mapping->m_segMapping, a, isOutgoing, s.GetMwmId(), edges); + for (CrossWeightedEdge const & edge : adj) + AddSegmentEdge(*m_numMwmIds, mapping->m_segMapping, edge, isOutgoing, s.GetMwmId(), edges); } }; LoadWith(s.GetMwmId(), fillEdgeList); @@ -237,12 +256,12 @@ void CrossMwmIndexGraph::GetEdgeList(Segment const & s, bool isOutgoing, vector< void CrossMwmIndexGraph::Clear() { - InitCrossMwmGraph(); + ResetCrossMwmGraph(); m_transitionCache.clear(); m_mappingGuards.clear(); } -void CrossMwmIndexGraph::InitCrossMwmGraph() +void CrossMwmIndexGraph::ResetCrossMwmGraph() { m_crossMwmGraph = make_unique(m_indexManager); } @@ -252,7 +271,7 @@ void CrossMwmIndexGraph::InsertWholeMwmTransitionSegments(NumMwmId numMwmId) if (m_transitionCache.count(numMwmId) != 0) return; - auto const fillAllTransitionSegments = [this](NumMwmId numMwmId, TRoutingMappingPtr const & mapping){ + auto const fillAllTransitionSegments = [&](TRoutingMappingPtr const & mapping) { TransitionSegments transitionSegments; mapping->m_crossContext.ForEachOutgoingNode([&](OutgoingCrossNode const & node) { @@ -274,48 +293,50 @@ void CrossMwmIndexGraph::InsertWholeMwmTransitionSegments(NumMwmId numMwmId) m_transitionCache.emplace(numMwmId, TransitionSegments()); } -void CrossMwmIndexGraph::GetBorderCross(TRoutingMappingPtr const & mapping, Segment const & s, bool isOutgoing, - vector & borderCrosses) +void CrossMwmIndexGraph::GetBorderCross(TRoutingMappingPtr const & mapping, Segment const & s, + bool isOutgoing, vector & borderCrosses) { // ingoing edge - pair const directReverseTo = GetDirectAndReverseNodeId(mapping->m_segMapping, s); + NodeIds const nodeIdsTo = GetDirectAndReverseNodeId(mapping->m_segMapping, s); - vector const & transitionPnt = isOutgoing ? GetIngoingTransitionPnt(s) - : GetOutgoingTransitionPnt(s); - CHECK(!transitionPnt.empty(), ()); + vector const & transitionPoints = + isOutgoing ? GetIngoingTransitionPoints(s) : GetOutgoingTransitionPoints(s); + CHECK(!transitionPoints.empty(), ("Segment:", s, ", isOutgoing:", isOutgoing)); // If |isOutgoing| == true |nodes| is "to" cross nodes, otherwise |nodes| is "from" cross nodes. vector nodes; - for (ms::LatLon const & p : transitionPnt) - nodes.emplace_back(directReverseTo.first, directReverseTo.second, mapping->GetMwmId(), p); + for (ms::LatLon const & p : transitionPoints) + nodes.emplace_back(nodeIdsTo.m_directNodeId, nodeIdsTo.m_reverseNodeId, mapping->GetMwmId(), p); // outgoing edge vector twins; GetTwins(s, !isOutgoing, twins); - CHECK(!twins.empty(), ()); + CHECK(!twins.empty(), ("Segment:", s, ", isOutgoing:", isOutgoing)); for (Segment const & twin : twins) { // If |isOutgoing| == true |otherSideMapping| is mapping outgoing (to) border cross. // If |isOutgoing| == false |mapping| is mapping ingoing (from) border cross. - auto const fillBorderCrossOut = [&](NumMwmId /* otherSideNumMwmId */, TRoutingMappingPtr const & otherSideMapping){ - pair directReverseFrom = GetDirectAndReverseNodeId(otherSideMapping->m_segMapping, twin); - vector const & otherSideTransitionPnt = isOutgoing ? GetOutgoingTransitionPnt(twin) - : GetIngoingTransitionPnt(twin); + auto const fillBorderCrossOut = [&](TRoutingMappingPtr const & otherSideMapping) { + NodeIds const nodeIdsFrom = GetDirectAndReverseNodeId(otherSideMapping->m_segMapping, twin); + vector const & otherSideTransitionPoints = + isOutgoing ? GetOutgoingTransitionPoints(twin) : GetIngoingTransitionPoints(twin); - CHECK(!otherSideTransitionPnt.empty(), ()); + CHECK(!otherSideTransitionPoints.empty(), ("Segment:", s, ", isOutgoing:", isOutgoing)); for (CrossNode const & node : nodes) { - // If |isOutgoing| == true |otherSideNodes| is "from" cross nodes, otherwise |otherSideNodes| is "to" cross nodes. + // If |isOutgoing| == true |otherSideNodes| is "from" cross nodes, otherwise + // |otherSideNodes| is "to" cross nodes. BorderCross bc; if (isOutgoing) bc.toNode = node; else bc.fromNode = node; - for (ms::LatLon const & ll : otherSideTransitionPnt) + for (ms::LatLon const & ll : otherSideTransitionPoints) { CrossNode & resultNode = isOutgoing ? bc.fromNode : bc.toNode; - resultNode = CrossNode(directReverseFrom.first, directReverseFrom.second, otherSideMapping->GetMwmId(), ll); + resultNode = CrossNode(nodeIdsFrom.m_directNodeId, nodeIdsFrom.m_reverseNodeId, + otherSideMapping->GetMwmId(), ll); borderCrosses.push_back(bc); } } @@ -336,19 +357,19 @@ CrossMwmIndexGraph::TransitionSegments const & CrossMwmIndexGraph::GetSegmentMap return it->second; } -vector const & CrossMwmIndexGraph::GetIngoingTransitionPnt(Segment const & s) +vector const & CrossMwmIndexGraph::GetIngoingTransitionPoints(Segment const & s) { auto const & ingoingSeg = GetSegmentMaps(s.GetMwmId()).m_ingoing; auto const it = ingoingSeg.find(s); - CHECK(it != ingoingSeg.cend(), ()); + CHECK(it != ingoingSeg.cend(), ("Segment:", s)); return it->second; } -vector const & CrossMwmIndexGraph::GetOutgoingTransitionPnt(Segment const & s) +vector const & CrossMwmIndexGraph::GetOutgoingTransitionPoints(Segment const & s) { auto const & outgoingSeg = GetSegmentMaps(s.GetMwmId()).m_outgoing; auto const it = outgoingSeg.find(s); - CHECK(it != outgoingSeg.cend(), ()); + CHECK(it != outgoingSeg.cend(), ("Segment:", s)); return it->second; } } // namespace routing diff --git a/routing/cross_mwm_index_graph.hpp b/routing/cross_mwm_index_graph.hpp index 3d8194d569..053c7e2d78 100644 --- a/routing/cross_mwm_index_graph.hpp +++ b/routing/cross_mwm_index_graph.hpp @@ -84,7 +84,7 @@ private: std::map> m_outgoing; }; - void InitCrossMwmGraph(); + void ResetCrossMwmGraph(); /// \brief Inserts all ingoing and outgoing transition segments of mwm with |numMwmId| /// to |m_transitionCache|. @@ -96,12 +96,12 @@ private: /// \note |s| and |isOutgoing| params have the same restrictions which described in /// GetEdgeList() method. void GetBorderCross(TRoutingMappingPtr const & mapping, Segment const & s, bool isOutgoing, - vector & borderCrosses); + std::vector & borderCrosses); TransitionSegments const & GetSegmentMaps(NumMwmId numMwmId); - vector const & GetIngoingTransitionPnt(Segment const & s); - vector const & GetOutgoingTransitionPnt(Segment const & s); + std::vector const & GetIngoingTransitionPoints(Segment const & s); + std::vector const & GetOutgoingTransitionPoints(Segment const & s); template bool LoadWith(NumMwmId numMwmId, Fn && fn) @@ -120,13 +120,13 @@ private: mapping->LoadCrossContext(); } - fn(numMwmId, mapping); + fn(mapping); return true; } RoutingIndexManager & m_indexManager; std::shared_ptr m_numMwmIds; - /// \note According to the constructor CrossMwmGraph is inited with RoutingIndexManager &. + /// \note According to the constructor CrossMwmGraph is initialized with RoutingIndexManager &. /// But then it is copied by value to CrossMwmGraph::RoutingIndexManager m_indexManager. /// It means that there're two copies of RoutingIndexManager in CrossMwmIndexGraph. std::unique_ptr m_crossMwmGraph; diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 59e87fe239..e3f048c859 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -109,16 +109,16 @@ template bool FindCrossNode(CrossRoutingContextReader const & currentContext, CrossNode const & crossNode, Node & node) { - double minDistance = std::numeric_limits::max(); + double constexpr kInvalidDistance = std::numeric_limits::max(); + double minDistance = kInvalidDistance; ClosestNodeFinder findingNode(crossNode, minDistance, node); CHECK(ForEachNodeNearPoint(currentContext, crossNode.point, findingNode), ()); - if (minDistance == std::numeric_limits::max()) + if (minDistance == kInvalidDistance) { LOG(LWARNING, ("Cross node is not found. Point:", crossNode.point)); return false; } return true; - } template diff --git a/routing/cross_mwm_road_graph.hpp b/routing/cross_mwm_road_graph.hpp index 9ab7e24c0b..fa9765f557 100644 --- a/routing/cross_mwm_road_graph.hpp +++ b/routing/cross_mwm_road_graph.hpp @@ -18,7 +18,7 @@ namespace routing { /// OSRM graph node representation with graph mwm name and border crossing point. -struct CrossNode +struct CrossNode final { NodeID node; NodeID reverseNode; @@ -65,7 +65,7 @@ inline string DebugPrint(CrossNode const & t) } /// Representation of border crossing. Contains node on previous map and node on next map. -struct BorderCross +struct BorderCross final { CrossNode fromNode; CrossNode toNode; @@ -75,6 +75,7 @@ struct BorderCross // TODO(bykoianko) Consider using fields |fromNode| and |toNode| in operator== and operator<. inline bool operator==(BorderCross const & a) const { return toNode == a.toNode; } + inline bool operator!=(BorderCross const & a) const { return !(*this == a); } inline bool operator<(BorderCross const & a) const { return toNode < a.toNode; } }; @@ -86,31 +87,35 @@ inline string DebugPrint(BorderCross const & t) } /// A class which represents an cross mwm weighted edge used by CrossMwmGraph. -class CrossWeightedEdge +class CrossWeightedEdge final { public: - CrossWeightedEdge(BorderCross const & target, double weight) : target(target), weight(weight) {} - - inline BorderCross const & GetTarget() const { return target; } - inline double GetWeight() const { return weight; } - - inline bool operator==(CrossWeightedEdge const & a) const + CrossWeightedEdge(BorderCross const & target, double weight) : m_target(target), m_weight(weight) { - return target == a.target && weight == a.weight; } - inline bool operator<(CrossWeightedEdge const & a) const + BorderCross const & GetTarget() const { return m_target; } + double GetWeight() const { return m_weight; } + + bool operator==(CrossWeightedEdge const & a) const { - return target < a.target && weight < a.weight; + return m_target == a.m_target && m_weight == a.m_weight; + } + + bool operator<(CrossWeightedEdge const & a) const + { + if (m_target != a.m_target) + return m_target < a.m_target; + return m_weight < a.m_weight; } private: - BorderCross target; - double weight; + BorderCross m_target; + double m_weight; }; /// A graph used for cross mwm routing in an astar algorithms. -class CrossMwmGraph +class CrossMwmGraph final { public: using TCachingKey = pair; @@ -126,7 +131,6 @@ public: }; explicit CrossMwmGraph(RoutingIndexManager & indexManager) : m_indexManager(indexManager) {} - void GetOutgoingEdgesList(BorderCross const & v, vector & adj) const { GetEdgesList(v, true /* isOutgoing */, adj); diff --git a/routing/index_router.cpp b/routing/index_router.cpp index ddda1ecb73..246caba3b0 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -239,8 +239,9 @@ IRouter::ResultCode IndexRouter::ProcessLeaps(vector const & input, CHECK_LESS(i, input.size(), ()); Segment const & next = input[i]; - CHECK_EQUAL(current.GetMwmId(), next.GetMwmId(), - ("Different mwm ids for leap enter and exit, i:", i, "size of input:", input.size())); + CHECK_EQUAL( + current.GetMwmId(), next.GetMwmId(), + ("Different mwm ids for leap enter and exit, i:", i, "size of input:", input.size())); IndexGraphStarter::FakeVertex const start(current, starter.GetPoint(current, true /* front */)); IndexGraphStarter::FakeVertex const finish(next, starter.GetPoint(next, true /* front */)); diff --git a/routing/osrm2feature_map.hpp b/routing/osrm2feature_map.hpp index 1a5a947449..9813743096 100644 --- a/routing/osrm2feature_map.hpp +++ b/routing/osrm2feature_map.hpp @@ -169,7 +169,8 @@ public: /// @note Methods GetSegmentsRange(...) and GetOsrmNodes(...) are not symmetric. /// For example in Tverskay Oblast for node id 161179 two FtSet can be gotten /// with GetSegmentsRange() / GetSegmentByIndex(). - /// But having these segments it's impossible to get node id 161179 with the help of GetOsrmNodes(...). + /// But having these segments it's impossible to get node id 161179 with the help of + /// GetOsrmNodes(...). pair GetSegmentsRange(TOsrmNodeId nodeId) const; /// @return Node id for segment's index. TOsrmNodeId GetNodeId(uint32_t segInd) const; diff --git a/routing/osrm_path_segment_factory.hpp b/routing/osrm_path_segment_factory.hpp index 71e50f45b8..0fbe1b30f4 100644 --- a/routing/osrm_path_segment_factory.hpp +++ b/routing/osrm_path_segment_factory.hpp @@ -9,7 +9,7 @@ struct RawPathData; struct RoutingMapping; // Osrm multiples seconds to 10, so we need to divide it back. -double constexpr kOSRMWeightToSecondsMultiplier = 1. / 10.; +double constexpr kOSRMWeightToSecondsMultiplier = 0.1; // General constructor. void OsrmPathSegmentFactory(RoutingMapping & mapping, Index const & index, diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index 9074cd92a9..15df806f59 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -165,4 +165,12 @@ UNIT_TEST(TestFindingByPoint) TEST(!newContext.ForEachOutgoingNodeNearPoint(p3, fnOutgoing), ()); TEST(outgoingNode.empty(), ()); } +UNIT_TEST(TestCrossWeightedEdgeComparator) +{ + CrossNode const from(0, Index::MwmId(), ms::LatLon::Zero()); + CrossWeightedEdge const lhs(BorderCross(from, {1, Index::MwmId(), ms::LatLon::Zero()}), 2.0); + CrossWeightedEdge const rhs(BorderCross(from, {2, Index::MwmId(), ms::LatLon::Zero()}), 1.0); + + TEST(lhs < rhs || rhs < lhs || lhs == rhs, ()); +} } // namespace diff --git a/routing/segment.hpp b/routing/segment.hpp index 63c67c6195..cd476c7e7b 100644 --- a/routing/segment.hpp +++ b/routing/segment.hpp @@ -37,6 +37,9 @@ public: return m_forward == front ? m_segmentIdx + 1 : m_segmentIdx; } + uint32_t GetMinPointId() const { return m_segmentIdx; } + uint32_t GetMaxPointId() const { return m_segmentIdx + 1; } + RoadPoint GetRoadPoint(bool front) const { return RoadPoint(m_featureId, GetPointId(front)); } bool operator<(Segment const & seg) const @@ -80,7 +83,7 @@ public: return m_target == edge.m_target && m_weight == edge.m_weight; } - bool operator< (SegmentEdge const & edge) const + bool operator<(SegmentEdge const & edge) const { if (m_target != edge.m_target) return m_target < edge.m_target;