diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 62f084bb51..4a6384c701 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -6,8 +6,6 @@ namespace { inline bool IsValidEdgeWeight(EdgeWeight const & w) { return w != INVALID_EDGE_WEIGHT; } - -double constexpr kMwmCrossingNodeEqualityRadiusMeters = 5.0; } namespace routing @@ -181,7 +179,7 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, // Find outs. Generate adjacency list. for (auto outIt = outRange.first; outIt != outRange.second; ++outIt) { - EdgeWeight const outWeight = currentContext.GetAdjacencyCost(inIt, outIt); + EdgeWeight const outWeight = currentContext.GetAdjacencyCost(*inIt, *outIt); if (outWeight != INVALID_CONTEXT_EDGE_WEIGHT && outWeight != 0) { BorderCross target = FindNextMwmNode(*outIt, currentMapping); diff --git a/routing/cross_mwm_road_graph.hpp b/routing/cross_mwm_road_graph.hpp index 8661ce8af9..08c9fa41c7 100644 --- a/routing/cross_mwm_road_graph.hpp +++ b/routing/cross_mwm_road_graph.hpp @@ -19,6 +19,7 @@ struct CrossNode { NodeID node; NodeID reverseNode; + // TODO switch to mwmID string mwmName; m2::PointD point; bool isVirtual; diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index f3230ff1a2..21688093fd 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -24,6 +24,7 @@ size_t OutgoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyInd m_nodeId = *reinterpret_cast(&buff[0]); m_point = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), g_coordBits); m_outgoingIndex = *reinterpret_cast(&(buff[sizeof(m_nodeId) + sizeof(uint64_t)])); + m_adjacencyIndex = adjacencyIndex; return pos + sizeof(buff); } @@ -46,29 +47,20 @@ size_t IngoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyInde return pos + sizeof(buff); } -size_t CrossRoutingContextReader::GetIndexInAdjMatrix(IngoingEdgeIteratorT ingoing, - OutgoingEdgeIteratorT outgoing) const -{ - size_t ingoing_index = distance(m_ingoingNodes.cbegin(), ingoing); - size_t outgoing_index = distance(m_outgoingNodes.cbegin(), outgoing); - ASSERT_LESS(ingoing_index, m_ingoingNodes.size(), ("ingoing index out of range")); - ASSERT_LESS(outgoing_index, m_outgoingNodes.size(), ("outgoing index out of range")); - return m_outgoingNodes.size() * ingoing_index + outgoing_index; -} - void CrossRoutingContextReader::Load(Reader const & r) { size_t pos = 0; - uint32_t size; - r.Read(pos, &size, sizeof(size)); - pos += sizeof(size); + uint32_t size, ingoingSize; + r.Read(pos, &ingoingSize, sizeof(ingoingSize)); + pos += sizeof(ingoingSize); - for (size_t i = 0; i < size; ++i) + for (size_t i = 0; i < ingoingSize; ++i) { IngoingCrossNode node; pos = node.Load(r, pos, i); m_ingoingIndex.Add(node); + m_ingoingNodes.emplace_back(node); } r.Read(pos, &size, sizeof(size)); @@ -78,8 +70,10 @@ void CrossRoutingContextReader::Load(Reader const & r) for (size_t i = 0; i < size; ++i) pos = m_outgoingNodes[i].Load(r, pos, i); - size_t const adjMatrixSize = sizeof(WritedEdgeWeightT) * m_ingoingNodes.size() * m_outgoingNodes.size(); - mp_reader = unique_ptr(r.CreateSubReader(pos, adjMatrixSize)); + size_t adjacencySize = ingoingSize * m_outgoingNodes.size(); + size_t const adjMatrixSize = sizeof(WritedEdgeWeightT) * adjacencySize; + m_adjacencyMatrix.resize(adjacencySize); + r.Read(pos, &m_adjacencyMatrix[0], adjMatrixSize); pos += adjMatrixSize; uint32_t strsize; @@ -130,25 +124,15 @@ pair CrossRoutingContextReader::Ge return make_pair(m_outgoingNodes.cbegin(), m_outgoingNodes.cend()); } -WritedEdgeWeightT CrossRoutingContextReader::GetAdjacencyCost(IngoingEdgeIteratorT ingoing, - OutgoingEdgeIteratorT outgoing) const +WritedEdgeWeightT CrossRoutingContextReader::GetAdjacencyCost(IngoingCrossNode const & ingoing, + OutgoingCrossNode const & outgoing) const { - if (!mp_reader) + if (ingoing.m_adjacencyIndex == kInvalidAdjacencyIndex || + outgoing.m_adjacencyIndex == kInvalidAdjacencyIndex) return INVALID_CONTEXT_EDGE_WEIGHT; - WritedEdgeWeightT result; - mp_reader->Read(GetIndexInAdjMatrix(ingoing, outgoing) * sizeof(WritedEdgeWeightT), &result, - sizeof(WritedEdgeWeightT)); - return result; -} -size_t CrossRoutingContextWriter::GetIndexInAdjMatrix(IngoingEdgeIteratorT ingoing, - OutgoingEdgeIteratorT outgoing) const -{ - size_t ingoing_index = distance(m_ingoingNodes.cbegin(), ingoing); - size_t outgoing_index = distance(m_outgoingNodes.cbegin(), outgoing); - ASSERT_LESS(ingoing_index, m_ingoingNodes.size(), ("ingoing index out of range")); - ASSERT_LESS(outgoing_index, m_outgoingNodes.size(), ("outgoing index out of range")); - return m_outgoingNodes.size() * ingoing_index + outgoing_index; + size_t cost_index = m_outgoingNodes.size() * ingoing.m_adjacencyIndex + outgoing.m_adjacencyIndex; + return cost_index < m_adjacencyMatrix.size() ? m_adjacencyMatrix[cost_index] : INVALID_CONTEXT_EDGE_WEIGHT; } void CrossRoutingContextWriter::Save(Writer & w) const @@ -179,17 +163,18 @@ void CrossRoutingContextWriter::Save(Writer & w) const void CrossRoutingContextWriter::AddIngoingNode(WritedNodeID const nodeId, m2::PointD const & point) { - m_ingoingNodes.push_back(IngoingCrossNode(nodeId, point, kInvalidAdjacencyIndex)); + size_t const adjIndex = m_ingoingNodes.size(); + m_ingoingNodes.emplace_back(nodeId, point, adjIndex); } void CrossRoutingContextWriter::AddOutgoingNode(WritedNodeID const nodeId, string const & targetMwm, m2::PointD const & point) { + size_t const adjIndex = m_outgoingNodes.size(); auto it = find(m_neighborMwmList.begin(), m_neighborMwmList.end(), targetMwm); if (it == m_neighborMwmList.end()) it = m_neighborMwmList.insert(m_neighborMwmList.end(), targetMwm); - m_outgoingNodes.push_back(OutgoingCrossNode(nodeId, distance(m_neighborMwmList.begin(), it), - point, kInvalidAdjacencyIndex)); + m_outgoingNodes.emplace_back(nodeId, distance(m_neighborMwmList.begin(), it), point, adjIndex); } void CrossRoutingContextWriter::ReserveAdjacencyMatrix() @@ -199,10 +184,12 @@ void CrossRoutingContextWriter::ReserveAdjacencyMatrix() } void CrossRoutingContextWriter::SetAdjacencyCost(IngoingEdgeIteratorT ingoing, - OutgoingEdgeIteratorT outgoin, + OutgoingEdgeIteratorT outgoing, WritedEdgeWeightT value) { - m_adjacencyMatrix[GetIndexInAdjMatrix(ingoing, outgoin)] = value; + size_t const index = m_outgoingNodes.size() * ingoing->m_adjacencyIndex + outgoing->m_adjacencyIndex; + ASSERT_LESS(index, m_adjacencyMatrix.size(), ()); + m_adjacencyMatrix[index] = value; } pair CrossRoutingContextWriter::GetIngoingIterators() diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index 63d41944f2..39131fb007 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -79,11 +79,9 @@ class CrossRoutingContextReader vector m_outgoingNodes; vector m_ingoingNodes; vector m_neighborMwmList; - unique_ptr mp_reader = nullptr; + vector m_adjacencyMatrix; m4::Tree m_ingoingIndex; - size_t GetIndexInAdjMatrix(IngoingEdgeIteratorT ingoing, OutgoingEdgeIteratorT outgoing) const; - public: void Load(Reader const & r); @@ -95,8 +93,8 @@ public: pair GetOutgoingIterators() const; - WritedEdgeWeightT GetAdjacencyCost(IngoingEdgeIteratorT ingoing, - OutgoingEdgeIteratorT outgoing) const; + WritedEdgeWeightT GetAdjacencyCost(IngoingCrossNode const & ingoing, + OutgoingCrossNode const & outgoing) const; }; /// Helper class to generate cross context section in mwm.routing file diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index d5f355eb82..1ac0774824 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -96,9 +96,9 @@ UNIT_TEST(TestAdjacencyMatrix) newContext.Load(reader); auto ins = newContext.GetIngoingIterators(); auto outs = newContext.GetOutgoingIterators(); - TEST_EQUAL(newContext.GetAdjacencyCost(ins.first, outs.first), 5, ()); - TEST_EQUAL(newContext.GetAdjacencyCost(ins.first + 1, outs.first), 9, ()); - TEST_EQUAL(newContext.GetAdjacencyCost(ins.first + 2, outs.first), + TEST_EQUAL(newContext.GetAdjacencyCost(*ins.first, *outs.first), 5, ()); + TEST_EQUAL(newContext.GetAdjacencyCost(*(ins.first + 1), *outs.first), 9, ()); + TEST_EQUAL(newContext.GetAdjacencyCost(*(ins.first + 2), *outs.first), routing::INVALID_CONTEXT_EDGE_WEIGHT, ("Default cost")); }