From fc00ee4d41d772204ff60debc3bf5f798549e1ea Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Thu, 22 Oct 2015 17:57:55 +0300 Subject: [PATCH 01/11] Tree index for cross section index finding. --- routing/cross_mwm_road_graph.cpp | 25 +++++++++++-------------- routing/cross_routing_context.cpp | 16 ++++++++++++++++ routing/cross_routing_context.hpp | 7 +++++++ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 49e55c1d55..62f084bb51 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -131,22 +131,19 @@ BorderCross CrossMwmGraph::FindNextMwmNode(OutgoingCrossNode const & startNode, return BorderCross(); nextMapping->LoadCrossContext(); - auto incomeIters = nextMapping->m_crossContext.GetIngoingIterators(); - for (auto i = incomeIters.first; i < incomeIters.second; ++i) + IngoingCrossNode ingoingNode; + if (nextMapping->m_crossContext.FindIngoingNodeByPoint(startPoint, ingoingNode)) { - m2::PointD const & targetPoint = i->m_point; - if (ms::DistanceOnEarth(startPoint.y, startPoint.x, targetPoint.y, targetPoint.x) < - kMwmCrossingNodeEqualityRadiusMeters) - { - BorderCross const cross( - CrossNode(startNode.m_nodeId, currentMapping->GetCountryName(), - MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x)), - CrossNode(i->m_nodeId, nextMwm, - MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x))); - m_cachedNextNodes.insert(make_pair(startPoint, cross)); - return cross; - } + auto const & targetPoint = ingoingNode.m_point; + BorderCross const cross( + CrossNode(startNode.m_nodeId, currentMapping->GetCountryName(), + MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x)), + CrossNode(ingoingNode.m_nodeId, nextMwm, + MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x))); + m_cachedNextNodes.insert(make_pair(startPoint, cross)); + return cross; } + return BorderCross(); } diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 317b854631..3e9e439ea8 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -1,5 +1,6 @@ #include "routing/cross_routing_context.hpp" +#include "indexer/mercator.hpp" #include "indexer/point_to_int64.hpp" namespace routing @@ -65,7 +66,10 @@ void CrossRoutingContextReader::Load(Reader const & r) m_ingoingNodes.resize(size); for (auto & node : m_ingoingNodes) + { pos = node.Load(r, pos); + m_ingoingIndex.Add(node); + } r.Read(pos, &size, sizeof(size)); pos += sizeof(size); @@ -92,6 +96,18 @@ void CrossRoutingContextReader::Load(Reader const & r) } } +bool CrossRoutingContextReader::FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const +{ + bool found = false; + m_ingoingIndex.ForEachInRect(MercatorBounds::RectByCenterXYAndSizeInMeters(point, 5), + [&found, &node](IngoingCrossNode const & nd) + { + node = nd; + found = true; + }); + return found; +} + const string & CrossRoutingContextReader::GetOutgoingMwmName( OutgoingCrossNode const & outgoingNode) const { diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index 8daa188348..87b0d5e29c 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -3,6 +3,8 @@ #include "coding/file_container.hpp" #include "geometry/point2d.hpp" +#include "geometry/rect2d.hpp" +#include "geometry/tree4d.hpp" #include "std/string.hpp" #include "std/vector.hpp" @@ -25,6 +27,8 @@ struct IngoingCrossNode void Save(Writer & w) const; size_t Load(Reader const & r, size_t pos); + + m2::RectD const GetLimitRect() const { return m2::RectD(m_point, m_point); } }; struct OutgoingCrossNode @@ -53,6 +57,7 @@ class CrossRoutingContextReader vector m_outgoingNodes; vector m_neighborMwmList; unique_ptr mp_reader = nullptr; + m4::Tree m_ingoingIndex; size_t GetIndexInAdjMatrix(IngoingEdgeIteratorT ingoing, OutgoingEdgeIteratorT outgoing) const; @@ -63,6 +68,8 @@ public: pair GetIngoingIterators() const; + bool FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const; + pair GetOutgoingIterators() const; WritedEdgeWeightT GetAdjacencyCost(IngoingEdgeIteratorT ingoing, From a6452b96c07b5e9a8c0a796d0b20fda5d4328765 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Fri, 23 Oct 2015 16:12:06 +0300 Subject: [PATCH 02/11] Adjacency indexes inside cross node records. --- routing/cross_routing_context.cpp | 61 ++++++++++++++++++------------- routing/cross_routing_context.hpp | 48 ++++++++++++++++++------ 2 files changed, 71 insertions(+), 38 deletions(-) diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 3e9e439ea8..f3230ff1a2 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -5,10 +5,9 @@ namespace routing { - static uint32_t const g_coordBits = POINT_COORD_BITS; -void OutgoingCrossNode::Save(Writer &w) const +void OutgoingCrossNode::Save(Writer & w) const { uint64_t point = PointToInt64(m_point, g_coordBits); char buff[sizeof(m_nodeId) + sizeof(point) + sizeof(m_outgoingIndex)]; @@ -16,10 +15,9 @@ void OutgoingCrossNode::Save(Writer &w) const *reinterpret_cast(&(buff[sizeof(m_nodeId)])) = point; *reinterpret_cast(&(buff[sizeof(m_nodeId) + sizeof(point)])) = m_outgoingIndex; w.Write(buff, sizeof(buff)); - } -size_t OutgoingCrossNode::Load(const Reader &r, size_t pos) +size_t OutgoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyIndex) { char buff[sizeof(m_nodeId) + sizeof(uint64_t) + sizeof(m_outgoingIndex)]; r.Read(pos, buff, sizeof(buff)); @@ -29,7 +27,7 @@ size_t OutgoingCrossNode::Load(const Reader &r, size_t pos) return pos + sizeof(buff); } -void IngoingCrossNode::Save(Writer &w) const +void IngoingCrossNode::Save(Writer & w) const { uint64_t point = PointToInt64(m_point, g_coordBits); char buff[sizeof(m_nodeId) + sizeof(point)]; @@ -38,16 +36,18 @@ void IngoingCrossNode::Save(Writer &w) const w.Write(buff, sizeof(buff)); } -size_t IngoingCrossNode::Load(const Reader &r, size_t pos) +size_t IngoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyIndex) { char buff[sizeof(m_nodeId) + sizeof(uint64_t)]; r.Read(pos, buff, sizeof(buff)); m_nodeId = *reinterpret_cast(&buff[0]); m_point = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), g_coordBits); + m_adjacencyIndex = adjacencyIndex; return pos + sizeof(buff); } -size_t CrossRoutingContextReader::GetIndexInAdjMatrix(IngoingEdgeIteratorT ingoing, OutgoingEdgeIteratorT outgoing) const +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); @@ -63,11 +63,11 @@ void CrossRoutingContextReader::Load(Reader const & r) uint32_t size; r.Read(pos, &size, sizeof(size)); pos += sizeof(size); - m_ingoingNodes.resize(size); - for (auto & node : m_ingoingNodes) + for (size_t i = 0; i < size; ++i) { - pos = node.Load(r, pos); + IngoingCrossNode node; + pos = node.Load(r, pos, i); m_ingoingIndex.Add(node); } @@ -75,8 +75,8 @@ void CrossRoutingContextReader::Load(Reader const & r) pos += sizeof(size); m_outgoingNodes.resize(size); - for (auto & node : m_outgoingNodes) - pos = node.Load(r, pos); + 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)); @@ -96,15 +96,16 @@ void CrossRoutingContextReader::Load(Reader const & r) } } -bool CrossRoutingContextReader::FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const +bool CrossRoutingContextReader::FindIngoingNodeByPoint(m2::PointD const & point, + IngoingCrossNode & node) const { bool found = false; - m_ingoingIndex.ForEachInRect(MercatorBounds::RectByCenterXYAndSizeInMeters(point, 5), + m_ingoingIndex.ForEachInRect(MercatorBounds::RectByCenterXYAndSizeInMeters(point, 5), [&found, &node](IngoingCrossNode const & nd) { node = nd; found = true; - }); + }); return found; } @@ -117,12 +118,14 @@ const string & CrossRoutingContextReader::GetOutgoingMwmName( return m_neighborMwmList[outgoingNode.m_outgoingIndex]; } -pair CrossRoutingContextReader::GetIngoingIterators() const +pair CrossRoutingContextReader::GetIngoingIterators() + const { return make_pair(m_ingoingNodes.cbegin(), m_ingoingNodes.cend()); } -pair CrossRoutingContextReader::GetOutgoingIterators() const +pair CrossRoutingContextReader::GetOutgoingIterators() + const { return make_pair(m_outgoingNodes.cbegin(), m_outgoingNodes.cend()); } @@ -133,11 +136,13 @@ WritedEdgeWeightT CrossRoutingContextReader::GetAdjacencyCost(IngoingEdgeIterato if (!mp_reader) return INVALID_CONTEXT_EDGE_WEIGHT; WritedEdgeWeightT result; - mp_reader->Read(GetIndexInAdjMatrix(ingoing, outgoing) * sizeof(WritedEdgeWeightT), &result, sizeof(WritedEdgeWeightT)); + mp_reader->Read(GetIndexInAdjMatrix(ingoing, outgoing) * sizeof(WritedEdgeWeightT), &result, + sizeof(WritedEdgeWeightT)); return result; } -size_t CrossRoutingContextWriter::GetIndexInAdjMatrix(IngoingEdgeIteratorT ingoing, OutgoingEdgeIteratorT outgoing) const +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); @@ -159,12 +164,12 @@ void CrossRoutingContextWriter::Save(Writer & w) const for (auto const & node : m_outgoingNodes) node.Save(w); - CHECK(m_adjacencyMatrix.size() == m_outgoingNodes.size()*m_ingoingNodes.size(), ()); + CHECK(m_adjacencyMatrix.size() == m_outgoingNodes.size() * m_ingoingNodes.size(), ()); w.Write(&m_adjacencyMatrix[0], sizeof(m_adjacencyMatrix[0]) * m_adjacencyMatrix.size()); size = static_cast(m_neighborMwmList.size()); w.Write(&size, sizeof(size)); - for (string const & neighbor: m_neighborMwmList) + for (string const & neighbor : m_neighborMwmList) { size = static_cast(neighbor.size()); w.Write(&size, sizeof(size)); @@ -174,7 +179,7 @@ void CrossRoutingContextWriter::Save(Writer & w) const void CrossRoutingContextWriter::AddIngoingNode(WritedNodeID const nodeId, m2::PointD const & point) { - m_ingoingNodes.push_back(IngoingCrossNode(nodeId, point)); + m_ingoingNodes.push_back(IngoingCrossNode(nodeId, point, kInvalidAdjacencyIndex)); } void CrossRoutingContextWriter::AddOutgoingNode(WritedNodeID const nodeId, string const & targetMwm, @@ -183,12 +188,14 @@ void CrossRoutingContextWriter::AddOutgoingNode(WritedNodeID const nodeId, strin 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)); + m_outgoingNodes.push_back(OutgoingCrossNode(nodeId, distance(m_neighborMwmList.begin(), it), + point, kInvalidAdjacencyIndex)); } void CrossRoutingContextWriter::ReserveAdjacencyMatrix() { - m_adjacencyMatrix.resize(m_ingoingNodes.size() * m_outgoingNodes.size(), INVALID_CONTEXT_EDGE_WEIGHT); + m_adjacencyMatrix.resize(m_ingoingNodes.size() * m_outgoingNodes.size(), + INVALID_CONTEXT_EDGE_WEIGHT); } void CrossRoutingContextWriter::SetAdjacencyCost(IngoingEdgeIteratorT ingoing, @@ -198,12 +205,14 @@ void CrossRoutingContextWriter::SetAdjacencyCost(IngoingEdgeIteratorT ingoing, m_adjacencyMatrix[GetIndexInAdjMatrix(ingoing, outgoin)] = value; } -pair CrossRoutingContextWriter::GetIngoingIterators() const +pair CrossRoutingContextWriter::GetIngoingIterators() + const { return make_pair(m_ingoingNodes.cbegin(), m_ingoingNodes.cend()); } -pair CrossRoutingContextWriter::GetOutgoingIterators() const +pair CrossRoutingContextWriter::GetOutgoingIterators() + const { return make_pair(m_outgoingNodes.cbegin(), m_outgoingNodes.cend()); } diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index 87b0d5e29c..63d41944f2 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -11,22 +11,33 @@ namespace routing { +// TODO (ldragunov) Fix this!!!! using WritedNodeID = uint32_t; using WritedEdgeWeightT = uint32_t; static WritedEdgeWeightT const INVALID_CONTEXT_EDGE_WEIGHT = std::numeric_limits::max(); static WritedEdgeWeightT const INVALID_CONTEXT_EDGE_NODE_ID = std::numeric_limits::max(); +static size_t constexpr kInvalidAdjacencyIndex = numeric_limits::max(); struct IngoingCrossNode { m2::PointD m_point; WritedNodeID m_nodeId; + size_t m_adjacencyIndex; - IngoingCrossNode() : m_point(m2::PointD::Zero()), m_nodeId(INVALID_CONTEXT_EDGE_NODE_ID) {} - IngoingCrossNode(WritedNodeID nodeId, m2::PointD const & point) :m_point(point), m_nodeId(nodeId) {} + IngoingCrossNode() + : m_point(m2::PointD::Zero()) + , m_nodeId(INVALID_CONTEXT_EDGE_NODE_ID) + , m_adjacencyIndex(kInvalidAdjacencyIndex) + { + } + IngoingCrossNode(WritedNodeID nodeId, m2::PointD const & point, size_t const adjacencyIndex) + : m_point(point), m_nodeId(nodeId), m_adjacencyIndex(adjacencyIndex) + { + } void Save(Writer & w) const; - size_t Load(Reader const & r, size_t pos); + size_t Load(Reader const & r, size_t pos, size_t adjacencyIndex); m2::RectD const GetLimitRect() const { return m2::RectD(m_point, m_point); } }; @@ -36,15 +47,27 @@ struct OutgoingCrossNode m2::PointD m_point; WritedNodeID m_nodeId; unsigned char m_outgoingIndex; + size_t m_adjacencyIndex; - OutgoingCrossNode() : m_point(m2::PointD::Zero()), m_nodeId(INVALID_CONTEXT_EDGE_NODE_ID), m_outgoingIndex(0) {} - OutgoingCrossNode(WritedNodeID nodeId, size_t const index, m2::PointD const & point) : m_point(point), - m_nodeId(nodeId), - m_outgoingIndex(static_cast(index)){} + OutgoingCrossNode() + : m_point(m2::PointD::Zero()) + , m_nodeId(INVALID_CONTEXT_EDGE_NODE_ID) + , m_outgoingIndex(0) + , m_adjacencyIndex(kInvalidAdjacencyIndex) + { + } + OutgoingCrossNode(WritedNodeID nodeId, size_t const index, m2::PointD const & point, + size_t const adjacencyIndex) + : m_point(point) + , m_nodeId(nodeId) + , m_outgoingIndex(static_cast(index)) + , m_adjacencyIndex(adjacencyIndex) + { + } void Save(Writer & w) const; - size_t Load(Reader const & r, size_t pos); + size_t Load(Reader const & r, size_t pos, size_t adjacencyIndex); }; using IngoingEdgeIteratorT = vector::const_iterator; @@ -53,22 +76,22 @@ using OutgoingEdgeIteratorT = vector::const_iterator; /// Reader class from cross context section in mwm.routing file class CrossRoutingContextReader { - vector m_ingoingNodes; vector m_outgoingNodes; + vector m_ingoingNodes; vector m_neighborMwmList; unique_ptr mp_reader = nullptr; m4::Tree m_ingoingIndex; size_t GetIndexInAdjMatrix(IngoingEdgeIteratorT ingoing, OutgoingEdgeIteratorT outgoing) const; -public: +public: void Load(Reader const & r); const string & GetOutgoingMwmName(OutgoingCrossNode const & mwmIndex) const; pair GetIngoingIterators() const; - bool FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const; + bool FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const; pair GetOutgoingIterators() const; @@ -91,7 +114,8 @@ public: void AddIngoingNode(WritedNodeID const nodeId, m2::PointD const & point); - void AddOutgoingNode(WritedNodeID const nodeId, string const & targetMwm, m2::PointD const & point); + void AddOutgoingNode(WritedNodeID const nodeId, string const & targetMwm, + m2::PointD const & point); void ReserveAdjacencyMatrix(); From b9349c6ece8459d4849d2715cf228cd046b41d67 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Mon, 26 Oct 2015 13:58:02 +0300 Subject: [PATCH 03/11] Use absolute parametrs in the GetAdjacencyCost function. --- routing/cross_mwm_road_graph.cpp | 4 +- routing/cross_mwm_road_graph.hpp | 1 + routing/cross_routing_context.cpp | 61 ++++++++----------- routing/cross_routing_context.hpp | 8 +-- routing/routing_tests/cross_routing_tests.cpp | 6 +- 5 files changed, 32 insertions(+), 48 deletions(-) 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")); } From 4f3964bd76d5739b33bca3d99986b97503319384 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Mon, 26 Oct 2015 16:38:38 +0300 Subject: [PATCH 04/11] Remove IngoingCrossNode duplication inside a CrossRoutingContext class. --- routing/cross_mwm_road_graph.cpp | 53 +++++++++++-------- routing/cross_mwm_router.hpp | 8 +-- routing/cross_routing_context.cpp | 15 +++--- routing/cross_routing_context.hpp | 5 +- routing/osrm_router.cpp | 33 +----------- .../cross_section_tests.cpp | 9 ++-- routing/routing_tests/cross_routing_tests.cpp | 18 ++++--- 7 files changed, 64 insertions(+), 77 deletions(-) diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 4a6384c701..fc28bd4cc1 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -72,25 +72,26 @@ IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode) finalMapping->LoadCrossContext(); // Load source data. - auto const mwmIngoingIter = finalMapping->m_crossContext.GetIngoingIterators(); - // Generate routing task from one source to several targets. - TRoutingNodes sources, targets(1); - size_t const ingoingSize = distance(mwmIngoingIter.first, mwmIngoingIter.second); - sources.reserve(ingoingSize); - + vector ingoingNodes; + finalMapping->m_crossContext.GetAllIngoingNodes(ingoingNodes); + size_t const ingoingSize = ingoingNodes.size(); // If there is no routes inside target map. - if (!ingoingSize) + if (ingoingSize == 0) return IRouter::RouteNotFound; - for (auto j = mwmIngoingIter.first; j != mwmIngoingIter.second; ++j) + // Generate routing task from one source to several targets. + TRoutingNodes sources, targets(1); + sources.reserve(ingoingSize); + + for (auto const & node : ingoingNodes) { // Case with a target node at the income mwm node. - if (j->m_nodeId == finalNode.node) + if (node.m_nodeId == finalNode.node) { - AddVirtualEdge(*j, finalNode, 0 /* no weight */); + AddVirtualEdge(node, finalNode, 0 /* no weight */); return IRouter::NoError; } - sources.emplace_back(j->m_nodeId, true /* isStartNode */, finalNode.mwmName); + sources.emplace_back(node.m_nodeId, true /* isStartNode */, finalNode.mwmName); } vector weights; @@ -103,7 +104,7 @@ IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode) { if (IsValidEdgeWeight(weights[i])) { - AddVirtualEdge(*(mwmIngoingIter.first + i), finalNode, weights[i]); + AddVirtualEdge(ingoingNodes[i], finalNode, weights[i]); } } return IRouter::NoError; @@ -164,22 +165,31 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, currentMapping->FreeFileIfPossible(); CrossRoutingContextReader const & currentContext = currentMapping->m_crossContext; - auto inRange = currentContext.GetIngoingIterators(); auto outRange = currentContext.GetOutgoingIterators(); // Find income node. - auto inIt = inRange.first; - while (inIt != inRange.second) + IngoingCrossNode ingoingNode; + bool found = currentContext.FindIngoingNodeByPoint({MercatorBounds::XToLon(v.toNode.point.x), MercatorBounds::YToLat(v.toNode.point.y)}, ingoingNode); + CHECK(found, (m2::PointD(MercatorBounds::XToLon(v.toNode.point.x), MercatorBounds::YToLat(v.toNode.point.y)))); + if (ingoingNode.m_nodeId != v.toNode.node) { - if (inIt->m_nodeId == v.toNode.node) - break; - ++inIt; + LOG(LDEBUG, ("Several nodes stores in one border point.", m2::PointD(MercatorBounds::XToLon(v.toNode.point.x), MercatorBounds::YToLat(v.toNode.point.y)))); + vector ingoingNodes; + currentContext.GetAllIngoingNodes(ingoingNodes); + for(auto const & node : ingoingNodes) + { + if (node.m_nodeId == v.toNode.node) + { + ingoingNode = node; + break; + } + } } - CHECK(inIt != inRange.second, ()); + // 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(ingoingNode, *outIt); if (outWeight != INVALID_CONTEXT_EDGE_WEIGHT && outWeight != 0) { BorderCross target = FindNextMwmNode(*outIt, currentMapping); @@ -204,7 +214,8 @@ void ConvertToSingleRouterTasks(vector const & graphCrosses, for (size_t i = 0; i + 1 < graphCrosses.size(); ++i) { ASSERT_EQUAL(graphCrosses[i].toNode.mwmName, graphCrosses[i + 1].fromNode.mwmName, ()); - route.emplace_back(graphCrosses[i].toNode.node, graphCrosses[i + 1].fromNode.node, + route.emplace_back(graphCrosses[i].toNode.node, graphCrosses[i].toNode.point, + graphCrosses[i + 1].fromNode.node, graphCrosses[i + 1].fromNode.point, graphCrosses[i].toNode.mwmName); } diff --git a/routing/cross_mwm_router.hpp b/routing/cross_mwm_router.hpp index 6df20a05ea..71f75ce029 100644 --- a/routing/cross_mwm_router.hpp +++ b/routing/cross_mwm_router.hpp @@ -17,10 +17,12 @@ struct RoutePathCross FeatureGraphNode startNode; /**< start graph node representation */ FeatureGraphNode finalNode; /**< end graph node representation */ - RoutePathCross(NodeID const startNode, NodeID const finalNode, string const & name) - : startNode(startNode, true /* isStartNode */, name), - finalNode(finalNode, false /* isStartNode*/, name) + RoutePathCross(NodeID const startNodeId, m2::PointD const & startPoint, NodeID const finalNodeId, m2::PointD const & finalPoint, string const & name) + : startNode(startNodeId, true /* isStartNode */, name), + finalNode(finalNodeId, false /* isStartNode*/, name) { + startNode.segmentPoint = startPoint; + finalNode.segmentPoint = finalPoint; } }; diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 21688093fd..57739618e2 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -60,7 +60,6 @@ void CrossRoutingContextReader::Load(Reader const & r) IngoingCrossNode node; pos = node.Load(r, pos, i); m_ingoingIndex.Add(node); - m_ingoingNodes.emplace_back(node); } r.Read(pos, &size, sizeof(size)); @@ -112,12 +111,6 @@ const string & CrossRoutingContextReader::GetOutgoingMwmName( return m_neighborMwmList[outgoingNode.m_outgoingIndex]; } -pair CrossRoutingContextReader::GetIngoingIterators() - const -{ - return make_pair(m_ingoingNodes.cbegin(), m_ingoingNodes.cend()); -} - pair CrossRoutingContextReader::GetOutgoingIterators() const { @@ -135,6 +128,14 @@ WritedEdgeWeightT CrossRoutingContextReader::GetAdjacencyCost(IngoingCrossNode c return cost_index < m_adjacencyMatrix.size() ? m_adjacencyMatrix[cost_index] : INVALID_CONTEXT_EDGE_WEIGHT; } +void CrossRoutingContextReader::GetAllIngoingNodes(vector & nodes) const +{ + m_ingoingIndex.ForEach([&nodes](IngoingCrossNode const & node) + { + nodes.push_back(node); + }); +} + void CrossRoutingContextWriter::Save(Writer & w) const { uint32_t size = static_cast(m_ingoingNodes.size()); diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index 39131fb007..a17fff673b 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -77,7 +77,6 @@ using OutgoingEdgeIteratorT = vector::const_iterator; class CrossRoutingContextReader { vector m_outgoingNodes; - vector m_ingoingNodes; vector m_neighborMwmList; vector m_adjacencyMatrix; m4::Tree m_ingoingIndex; @@ -87,14 +86,14 @@ public: const string & GetOutgoingMwmName(OutgoingCrossNode const & mwmIndex) const; - pair GetIngoingIterators() const; - bool FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const; pair GetOutgoingIterators() const; WritedEdgeWeightT GetAdjacencyCost(IngoingCrossNode const & ingoing, OutgoingCrossNode const & outgoing) const; + + void GetAllIngoingNodes(vector & nodes) const; }; /// Helper class to generate cross context section in mwm.routing file diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index 80d9607637..92d31da77a 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -149,38 +149,7 @@ void CalculatePhantomNodeForCross(TRoutingMappingPtr & mapping, FeatureGraphNode CHECK_NOT_EQUAL(nodeId, INVALID_NODE_ID, ()); - mapping->LoadCrossContext(); - MappingGuard guard(mapping); - UNUSED_VALUE(guard); - - m2::PointD point = m2::PointD::Zero(); - if (forward) - { - auto inIters = mapping->m_crossContext.GetIngoingIterators(); - for (auto iter = inIters.first; iter != inIters.second; ++iter) - { - if (iter->m_nodeId != nodeId) - continue; - point = iter->m_point; - break; - } - } - else - { - auto outIters = mapping->m_crossContext.GetOutgoingIterators(); - for (auto iter = outIters.first; iter != outIters.second; ++iter) - { - if (iter->m_nodeId != nodeId) - continue; - point = iter->m_point; - break; - } - } - - CHECK(!point.IsAlmostZero(), ()); - - FindGraphNodeOffsets(nodeId, MercatorBounds::FromLatLon(point.y, point.x), - pIndex, mapping, graphNode); + FindGraphNodeOffsets(nodeId, graphNode.segmentPoint, pIndex, mapping, graphNode); } // TODO (ldragunov) move this function to cross mwm router diff --git a/routing/routing_integration_tests/cross_section_tests.cpp b/routing/routing_integration_tests/cross_section_tests.cpp index 7d1232e648..af364aee2f 100644 --- a/routing/routing_integration_tests/cross_section_tests.cpp +++ b/routing/routing_integration_tests/cross_section_tests.cpp @@ -38,15 +38,18 @@ UNIT_TEST(CheckCrossSections) } FilesMappingContainer container(file.GetPath(MapOptions::CarRouting)); crossReader.Load(container.GetReader(ROUTING_CROSS_CONTEXT_TAG)); - auto ingoing = crossReader.GetIngoingIterators(); - for (auto i = ingoing.first; i != ingoing.second; ++i) + + vector ingoingNodes; + crossReader.GetAllIngoingNodes(ingoingNodes); + for (auto const & node : ingoingNodes) { - if (i->m_point.EqualDxDy(kZeroPoint, kPointEquality)) + if (node.m_point.EqualDxDy(kZeroPoint, kPointEquality)) { ingoingErrors++; break; } } + auto outgoing = crossReader.GetOutgoingIterators(); for (auto i = outgoing.first; i != outgoing.second; ++i) { diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index 1ac0774824..0114c833df 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -56,10 +56,11 @@ UNIT_TEST(TestContextSerialization) MemReader reader(buffer.data(), buffer.size()); newContext.Load(reader); - auto ins = newContext.GetIngoingIterators(); - TEST_EQUAL(distance(ins.first,ins.second), 2, ()); - TEST_EQUAL(ins.first->m_nodeId, 1, ()); - TEST_EQUAL((++ins.first)->m_nodeId, 2, ()); + vector ingoingNodes; + newContext.GetAllIngoingNodes(ingoingNodes); + TEST_EQUAL(ingoingNodes.size(), 2, ()); + TEST_EQUAL(ingoingNodes[0].m_nodeId, 1, ()); + TEST_EQUAL(ingoingNodes[1].m_nodeId, 2, ()); auto outs = newContext.GetOutgoingIterators(); TEST_EQUAL(distance(outs.first,outs.second), 2, ()); @@ -94,11 +95,12 @@ UNIT_TEST(TestAdjacencyMatrix) MemReader reader(buffer.data(), buffer.size()); newContext.Load(reader); - auto ins = newContext.GetIngoingIterators(); + vector ingoingNodes; + newContext.GetAllIngoingNodes(ingoingNodes); 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(ingoingNodes[0], *outs.first), 5, ()); + TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[1], *outs.first), 9, ()); + TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[2], *outs.first), routing::INVALID_CONTEXT_EDGE_WEIGHT, ("Default cost")); } From ba3db415505896e05a45c0daa6a0fef1678c9a86 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Tue, 27 Oct 2015 12:03:43 +0300 Subject: [PATCH 05/11] GetAllOutgoingCrossNodes refactoring. --- routing/cross_mwm_road_graph.cpp | 25 ++++++++++++------- routing/cross_routing_context.cpp | 13 +++++----- routing/cross_routing_context.hpp | 3 +-- .../cross_section_tests.cpp | 6 ++--- routing/routing_tests/cross_routing_tests.cpp | 23 +++++++++-------- 5 files changed, 39 insertions(+), 31 deletions(-) diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index fc28bd4cc1..44f52caf55 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -20,8 +20,9 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) startMapping->LoadCrossContext(); // Load source data. - auto const mwmOutsIter = startMapping->m_crossContext.GetOutgoingIterators(); - size_t const outSize = distance(mwmOutsIter.first, mwmOutsIter.second); + vector outgoingNodes; + startMapping->m_crossContext.GetAllOutgoingNodes(outgoingNodes); + size_t const outSize = outgoingNodes.size(); // Can't find the route if there are no routes outside source map. if (!outSize) return IRouter::RouteNotFound; @@ -29,8 +30,11 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) // Generate routing task from one source to several targets. TRoutingNodes sources(1), targets; targets.reserve(outSize); - for (auto j = mwmOutsIter.first; j < mwmOutsIter.second; ++j) - targets.emplace_back(j->m_nodeId, false /* isStartNode */, startNode.mwmName); + for (auto const & node : outgoingNodes) + { + targets.emplace_back(node.m_nodeId, false /* isStartNode */, startNode.mwmName); + targets.back().segmentPoint = node.m_point; + } sources[0] = FeatureGraphNode(startNode.node, startNode.reverseNode, true /* isStartNode */, startNode.mwmName); @@ -43,7 +47,7 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) { if (IsValidEdgeWeight(weights[i])) { - BorderCross nextNode = FindNextMwmNode(*(mwmOutsIter.first + i), startMapping); + BorderCross nextNode = FindNextMwmNode(outgoingNodes[i], startMapping); if (nextNode.toNode.IsValid()) dummyEdges.emplace_back(nextNode, weights[i]); } @@ -92,6 +96,7 @@ IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode) return IRouter::NoError; } sources.emplace_back(node.m_nodeId, true /* isStartNode */, finalNode.mwmName); + sources.back().segmentPoint = node.m_point; } vector weights; @@ -165,7 +170,6 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, currentMapping->FreeFileIfPossible(); CrossRoutingContextReader const & currentContext = currentMapping->m_crossContext; - auto outRange = currentContext.GetOutgoingIterators(); // Find income node. IngoingCrossNode ingoingNode; @@ -186,13 +190,16 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, } } + vector outgoingNodes; + currentContext.GetAllOutgoingNodes(outgoingNodes); + // Find outs. Generate adjacency list. - for (auto outIt = outRange.first; outIt != outRange.second; ++outIt) + for (auto const & node : outgoingNodes) { - EdgeWeight const outWeight = currentContext.GetAdjacencyCost(ingoingNode, *outIt); + EdgeWeight const outWeight = currentContext.GetAdjacencyCost(ingoingNode, node); if (outWeight != INVALID_CONTEXT_EDGE_WEIGHT && outWeight != 0) { - BorderCross target = FindNextMwmNode(*outIt, currentMapping); + BorderCross target = FindNextMwmNode(node, currentMapping); if (target.toNode.IsValid()) adj.emplace_back(target, outWeight); } diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 57739618e2..4d3a7c5885 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -111,12 +111,6 @@ const string & CrossRoutingContextReader::GetOutgoingMwmName( return m_neighborMwmList[outgoingNode.m_outgoingIndex]; } -pair CrossRoutingContextReader::GetOutgoingIterators() - const -{ - return make_pair(m_outgoingNodes.cbegin(), m_outgoingNodes.cend()); -} - WritedEdgeWeightT CrossRoutingContextReader::GetAdjacencyCost(IngoingCrossNode const & ingoing, OutgoingCrossNode const & outgoing) const { @@ -136,6 +130,13 @@ void CrossRoutingContextReader::GetAllIngoingNodes(vector & no }); } +// It is not absolutelty effective, because we plan to change internal storage to avoid backward A* +// So we can't just return a reference. +void CrossRoutingContextReader::GetAllOutgoingNodes(vector & nodes) const +{ + nodes = m_outgoingNodes; +} + void CrossRoutingContextWriter::Save(Writer & w) const { uint32_t size = static_cast(m_ingoingNodes.size()); diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index a17fff673b..428d2f74af 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -88,12 +88,11 @@ public: bool FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const; - pair GetOutgoingIterators() const; - WritedEdgeWeightT GetAdjacencyCost(IngoingCrossNode const & ingoing, OutgoingCrossNode const & outgoing) const; void GetAllIngoingNodes(vector & nodes) const; + void GetAllOutgoingNodes(vector & nodes) const; }; /// Helper class to generate cross context section in mwm.routing file diff --git a/routing/routing_integration_tests/cross_section_tests.cpp b/routing/routing_integration_tests/cross_section_tests.cpp index af364aee2f..87e1a5f1a6 100644 --- a/routing/routing_integration_tests/cross_section_tests.cpp +++ b/routing/routing_integration_tests/cross_section_tests.cpp @@ -50,10 +50,10 @@ UNIT_TEST(CheckCrossSections) } } - auto outgoing = crossReader.GetOutgoingIterators(); - for (auto i = outgoing.first; i != outgoing.second; ++i) + vector outgoingNodes; + for (auto const & node : outgoingNodes) { - if (i->m_point.EqualDxDy(kZeroPoint, kPointEquality)) + if (node.m_point.EqualDxDy(kZeroPoint, kPointEquality)) { outgoingErrors++; break; diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index 0114c833df..4c8fe6df92 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -62,13 +62,13 @@ UNIT_TEST(TestContextSerialization) TEST_EQUAL(ingoingNodes[0].m_nodeId, 1, ()); TEST_EQUAL(ingoingNodes[1].m_nodeId, 2, ()); - auto outs = newContext.GetOutgoingIterators(); - TEST_EQUAL(distance(outs.first,outs.second), 2, ()); - TEST_EQUAL(outs.first->m_nodeId, 3, ()); - TEST_EQUAL(newContext.GetOutgoingMwmName(*outs.first), string("foo"), ()); - ++outs.first; - TEST_EQUAL(outs.first->m_nodeId, 4, ()); - TEST_EQUAL(newContext.GetOutgoingMwmName(*outs.first), string("bar"), ()); + vector outgoingNodes; + newContext.GetAllOutgoingNodes(outgoingNodes); + TEST_EQUAL(outgoingNodes.size(), 2, ()); + TEST_EQUAL(outgoingNodes[0].m_nodeId, 3, ()); + TEST_EQUAL(newContext.GetOutgoingMwmName(outgoingNodes[0]), string("foo"), ()); + TEST_EQUAL(outgoingNodes[1].m_nodeId, 4, ()); + TEST_EQUAL(newContext.GetOutgoingMwmName(outgoingNodes[1]), string("bar"), ()); } UNIT_TEST(TestAdjacencyMatrix) @@ -97,10 +97,11 @@ UNIT_TEST(TestAdjacencyMatrix) newContext.Load(reader); vector ingoingNodes; newContext.GetAllIngoingNodes(ingoingNodes); - auto outs = newContext.GetOutgoingIterators(); - TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[0], *outs.first), 5, ()); - TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[1], *outs.first), 9, ()); - TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[2], *outs.first), + vector outgoingNodes; + newContext.GetAllOutgoingNodes(outgoingNodes); + TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[0], outgoingNodes[0]), 5, ()); + TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[1], outgoingNodes[0]), 9, ()); + TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[2], outgoingNodes[0]), routing::INVALID_CONTEXT_EDGE_WEIGHT, ("Default cost")); } From 17f7099da64a8e0a891dbcbfc516218deecbef86 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Tue, 27 Oct 2015 16:25:30 +0300 Subject: [PATCH 06/11] Using LatLon for WGS coordinates in cross routing. --- generator/routing_generator.cpp | 6 ++--- geometry/latlon.hpp | 25 ++++++++++++++++- routing/cross_mwm_road_graph.cpp | 27 +++++++++---------- routing/cross_mwm_road_graph.hpp | 11 ++++---- routing/cross_mwm_router.cpp | 6 ++--- routing/cross_routing_context.cpp | 18 +++++++------ routing/cross_routing_context.hpp | 21 ++++++++------- .../cross_section_tests.cpp | 5 ++-- routing/routing_tests/cross_routing_tests.cpp | 16 +++++------ 9 files changed, 80 insertions(+), 55 deletions(-) diff --git a/generator/routing_generator.cpp b/generator/routing_generator.cpp index 053fe02aaa..2da32ee52c 100644 --- a/generator/routing_generator.cpp +++ b/generator/routing_generator.cpp @@ -128,9 +128,9 @@ void FindCrossNodes(osrm::NodeDataVectorT const & nodeData, gen::OsmID2FeatureID continue; } // for old format compatibility - intersection = m2::PointD(MercatorBounds::XToLon(intersection.x), MercatorBounds::YToLat(intersection.y)); + ms::LatLon wgsIntersection = ms::LatLon(MercatorBounds::ToLatLon(intersection)); if (!outStart && outEnd) - crossContext.AddIngoingNode(nodeId, intersection); + crossContext.AddIngoingNode(nodeId, wgsIntersection); else if (outStart && !outEnd) { string mwmName; @@ -147,7 +147,7 @@ void FindCrossNodes(osrm::NodeDataVectorT const & nodeData, gen::OsmID2FeatureID }); }); if (!mwmName.empty()) - crossContext.AddOutgoingNode(nodeId, mwmName, intersection); + crossContext.AddOutgoingNode(nodeId, mwmName, wgsIntersection); else LOG(LINFO, ("Unknowing outgoing edge", endSeg.lat2, endSeg.lon2, startSeg.lat1, startSeg.lon1)); } diff --git a/geometry/latlon.hpp b/geometry/latlon.hpp index d5512993f6..4d5d105c29 100644 --- a/geometry/latlon.hpp +++ b/geometry/latlon.hpp @@ -1,5 +1,7 @@ #pragma once +#include "base/math.hpp" + #include "std/string.hpp" namespace ms @@ -9,8 +11,29 @@ namespace ms class LatLon { public: - LatLon(double lat, double lon) : lat(lat), lon(lon) {} double lat, lon; + + LatLon(double lat, double lon) : lat(lat), lon(lon) {} + + static LatLon Zero() { return LatLon(0., 0.); } + + bool operator == (ms::LatLon const & p) const + { + return lat == p.lat && lon == p.lon; + } + + bool EqualDxDy(LatLon const & p, double eps) const + { + return ((fabs(lat - p.lat) < eps) && (fabs(lon - p.lon) < eps)); + } + + struct Hash + { + size_t operator()(ms::LatLon const & p) const + { + return my::Hash(p.lat, p.lon); + } + }; }; string DebugPrint(LatLon const & t); diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 44f52caf55..950229fc34 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -33,7 +33,7 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) for (auto const & node : outgoingNodes) { targets.emplace_back(node.m_nodeId, false /* isStartNode */, startNode.mwmName); - targets.back().segmentPoint = node.m_point; + targets.back().segmentPoint = MercatorBounds::FromLatLon(node.m_point); } sources[0] = FeatureGraphNode(startNode.node, startNode.reverseNode, true /* isStartNode */, startNode.mwmName); @@ -60,8 +60,7 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) void CrossMwmGraph::AddVirtualEdge(IngoingCrossNode const & node, CrossNode const & finalNode, EdgeWeight weight) { - CrossNode start(node.m_nodeId, finalNode.mwmName, - MercatorBounds::FromLatLon(node.m_point.y, node.m_point.x)); + CrossNode start(node.m_nodeId, finalNode.mwmName, node.m_point); vector dummyEdges; dummyEdges.emplace_back(BorderCross(finalNode, finalNode), weight); m_virtualEdges.insert(make_pair(start, dummyEdges)); @@ -96,7 +95,7 @@ IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode) return IRouter::NoError; } sources.emplace_back(node.m_nodeId, true /* isStartNode */, finalNode.mwmName); - sources.back().segmentPoint = node.m_point; + sources.back().segmentPoint = MercatorBounds::FromLatLon(node.m_point); } vector weights; @@ -118,7 +117,7 @@ IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode) BorderCross CrossMwmGraph::FindNextMwmNode(OutgoingCrossNode const & startNode, TRoutingMappingPtr const & currentMapping) const { - m2::PointD const & startPoint = startNode.m_point; + ms::LatLon const & startPoint = startNode.m_point; // Check cached crosses. auto const it = m_cachedNextNodes.find(startPoint); @@ -140,10 +139,8 @@ BorderCross CrossMwmGraph::FindNextMwmNode(OutgoingCrossNode const & startNode, { auto const & targetPoint = ingoingNode.m_point; BorderCross const cross( - CrossNode(startNode.m_nodeId, currentMapping->GetCountryName(), - MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x)), - CrossNode(ingoingNode.m_nodeId, nextMwm, - MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x))); + CrossNode(startNode.m_nodeId, currentMapping->GetCountryName(), targetPoint), + CrossNode(ingoingNode.m_nodeId, nextMwm, targetPoint)); m_cachedNextNodes.insert(make_pair(startPoint, cross)); return cross; } @@ -173,11 +170,11 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, // Find income node. IngoingCrossNode ingoingNode; - bool found = currentContext.FindIngoingNodeByPoint({MercatorBounds::XToLon(v.toNode.point.x), MercatorBounds::YToLat(v.toNode.point.y)}, ingoingNode); - CHECK(found, (m2::PointD(MercatorBounds::XToLon(v.toNode.point.x), MercatorBounds::YToLat(v.toNode.point.y)))); + bool found = currentContext.FindIngoingNodeByPoint(v.toNode.point, ingoingNode); + CHECK(found, ()); if (ingoingNode.m_nodeId != v.toNode.node) { - LOG(LDEBUG, ("Several nodes stores in one border point.", m2::PointD(MercatorBounds::XToLon(v.toNode.point.x), MercatorBounds::YToLat(v.toNode.point.y)))); + LOG(LDEBUG, ("Several nodes stores in one border point.", v.toNode.point)); vector ingoingNodes; currentContext.GetAllIngoingNodes(ingoingNodes); for(auto const & node : ingoingNodes) @@ -221,8 +218,10 @@ void ConvertToSingleRouterTasks(vector const & graphCrosses, for (size_t i = 0; i + 1 < graphCrosses.size(); ++i) { ASSERT_EQUAL(graphCrosses[i].toNode.mwmName, graphCrosses[i + 1].fromNode.mwmName, ()); - route.emplace_back(graphCrosses[i].toNode.node, graphCrosses[i].toNode.point, - graphCrosses[i + 1].fromNode.node, graphCrosses[i + 1].fromNode.point, + route.emplace_back(graphCrosses[i].toNode.node, + MercatorBounds::FromLatLon(graphCrosses[i].toNode.point), + graphCrosses[i + 1].fromNode.node, + MercatorBounds::FromLatLon(graphCrosses[i + 1].fromNode.point), graphCrosses[i].toNode.mwmName); } diff --git a/routing/cross_mwm_road_graph.hpp b/routing/cross_mwm_road_graph.hpp index 08c9fa41c7..439dd62db1 100644 --- a/routing/cross_mwm_road_graph.hpp +++ b/routing/cross_mwm_road_graph.hpp @@ -6,6 +6,7 @@ #include "indexer/index.hpp" +#include "geometry/latlon.hpp" #include "geometry/point2d.hpp" #include "base/macros.hpp" @@ -21,20 +22,20 @@ struct CrossNode NodeID reverseNode; // TODO switch to mwmID string mwmName; - m2::PointD point; + ms::LatLon point; bool isVirtual; - CrossNode(NodeID node, NodeID reverse, string const & mwmName, m2::PointD const & point) + CrossNode(NodeID node, NodeID reverse, string const & mwmName, ms::LatLon const & point) : node(node), reverseNode(reverse), mwmName(mwmName), point(point), isVirtual(false) { } - CrossNode(NodeID node, string const & mwmName, m2::PointD const & point) + CrossNode(NodeID node, string const & mwmName, ms::LatLon const & point) : node(node), reverseNode(INVALID_NODE_ID), mwmName(mwmName), point(point), isVirtual(false) { } - CrossNode() : node(INVALID_NODE_ID), reverseNode(INVALID_NODE_ID), point(m2::PointD::Zero()) {} + CrossNode() : node(INVALID_NODE_ID), reverseNode(INVALID_NODE_ID), point(ms::LatLon::Zero()) {} inline bool IsValid() const { return node != INVALID_NODE_ID; } @@ -131,7 +132,7 @@ private: map > m_virtualEdges; mutable RoutingIndexManager m_indexManager; - mutable unordered_map m_cachedNextNodes; + mutable unordered_map m_cachedNextNodes; }; //-------------------------------------------------------------------------------------------------- diff --git a/routing/cross_mwm_router.cpp b/routing/cross_mwm_router.cpp index df138b4dbf..302689a6a3 100644 --- a/routing/cross_mwm_router.cpp +++ b/routing/cross_mwm_router.cpp @@ -18,7 +18,7 @@ IRouter::ResultCode CalculateRoute(BorderCross const & startPos, BorderCross con TAlgorithm::TOnVisitedVertexCallback onVisitedVertex = [&delegate](BorderCross const & cross, BorderCross const & /* target */) { - delegate.OnPointCheck(cross.fromNode.point); + delegate.OnPointCheck(MercatorBounds::FromLatLon(cross.fromNode.point)); }; my::HighResTimer timer(true); @@ -54,7 +54,7 @@ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes, for (FeatureGraphNode const & start : startGraphNodes) { startNode = CrossNode(start.node.forward_node_id, start.node.reverse_node_id, start.mwmName, - start.segmentPoint); + MercatorBounds::ToLatLon(start.segmentPoint)); code = roadGraph.SetStartNode(startNode); if (code == IRouter::NoError) { @@ -72,7 +72,7 @@ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes, for (FeatureGraphNode const & final : finalGraphNodes) { finalNode = CrossNode(final.node.reverse_node_id, final.node.forward_node_id, final.mwmName, - final.segmentPoint); + MercatorBounds::ToLatLon(final.segmentPoint)); finalNode.isVirtual = true; code = roadGraph.SetFinalNode(finalNode); if (code == IRouter::NoError) diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 4d3a7c5885..61ff4127e1 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -9,7 +9,7 @@ static uint32_t const g_coordBits = POINT_COORD_BITS; void OutgoingCrossNode::Save(Writer & w) const { - uint64_t point = PointToInt64(m_point, g_coordBits); + uint64_t point = PointToInt64(m2::PointD(m_point.lon, m_point.lat), g_coordBits); char buff[sizeof(m_nodeId) + sizeof(point) + sizeof(m_outgoingIndex)]; *reinterpret_cast(&buff[0]) = m_nodeId; *reinterpret_cast(&(buff[sizeof(m_nodeId)])) = point; @@ -22,7 +22,8 @@ size_t OutgoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyInd char buff[sizeof(m_nodeId) + sizeof(uint64_t) + sizeof(m_outgoingIndex)]; r.Read(pos, buff, sizeof(buff)); m_nodeId = *reinterpret_cast(&buff[0]); - m_point = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), g_coordBits); + m2::PointD bufferPoint = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), g_coordBits); + m_point = ms::LatLon(bufferPoint.y, bufferPoint.x); m_outgoingIndex = *reinterpret_cast(&(buff[sizeof(m_nodeId) + sizeof(uint64_t)])); m_adjacencyIndex = adjacencyIndex; return pos + sizeof(buff); @@ -30,7 +31,7 @@ size_t OutgoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyInd void IngoingCrossNode::Save(Writer & w) const { - uint64_t point = PointToInt64(m_point, g_coordBits); + uint64_t point = PointToInt64(m2::PointD(m_point.lon, m_point.lat), g_coordBits); char buff[sizeof(m_nodeId) + sizeof(point)]; *reinterpret_cast(&buff[0]) = m_nodeId; *reinterpret_cast(&(buff[sizeof(m_nodeId)])) = point; @@ -42,7 +43,8 @@ size_t IngoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyInde char buff[sizeof(m_nodeId) + sizeof(uint64_t)]; r.Read(pos, buff, sizeof(buff)); m_nodeId = *reinterpret_cast(&buff[0]); - m_point = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), g_coordBits); + m2::PointD bufferPoint = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), g_coordBits); + m_point = ms::LatLon(bufferPoint.y, bufferPoint.x); m_adjacencyIndex = adjacencyIndex; return pos + sizeof(buff); } @@ -89,11 +91,11 @@ void CrossRoutingContextReader::Load(Reader const & r) } } -bool CrossRoutingContextReader::FindIngoingNodeByPoint(m2::PointD const & point, +bool CrossRoutingContextReader::FindIngoingNodeByPoint(ms::LatLon const & point, IngoingCrossNode & node) const { bool found = false; - m_ingoingIndex.ForEachInRect(MercatorBounds::RectByCenterXYAndSizeInMeters(point, 5), + m_ingoingIndex.ForEachInRect(MercatorBounds::RectByCenterXYAndSizeInMeters({point.lat, point.lon}, 5), [&found, &node](IngoingCrossNode const & nd) { node = nd; @@ -163,14 +165,14 @@ void CrossRoutingContextWriter::Save(Writer & w) const } } -void CrossRoutingContextWriter::AddIngoingNode(WritedNodeID const nodeId, m2::PointD const & point) +void CrossRoutingContextWriter::AddIngoingNode(WritedNodeID const nodeId, ms::LatLon const & point) { 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) + ms::LatLon const & point) { size_t const adjIndex = m_outgoingNodes.size(); auto it = find(m_neighborMwmList.begin(), m_neighborMwmList.end(), targetMwm); diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index 428d2f74af..f99578ff16 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -2,6 +2,7 @@ #include "coding/file_container.hpp" +#include "geometry/latlon.hpp" #include "geometry/point2d.hpp" #include "geometry/rect2d.hpp" #include "geometry/tree4d.hpp" @@ -20,17 +21,17 @@ static size_t constexpr kInvalidAdjacencyIndex = numeric_limits::max(); struct IngoingCrossNode { - m2::PointD m_point; + ms::LatLon m_point; WritedNodeID m_nodeId; size_t m_adjacencyIndex; IngoingCrossNode() - : m_point(m2::PointD::Zero()) + : m_point(ms::LatLon::Zero()) , m_nodeId(INVALID_CONTEXT_EDGE_NODE_ID) , m_adjacencyIndex(kInvalidAdjacencyIndex) { } - IngoingCrossNode(WritedNodeID nodeId, m2::PointD const & point, size_t const adjacencyIndex) + IngoingCrossNode(WritedNodeID nodeId, ms::LatLon const & point, size_t const adjacencyIndex) : m_point(point), m_nodeId(nodeId), m_adjacencyIndex(adjacencyIndex) { } @@ -39,24 +40,24 @@ struct IngoingCrossNode size_t Load(Reader const & r, size_t pos, size_t adjacencyIndex); - m2::RectD const GetLimitRect() const { return m2::RectD(m_point, m_point); } + m2::RectD const GetLimitRect() const { return m2::RectD(m_point.lat, m_point.lon, m_point.lat, m_point.lon); } }; struct OutgoingCrossNode { - m2::PointD m_point; + ms::LatLon m_point; WritedNodeID m_nodeId; unsigned char m_outgoingIndex; size_t m_adjacencyIndex; OutgoingCrossNode() - : m_point(m2::PointD::Zero()) + : m_point(ms::LatLon::Zero()) , m_nodeId(INVALID_CONTEXT_EDGE_NODE_ID) , m_outgoingIndex(0) , m_adjacencyIndex(kInvalidAdjacencyIndex) { } - OutgoingCrossNode(WritedNodeID nodeId, size_t const index, m2::PointD const & point, + OutgoingCrossNode(WritedNodeID nodeId, size_t const index, ms::LatLon const & point, size_t const adjacencyIndex) : m_point(point) , m_nodeId(nodeId) @@ -86,7 +87,7 @@ public: const string & GetOutgoingMwmName(OutgoingCrossNode const & mwmIndex) const; - bool FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const; + bool FindIngoingNodeByPoint(ms::LatLon const & point, IngoingCrossNode & node) const; WritedEdgeWeightT GetAdjacencyCost(IngoingCrossNode const & ingoing, OutgoingCrossNode const & outgoing) const; @@ -108,10 +109,10 @@ class CrossRoutingContextWriter public: void Save(Writer & w) const; - void AddIngoingNode(WritedNodeID const nodeId, m2::PointD const & point); + void AddIngoingNode(WritedNodeID const nodeId, ms::LatLon const & point); void AddOutgoingNode(WritedNodeID const nodeId, string const & targetMwm, - m2::PointD const & point); + ms::LatLon const & point); void ReserveAdjacencyMatrix(); diff --git a/routing/routing_integration_tests/cross_section_tests.cpp b/routing/routing_integration_tests/cross_section_tests.cpp index 87e1a5f1a6..9944730df0 100644 --- a/routing/routing_integration_tests/cross_section_tests.cpp +++ b/routing/routing_integration_tests/cross_section_tests.cpp @@ -17,7 +17,6 @@ namespace UNIT_TEST(CheckCrossSections) { static double constexpr kPointEquality = 0.01; - static m2::PointD const kZeroPoint = m2::PointD(0., 0.); vector localFiles; platform::FindAllLocalMaps(localFiles); @@ -43,7 +42,7 @@ UNIT_TEST(CheckCrossSections) crossReader.GetAllIngoingNodes(ingoingNodes); for (auto const & node : ingoingNodes) { - if (node.m_point.EqualDxDy(kZeroPoint, kPointEquality)) + if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) { ingoingErrors++; break; @@ -53,7 +52,7 @@ UNIT_TEST(CheckCrossSections) vector outgoingNodes; for (auto const & node : outgoingNodes) { - if (node.m_point.EqualDxDy(kZeroPoint, kPointEquality)) + if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) { outgoingErrors++; break; diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index 4c8fe6df92..e22abd9e4d 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -43,10 +43,10 @@ UNIT_TEST(TestContextSerialization) routing::CrossRoutingContextWriter context; routing::CrossRoutingContextReader newContext; - context.AddIngoingNode(1, m2::PointD::Zero()); - context.AddIngoingNode(2, m2::PointD::Zero()); - context.AddOutgoingNode(3, "foo", m2::PointD::Zero()); - context.AddOutgoingNode(4, "bar", m2::PointD::Zero()); + context.AddIngoingNode(1, ms::LatLon::Zero()); + context.AddIngoingNode(2, ms::LatLon::Zero()); + context.AddOutgoingNode(3, "foo", ms::LatLon::Zero()); + context.AddOutgoingNode(4, "bar", ms::LatLon::Zero()); context.ReserveAdjacencyMatrix(); vector buffer; @@ -76,10 +76,10 @@ UNIT_TEST(TestAdjacencyMatrix) routing::CrossRoutingContextWriter context; routing::CrossRoutingContextReader newContext; - context.AddIngoingNode(1, m2::PointD::Zero()); - context.AddIngoingNode(2, m2::PointD::Zero()); - context.AddIngoingNode(3, m2::PointD::Zero()); - context.AddOutgoingNode(4, "foo", m2::PointD::Zero()); + context.AddIngoingNode(1, ms::LatLon::Zero()); + context.AddIngoingNode(2, ms::LatLon::Zero()); + context.AddIngoingNode(3, ms::LatLon::Zero()); + context.AddOutgoingNode(4, "foo", ms::LatLon::Zero()); context.ReserveAdjacencyMatrix(); { auto ins = context.GetIngoingIterators(); From af001ed07b3dc6c974c5ad2906d4a25eb63ff874 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Tue, 27 Oct 2015 18:00:48 +0300 Subject: [PATCH 07/11] MwmId usage inside a cross mwm road graph. --- generator/routing_generator.cpp | 4 +- routing/cross_mwm_road_graph.cpp | 38 ++++++++++--------- routing/cross_mwm_road_graph.hpp | 17 ++++----- routing/cross_mwm_router.cpp | 4 +- routing/cross_mwm_router.hpp | 6 +-- routing/cross_routing_context.cpp | 6 +-- routing/cross_routing_context.hpp | 12 +++--- routing/osrm_engine.cpp | 8 ++-- routing/osrm_engine.hpp | 8 ++-- routing/osrm_helpers.cpp | 7 ++-- routing/osrm_helpers.hpp | 2 +- routing/osrm_router.cpp | 6 +-- routing/routing_mapping.cpp | 7 ++++ routing/routing_mapping.hpp | 3 ++ routing/routing_tests/cross_routing_tests.cpp | 13 +++---- 15 files changed, 77 insertions(+), 64 deletions(-) diff --git a/generator/routing_generator.cpp b/generator/routing_generator.cpp index 2da32ee52c..6610f49ad3 100644 --- a/generator/routing_generator.cpp +++ b/generator/routing_generator.cpp @@ -173,10 +173,10 @@ void CalculateCrossAdjacency(string const & mwmRoutingPath, routing::CrossRoutin // Fill sources and targets with start node task for ingoing (true) and target node task // (false) for outgoing nodes for (auto i = in.first; i != in.second; ++i) - sources.emplace_back(i->m_nodeId, true /* isStartNode */, mwmRoutingPath); + sources.emplace_back(i->m_nodeId, true /* isStartNode */, Index::MwmId()); for (auto i = out.first; i != out.second; ++i) - targets.emplace_back(i->m_nodeId, false /* isStartNode */, mwmRoutingPath); + targets.emplace_back(i->m_nodeId, false /* isStartNode */, Index::MwmId()); LOG(LINFO, ("Cross section has", sources.size(), "incomes and ", targets.size(), "outcomes.")); vector costs; diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 950229fc34..00aaebee0e 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -12,9 +12,11 @@ namespace routing { IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) { - ASSERT(!startNode.mwmName.empty(), ()); + ASSERT(startNode.mwmId.IsAlive(), ()); // TODO (ldragunov) make cancellation if necessary - TRoutingMappingPtr startMapping = m_indexManager.GetMappingByName(startNode.mwmName); + TRoutingMappingPtr startMapping = m_indexManager.GetMappingById(startNode.mwmId); + if (!startMapping->IsValid()) + return IRouter::ResultCode::StartPointNotFound; MappingGuard startMappingGuard(startMapping); UNUSED_VALUE(startMappingGuard); startMapping->LoadCrossContext(); @@ -32,11 +34,11 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) targets.reserve(outSize); for (auto const & node : outgoingNodes) { - targets.emplace_back(node.m_nodeId, false /* isStartNode */, startNode.mwmName); + targets.emplace_back(node.m_nodeId, false /* isStartNode */, startNode.mwmId); targets.back().segmentPoint = MercatorBounds::FromLatLon(node.m_point); } sources[0] = FeatureGraphNode(startNode.node, startNode.reverseNode, true /* isStartNode */, - startNode.mwmName); + startNode.mwmId); vector weights; FindWeightsMatrix(sources, targets, startMapping->m_dataFacade, weights); @@ -60,7 +62,7 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) void CrossMwmGraph::AddVirtualEdge(IngoingCrossNode const & node, CrossNode const & finalNode, EdgeWeight weight) { - CrossNode start(node.m_nodeId, finalNode.mwmName, node.m_point); + CrossNode start(node.m_nodeId, finalNode.mwmId, node.m_point); vector dummyEdges; dummyEdges.emplace_back(BorderCross(finalNode, finalNode), weight); m_virtualEdges.insert(make_pair(start, dummyEdges)); @@ -68,8 +70,10 @@ void CrossMwmGraph::AddVirtualEdge(IngoingCrossNode const & node, CrossNode cons IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode) { - ASSERT(finalNode.mwmName.length(), ()); - TRoutingMappingPtr finalMapping = m_indexManager.GetMappingByName(finalNode.mwmName); + ASSERT(finalNode.mwmId.IsAlive(), ()); + TRoutingMappingPtr finalMapping = m_indexManager.GetMappingById(finalNode.mwmId); + if (!finalMapping->IsValid()) + return IRouter::ResultCode::EndPointNotFound; MappingGuard finalMappingGuard(finalMapping); UNUSED_VALUE(finalMappingGuard); finalMapping->LoadCrossContext(); @@ -94,13 +98,13 @@ IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode) AddVirtualEdge(node, finalNode, 0 /* no weight */); return IRouter::NoError; } - sources.emplace_back(node.m_nodeId, true /* isStartNode */, finalNode.mwmName); + sources.emplace_back(node.m_nodeId, true /* isStartNode */, finalNode.mwmId); sources.back().segmentPoint = MercatorBounds::FromLatLon(node.m_point); } vector weights; targets[0] = FeatureGraphNode(finalNode.node, finalNode.reverseNode, false /* isStartNode */, - finalNode.mwmName); + finalNode.mwmId); FindWeightsMatrix(sources, targets, finalMapping->m_dataFacade, weights); if (find_if(weights.begin(), weights.end(), &IsValidEdgeWeight) == weights.end()) return IRouter::EndPointNotFound; @@ -139,8 +143,8 @@ BorderCross CrossMwmGraph::FindNextMwmNode(OutgoingCrossNode const & startNode, { auto const & targetPoint = ingoingNode.m_point; BorderCross const cross( - CrossNode(startNode.m_nodeId, currentMapping->GetCountryName(), targetPoint), - CrossNode(ingoingNode.m_nodeId, nextMwm, targetPoint)); + CrossNode(startNode.m_nodeId, currentMapping->GetMwmId(), targetPoint), + CrossNode(ingoingNode.m_nodeId, nextMapping->GetMwmId(), targetPoint)); m_cachedNextNodes.insert(make_pair(startPoint, cross)); return cross; } @@ -161,7 +165,7 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, } // Loading cross routing section. - TRoutingMappingPtr currentMapping = m_indexManager.GetMappingByName(v.toNode.mwmName); + TRoutingMappingPtr currentMapping = m_indexManager.GetMappingById(v.toNode.mwmId); ASSERT(currentMapping->IsValid(), ()); currentMapping->LoadCrossContext(); currentMapping->FreeFileIfPossible(); @@ -194,7 +198,7 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, for (auto const & node : outgoingNodes) { EdgeWeight const outWeight = currentContext.GetAdjacencyCost(ingoingNode, node); - if (outWeight != INVALID_CONTEXT_EDGE_WEIGHT && outWeight != 0) + if (outWeight != kInvalidContextEdgeWeight && outWeight != 0) { BorderCross target = FindNextMwmNode(node, currentMapping); if (target.toNode.IsValid()) @@ -217,12 +221,12 @@ void ConvertToSingleRouterTasks(vector const & graphCrosses, route.clear(); for (size_t i = 0; i + 1 < graphCrosses.size(); ++i) { - ASSERT_EQUAL(graphCrosses[i].toNode.mwmName, graphCrosses[i + 1].fromNode.mwmName, ()); + ASSERT_EQUAL(graphCrosses[i].toNode.mwmId, graphCrosses[i + 1].fromNode.mwmId, ()); route.emplace_back(graphCrosses[i].toNode.node, MercatorBounds::FromLatLon(graphCrosses[i].toNode.point), graphCrosses[i + 1].fromNode.node, MercatorBounds::FromLatLon(graphCrosses[i + 1].fromNode.point), - graphCrosses[i].toNode.mwmName); + graphCrosses[i].toNode.mwmId); } if (route.empty()) @@ -230,8 +234,8 @@ void ConvertToSingleRouterTasks(vector const & graphCrosses, route.front().startNode = startGraphNode; route.back().finalNode = finalGraphNode; - ASSERT_EQUAL(route.front().startNode.mwmName, route.front().finalNode.mwmName, ()); - ASSERT_EQUAL(route.back().startNode.mwmName, route.back().finalNode.mwmName, ()); + ASSERT_EQUAL(route.front().startNode.mwmId, route.front().finalNode.mwmId, ()); + ASSERT_EQUAL(route.back().startNode.mwmId, route.back().finalNode.mwmId, ()); } } // namespace routing diff --git a/routing/cross_mwm_road_graph.hpp b/routing/cross_mwm_road_graph.hpp index 439dd62db1..6149074fa2 100644 --- a/routing/cross_mwm_road_graph.hpp +++ b/routing/cross_mwm_road_graph.hpp @@ -20,18 +20,17 @@ struct CrossNode { NodeID node; NodeID reverseNode; - // TODO switch to mwmID - string mwmName; + Index::MwmId mwmId; ms::LatLon point; bool isVirtual; - CrossNode(NodeID node, NodeID reverse, string const & mwmName, ms::LatLon const & point) - : node(node), reverseNode(reverse), mwmName(mwmName), point(point), isVirtual(false) + CrossNode(NodeID node, NodeID reverse, Index::MwmId const & id, ms::LatLon const & point) + : node(node), reverseNode(reverse), mwmId(id), point(point), isVirtual(false) { } - CrossNode(NodeID node, string const & mwmName, ms::LatLon const & point) - : node(node), reverseNode(INVALID_NODE_ID), mwmName(mwmName), point(point), isVirtual(false) + CrossNode(NodeID node, Index::MwmId const & id, ms::LatLon const & point) + : node(node), reverseNode(INVALID_NODE_ID), mwmId(id), point(point), isVirtual(false) { } @@ -41,7 +40,7 @@ struct CrossNode inline bool operator==(CrossNode const & a) const { - return node == a.node && mwmName == a.mwmName && isVirtual == a.isVirtual; + return node == a.node && mwmId == a.mwmId && isVirtual == a.isVirtual; } inline bool operator<(CrossNode const & a) const @@ -52,14 +51,14 @@ struct CrossNode if (isVirtual != a.isVirtual) return isVirtual < a.isVirtual; - return mwmName < a.mwmName; + return mwmId < a.mwmId; } }; inline string DebugPrint(CrossNode const & t) { ostringstream out; - out << "CrossNode [ node: " << t.node << ", map: " << t.mwmName << " ]"; + out << "CrossNode [ node: " << t.node << ", map: " << t.mwmId.GetInfo()->GetCountryName()<< " ]"; return out.str(); } diff --git a/routing/cross_mwm_router.cpp b/routing/cross_mwm_router.cpp index 302689a6a3..4da5761af7 100644 --- a/routing/cross_mwm_router.cpp +++ b/routing/cross_mwm_router.cpp @@ -53,7 +53,7 @@ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes, IRouter::ResultCode code = IRouter::StartPointNotFound; for (FeatureGraphNode const & start : startGraphNodes) { - startNode = CrossNode(start.node.forward_node_id, start.node.reverse_node_id, start.mwmName, + startNode = CrossNode(start.node.forward_node_id, start.node.reverse_node_id, start.mwmId, MercatorBounds::ToLatLon(start.segmentPoint)); code = roadGraph.SetStartNode(startNode); if (code == IRouter::NoError) @@ -71,7 +71,7 @@ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes, code = IRouter::EndPointNotFound; for (FeatureGraphNode const & final : finalGraphNodes) { - finalNode = CrossNode(final.node.reverse_node_id, final.node.forward_node_id, final.mwmName, + finalNode = CrossNode(final.node.reverse_node_id, final.node.forward_node_id, final.mwmId, MercatorBounds::ToLatLon(final.segmentPoint)); finalNode.isVirtual = true; code = roadGraph.SetFinalNode(finalNode); diff --git a/routing/cross_mwm_router.hpp b/routing/cross_mwm_router.hpp index 71f75ce029..4fcebf8c16 100644 --- a/routing/cross_mwm_router.hpp +++ b/routing/cross_mwm_router.hpp @@ -17,9 +17,9 @@ struct RoutePathCross FeatureGraphNode startNode; /**< start graph node representation */ FeatureGraphNode finalNode; /**< end graph node representation */ - RoutePathCross(NodeID const startNodeId, m2::PointD const & startPoint, NodeID const finalNodeId, m2::PointD const & finalPoint, string const & name) - : startNode(startNodeId, true /* isStartNode */, name), - finalNode(finalNodeId, false /* isStartNode*/, name) + RoutePathCross(NodeID const startNodeId, m2::PointD const & startPoint, NodeID const finalNodeId, m2::PointD const & finalPoint, Index::MwmId const & id) + : startNode(startNodeId, true /* isStartNode */, id), + finalNode(finalNodeId, false /* isStartNode*/, id) { startNode.segmentPoint = startPoint; finalNode.segmentPoint = finalPoint; diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 61ff4127e1..81da8308ea 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -118,10 +118,10 @@ WritedEdgeWeightT CrossRoutingContextReader::GetAdjacencyCost(IngoingCrossNode c { if (ingoing.m_adjacencyIndex == kInvalidAdjacencyIndex || outgoing.m_adjacencyIndex == kInvalidAdjacencyIndex) - return INVALID_CONTEXT_EDGE_WEIGHT; + return kInvalidContextEdgeWeight; 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; + return cost_index < m_adjacencyMatrix.size() ? m_adjacencyMatrix[cost_index] : kInvalidContextEdgeWeight; } void CrossRoutingContextReader::GetAllIngoingNodes(vector & nodes) const @@ -184,7 +184,7 @@ void CrossRoutingContextWriter::AddOutgoingNode(WritedNodeID const nodeId, strin void CrossRoutingContextWriter::ReserveAdjacencyMatrix() { m_adjacencyMatrix.resize(m_ingoingNodes.size() * m_outgoingNodes.size(), - INVALID_CONTEXT_EDGE_WEIGHT); + kInvalidContextEdgeWeight); } void CrossRoutingContextWriter::SetAdjacencyCost(IngoingEdgeIteratorT ingoing, diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index f99578ff16..228c0dcfed 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -12,12 +12,12 @@ namespace routing { -// TODO (ldragunov) Fix this!!!! using WritedNodeID = uint32_t; using WritedEdgeWeightT = uint32_t; -static WritedEdgeWeightT const INVALID_CONTEXT_EDGE_WEIGHT = std::numeric_limits::max(); -static WritedEdgeWeightT const INVALID_CONTEXT_EDGE_NODE_ID = std::numeric_limits::max(); -static size_t constexpr kInvalidAdjacencyIndex = numeric_limits::max(); + +WritedEdgeWeightT constexpr kInvalidContextEdgeNodeId = std::numeric_limits::max(); +WritedEdgeWeightT constexpr kInvalidContextEdgeWeight = std::numeric_limits::max(); +size_t constexpr kInvalidAdjacencyIndex = numeric_limits::max(); struct IngoingCrossNode { @@ -27,7 +27,7 @@ struct IngoingCrossNode IngoingCrossNode() : m_point(ms::LatLon::Zero()) - , m_nodeId(INVALID_CONTEXT_EDGE_NODE_ID) + , m_nodeId(kInvalidContextEdgeNodeId) , m_adjacencyIndex(kInvalidAdjacencyIndex) { } @@ -52,7 +52,7 @@ struct OutgoingCrossNode OutgoingCrossNode() : m_point(ms::LatLon::Zero()) - , m_nodeId(INVALID_CONTEXT_EDGE_NODE_ID) + , m_nodeId(kInvalidContextEdgeNodeId) , m_outgoingIndex(0) , m_adjacencyIndex(kInvalidAdjacencyIndex) { diff --git a/routing/osrm_engine.cpp b/routing/osrm_engine.cpp index eb0d15eb62..8c03db9258 100644 --- a/routing/osrm_engine.cpp +++ b/routing/osrm_engine.cpp @@ -91,8 +91,8 @@ bool FindSingleRoute(FeatureGraphNode const & source, FeatureGraphNode const & t } FeatureGraphNode::FeatureGraphNode(NodeID const nodeId, bool const isStartNode, - string const & mwmName) - : segmentPoint(m2::PointD::Zero()), mwmName(mwmName) + Index::MwmId const & id) + : segmentPoint(m2::PointD::Zero()), mwmId(id) { node.forward_node_id = isStartNode ? nodeId : INVALID_NODE_ID; node.reverse_node_id = isStartNode ? INVALID_NODE_ID : nodeId; @@ -105,8 +105,8 @@ FeatureGraphNode::FeatureGraphNode(NodeID const nodeId, bool const isStartNode, } FeatureGraphNode::FeatureGraphNode(NodeID const nodeId, NodeID const reverseNodeId, - bool const isStartNode, string const & mwmName) - : segmentPoint(m2::PointD::Zero()), mwmName(mwmName) + bool const isStartNode, Index::MwmId const & id) + : segmentPoint(m2::PointD::Zero()), mwmId(id) { node.forward_node_id = isStartNode ? nodeId : reverseNodeId; node.reverse_node_id = isStartNode ? reverseNodeId : nodeId; diff --git a/routing/osrm_engine.hpp b/routing/osrm_engine.hpp index 40671963e0..2d032dde9c 100644 --- a/routing/osrm_engine.hpp +++ b/routing/osrm_engine.hpp @@ -3,6 +3,8 @@ #include "routing/osrm2feature_map.hpp" #include "routing/osrm_data_facade.hpp" +#include "indexer/index.hpp" + #include "geometry/point2d.hpp" #include "std/vector.hpp" @@ -17,7 +19,7 @@ struct FeatureGraphNode PhantomNode node; OsrmMappingTypes::FtSeg segment; m2::PointD segmentPoint; - string mwmName; + Index::MwmId mwmId; /*! * \brief fill FeatureGraphNode with values. @@ -25,10 +27,10 @@ struct FeatureGraphNode * \param isStartNode true if this node will first in the path. * \param mwmName @nodeId refers node on the graph of this map. */ - FeatureGraphNode(NodeID const nodeId, bool const isStartNode, string const & mwmName); + FeatureGraphNode(NodeID const nodeId, bool const isStartNode, Index::MwmId const & id); FeatureGraphNode(NodeID const nodeId, NodeID const reverseNodeId, bool const isStartNode, - string const & mwmName); + Index::MwmId const & id); /// \brief Invalid graph node constructor FeatureGraphNode(); diff --git a/routing/osrm_helpers.cpp b/routing/osrm_helpers.cpp index 1b35639d1a..51fd5108a9 100644 --- a/routing/osrm_helpers.cpp +++ b/routing/osrm_helpers.cpp @@ -189,8 +189,7 @@ EdgeWeight Point2PhantomNode::GetMinNodeWeight(NodeID node, m2::PointD const & p return minWeight; } -void Point2PhantomNode::MakeResult(vector & res, size_t maxCount, - string const & mwmName) +void Point2PhantomNode::MakeResult(vector & res, size_t maxCount) { vector segments; @@ -258,14 +257,14 @@ void Point2PhantomNode::MakeResult(vector & res, size_t maxCou node.segment = segments[j]; node.segmentPoint = m_candidates[j].m_point; - node.mwmName = mwmName; + node.mwmId = m_routingMapping.GetMwmId(); CalculateWeights(node); } res.erase(remove_if(res.begin(), res.end(), [](FeatureGraphNode const & f) { - return f.mwmName.empty(); + return !f.mwmId.IsAlive(); }), res.end()); } diff --git a/routing/osrm_helpers.hpp b/routing/osrm_helpers.hpp index 01871997dd..97168e0c3e 100644 --- a/routing/osrm_helpers.hpp +++ b/routing/osrm_helpers.hpp @@ -49,7 +49,7 @@ public: void operator()(FeatureType const & ft); /// Makes OSRM tasks result vector. - void MakeResult(vector & res, size_t maxCount, string const & mwmName); + void MakeResult(vector & res, size_t maxCount); private: // Calculates distance in meters on the feature from startPoint to endPoint. diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index 92d31da77a..4c924ff6f4 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -163,9 +163,9 @@ OsrmRouter::ResultCode OsrmRouter::MakeRouteFromCrossesPath(TCheckedPath const & vector Points; for (RoutePathCross cross : path) { - ASSERT_EQUAL(cross.startNode.mwmName, cross.finalNode.mwmName, ()); + ASSERT_EQUAL(cross.startNode.mwmId, cross.finalNode.mwmId, ()); RawRoutingResult routingResult; - TRoutingMappingPtr mwmMapping = m_indexManager.GetMappingByName(cross.startNode.mwmName); + TRoutingMappingPtr mwmMapping = m_indexManager.GetMappingById(cross.startNode.mwmId); ASSERT(mwmMapping->IsValid(), ()); MappingGuard mwmMappingGuard(mwmMapping); UNUSED_VALUE(mwmMappingGuard); @@ -359,7 +359,7 @@ IRouter::ResultCode OsrmRouter::FindPhantomNodes(m2::PointD const & point, if (!getter.HasCandidates()) return RouteNotFound; - getter.MakeResult(res, maxCount, mapping->GetCountryName()); + getter.MakeResult(res, maxCount); return NoError; } diff --git a/routing/routing_mapping.cpp b/routing/routing_mapping.cpp index 228857551d..d1dc9a3370 100644 --- a/routing/routing_mapping.cpp +++ b/routing/routing_mapping.cpp @@ -196,4 +196,11 @@ TRoutingMappingPtr RoutingIndexManager::GetMappingByName(string const & mapName) return newMapping; } +TRoutingMappingPtr RoutingIndexManager::GetMappingById(Index::MwmId const & id) +{ + if (!id.IsAlive()) + return TRoutingMappingPtr(new RoutingMapping()); + return GetMappingByName(id.GetInfo()->GetCountryName()); +} + } // namespace routing diff --git a/routing/routing_mapping.hpp b/routing/routing_mapping.hpp index 5e46cf48aa..b97f279475 100644 --- a/routing/routing_mapping.hpp +++ b/routing/routing_mapping.hpp @@ -106,6 +106,8 @@ public: TRoutingMappingPtr GetMappingByName(string const & mapName); + TRoutingMappingPtr GetMappingById(Index::MwmId const & id); + template void ForEachMapping(TFunctor toDo) { @@ -116,6 +118,7 @@ public: private: TCountryFileFn m_countryFileFn; + // TODO (ldragunov) Rewrite to mwmId. unordered_map m_mapping; MwmSet & m_index; }; diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index e22abd9e4d..52d692ea1a 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -14,23 +14,22 @@ namespace // Graph to convertions. UNIT_TEST(TestCrossRouteConverter) { + Index::MwmId aMap, bMap; vector graphCrosses; - CrossNode const a(1, "aMap", {0, 0}), b(2, "aMap", {2, 2}); - CrossNode const c(3, "bMap", {3, 3}), d(3, "bMap", {4, 4}); + CrossNode const a(1, aMap, {0, 0}), b(2, aMap, {2, 2}); + CrossNode const c(3, bMap, {3, 3}), d(3, bMap, {4, 4}); graphCrosses.emplace_back(a, b); graphCrosses.emplace_back(b, c); graphCrosses.emplace_back(c, d); FeatureGraphNode startGraphNode; startGraphNode.node.forward_node_id = 5; - startGraphNode.mwmName = "aMap"; + startGraphNode.mwmId = aMap; FeatureGraphNode finalGraphNode; finalGraphNode.node.reverse_node_id = 6; - finalGraphNode.mwmName = "bMap"; + finalGraphNode.mwmId = bMap; TCheckedPath route; ConvertToSingleRouterTasks(graphCrosses, startGraphNode, finalGraphNode, route); TEST_EQUAL(route.size(), 2, ("We have 2 maps aMap and bMap.")); - for (auto const & r : route) - TEST_EQUAL(r.startNode.mwmName, r.finalNode.mwmName, ()); TEST_EQUAL(route.front().startNode.node, startGraphNode.node, ("Start node must be replaced by origin.")); TEST_EQUAL(route.back().finalNode.node, finalGraphNode.node, @@ -102,7 +101,7 @@ UNIT_TEST(TestAdjacencyMatrix) TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[0], outgoingNodes[0]), 5, ()); TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[1], outgoingNodes[0]), 9, ()); TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[2], outgoingNodes[0]), - routing::INVALID_CONTEXT_EDGE_WEIGHT, ("Default cost")); + routing::kInvalidContextEdgeWeight, ("Default cost")); } } From d8de1921c3ffae9cf216a3407ab098a21cdba5a6 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Tue, 27 Oct 2015 18:14:56 +0300 Subject: [PATCH 08/11] Cross routing NodeByPoint method test. --- routing/cross_mwm_road_graph.cpp | 2 +- routing/routing_tests/cross_routing_tests.cpp | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 00aaebee0e..27313cf966 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -178,7 +178,7 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, CHECK(found, ()); if (ingoingNode.m_nodeId != v.toNode.node) { - LOG(LDEBUG, ("Several nodes stores in one border point.", v.toNode.point)); + LOG(LDEBUG, ("Several nodes stores in a one border point.", v.toNode.point)); vector ingoingNodes; currentContext.GetAllIngoingNodes(ingoingNodes); for(auto const & node : ingoingNodes) diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index 52d692ea1a..58e3108081 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -104,4 +104,31 @@ UNIT_TEST(TestAdjacencyMatrix) routing::kInvalidContextEdgeWeight, ("Default cost")); } +UNIT_TEST(TestFindingByPoint) +{ + routing::CrossRoutingContextWriter context; + routing::CrossRoutingContextReader newContext; + + ms::LatLon p1(1., 1.), p2(5., 5.), p3(10.,1.); + + context.AddIngoingNode(1, ms::LatLon::Zero()); + context.AddIngoingNode(2, p1); + context.AddIngoingNode(3, p2); + context.AddOutgoingNode(4, "foo", ms::LatLon::Zero()); + context.ReserveAdjacencyMatrix(); + + vector buffer; + MemWriter > writer(buffer); + context.Save(writer); + TEST_GREATER(buffer.size(), 5, ("Context serializer make some data")); + + MemReader reader(buffer.data(), buffer.size()); + newContext.Load(reader); + IngoingCrossNode node; + TEST(newContext.FindIngoingNodeByPoint(p1, node), ()); + TEST_EQUAL(node.m_nodeId, 2, ()); + TEST(newContext.FindIngoingNodeByPoint(p2, node), ()); + TEST_EQUAL(node.m_nodeId, 3, ()); + TEST(!newContext.FindIngoingNodeByPoint(p3, node), ()); } +} // namespace From 419488cd68eebc821ce7e3300ac042e171abba7b Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Wed, 28 Oct 2015 16:34:02 +0300 Subject: [PATCH 09/11] Review fixes. --- generator/routing_generator.cpp | 6 +++--- geometry/latlon.cpp | 9 +++++++++ geometry/latlon.hpp | 10 ++-------- routing/cross_mwm_road_graph.cpp | 5 ++--- routing/cross_routing_context.cpp | 10 +++++----- routing/cross_routing_context.hpp | 28 ++++++++++++++-------------- 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/generator/routing_generator.cpp b/generator/routing_generator.cpp index 6610f49ad3..7c7edb431c 100644 --- a/generator/routing_generator.cpp +++ b/generator/routing_generator.cpp @@ -91,7 +91,7 @@ void FindCrossNodes(osrm::NodeDataVectorT const & nodeData, gen::OsmID2FeatureID }); }); - for (WritedNodeID nodeId = 0; nodeId < nodeData.size(); ++nodeId) + for (TWrittenNodeId nodeId = 0; nodeId < nodeData.size(); ++nodeId) { auto const & data = nodeData[nodeId]; @@ -128,7 +128,7 @@ void FindCrossNodes(osrm::NodeDataVectorT const & nodeData, gen::OsmID2FeatureID continue; } // for old format compatibility - ms::LatLon wgsIntersection = ms::LatLon(MercatorBounds::ToLatLon(intersection)); + ms::LatLon wgsIntersection = MercatorBounds::ToLatLon(intersection); if (!outStart && outEnd) crossContext.AddIngoingNode(nodeId, wgsIntersection); else if (outStart && !outEnd) @@ -259,7 +259,7 @@ void BuildRoutingIndex(string const & baseDir, string const & countryName, strin uint32_t found = 0, all = 0, multiple = 0, equal = 0, moreThan1Seg = 0, stored = 0; - for (WritedNodeID nodeId = 0; nodeId < nodeData.size(); ++nodeId) + for (TWrittenNodeId nodeId = 0; nodeId < nodeData.size(); ++nodeId) { auto const & data = nodeData[nodeId]; diff --git a/geometry/latlon.cpp b/geometry/latlon.cpp index fb57a27788..eefcd02386 100644 --- a/geometry/latlon.cpp +++ b/geometry/latlon.cpp @@ -13,4 +13,13 @@ string DebugPrint(LatLon const & t) return out.str(); } +bool LatLon::operator == (ms::LatLon const & p) const +{ + return lat == p.lat && lon == p.lon; +} + +bool LatLon::EqualDxDy(LatLon const & p, double eps) const +{ + return (my::AlmostEqualAbs(lat, p.lat, eps) && my::AlmostEqualAbs(lon, p.lon, eps)); +} } // namespace ms diff --git a/geometry/latlon.hpp b/geometry/latlon.hpp index 4d5d105c29..4ff650d745 100644 --- a/geometry/latlon.hpp +++ b/geometry/latlon.hpp @@ -17,15 +17,9 @@ public: static LatLon Zero() { return LatLon(0., 0.); } - bool operator == (ms::LatLon const & p) const - { - return lat == p.lat && lon == p.lon; - } + bool operator == (ms::LatLon const & p) const; - bool EqualDxDy(LatLon const & p, double eps) const - { - return ((fabs(lat - p.lat) < eps) && (fabs(lon - p.lon) < eps)); - } + bool EqualDxDy(LatLon const & p, double eps) const; struct Hash { diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 27313cf966..211d2781a8 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -174,11 +174,10 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, // Find income node. IngoingCrossNode ingoingNode; - bool found = currentContext.FindIngoingNodeByPoint(v.toNode.point, ingoingNode); - CHECK(found, ()); + CHECK(currentContext.FindIngoingNodeByPoint(v.toNode.point, ingoingNode), ()); if (ingoingNode.m_nodeId != v.toNode.node) { - LOG(LDEBUG, ("Several nodes stores in a one border point.", v.toNode.point)); + LOG(LDEBUG, ("Several nodes stores in one border point.", v.toNode.point)); vector ingoingNodes; currentContext.GetAllIngoingNodes(ingoingNodes); for(auto const & node : ingoingNodes) diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 81da8308ea..64410ebd5a 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -72,7 +72,7 @@ void CrossRoutingContextReader::Load(Reader const & r) pos = m_outgoingNodes[i].Load(r, pos, i); size_t adjacencySize = ingoingSize * m_outgoingNodes.size(); - size_t const adjMatrixSize = sizeof(WritedEdgeWeightT) * adjacencySize; + size_t const adjMatrixSize = sizeof(TWrittenEdgeWeight) * adjacencySize; m_adjacencyMatrix.resize(adjacencySize); r.Read(pos, &m_adjacencyMatrix[0], adjMatrixSize); pos += adjMatrixSize; @@ -113,7 +113,7 @@ const string & CrossRoutingContextReader::GetOutgoingMwmName( return m_neighborMwmList[outgoingNode.m_outgoingIndex]; } -WritedEdgeWeightT CrossRoutingContextReader::GetAdjacencyCost(IngoingCrossNode const & ingoing, +TWrittenEdgeWeight CrossRoutingContextReader::GetAdjacencyCost(IngoingCrossNode const & ingoing, OutgoingCrossNode const & outgoing) const { if (ingoing.m_adjacencyIndex == kInvalidAdjacencyIndex || @@ -165,13 +165,13 @@ void CrossRoutingContextWriter::Save(Writer & w) const } } -void CrossRoutingContextWriter::AddIngoingNode(WritedNodeID const nodeId, ms::LatLon const & point) +void CrossRoutingContextWriter::AddIngoingNode(TWrittenNodeId const nodeId, ms::LatLon const & point) { size_t const adjIndex = m_ingoingNodes.size(); m_ingoingNodes.emplace_back(nodeId, point, adjIndex); } -void CrossRoutingContextWriter::AddOutgoingNode(WritedNodeID const nodeId, string const & targetMwm, +void CrossRoutingContextWriter::AddOutgoingNode(TWrittenNodeId const nodeId, string const & targetMwm, ms::LatLon const & point) { size_t const adjIndex = m_outgoingNodes.size(); @@ -189,7 +189,7 @@ void CrossRoutingContextWriter::ReserveAdjacencyMatrix() void CrossRoutingContextWriter::SetAdjacencyCost(IngoingEdgeIteratorT ingoing, OutgoingEdgeIteratorT outgoing, - WritedEdgeWeightT value) + TWrittenEdgeWeight value) { size_t const index = m_outgoingNodes.size() * ingoing->m_adjacencyIndex + outgoing->m_adjacencyIndex; ASSERT_LESS(index, m_adjacencyMatrix.size(), ()); diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index 228c0dcfed..16a2707696 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -12,17 +12,17 @@ namespace routing { -using WritedNodeID = uint32_t; -using WritedEdgeWeightT = uint32_t; +using TWrittenNodeId = uint32_t; +using TWrittenEdgeWeight = uint32_t; -WritedEdgeWeightT constexpr kInvalidContextEdgeNodeId = std::numeric_limits::max(); -WritedEdgeWeightT constexpr kInvalidContextEdgeWeight = std::numeric_limits::max(); +TWrittenEdgeWeight constexpr kInvalidContextEdgeNodeId = std::numeric_limits::max(); +TWrittenEdgeWeight constexpr kInvalidContextEdgeWeight = std::numeric_limits::max(); size_t constexpr kInvalidAdjacencyIndex = numeric_limits::max(); struct IngoingCrossNode { ms::LatLon m_point; - WritedNodeID m_nodeId; + TWrittenNodeId m_nodeId; size_t m_adjacencyIndex; IngoingCrossNode() @@ -31,7 +31,7 @@ struct IngoingCrossNode , m_adjacencyIndex(kInvalidAdjacencyIndex) { } - IngoingCrossNode(WritedNodeID nodeId, ms::LatLon const & point, size_t const adjacencyIndex) + IngoingCrossNode(TWrittenNodeId nodeId, ms::LatLon const & point, size_t const adjacencyIndex) : m_point(point), m_nodeId(nodeId), m_adjacencyIndex(adjacencyIndex) { } @@ -46,7 +46,7 @@ struct IngoingCrossNode struct OutgoingCrossNode { ms::LatLon m_point; - WritedNodeID m_nodeId; + TWrittenNodeId m_nodeId; unsigned char m_outgoingIndex; size_t m_adjacencyIndex; @@ -57,7 +57,7 @@ struct OutgoingCrossNode , m_adjacencyIndex(kInvalidAdjacencyIndex) { } - OutgoingCrossNode(WritedNodeID nodeId, size_t const index, ms::LatLon const & point, + OutgoingCrossNode(TWrittenNodeId nodeId, size_t const index, ms::LatLon const & point, size_t const adjacencyIndex) : m_point(point) , m_nodeId(nodeId) @@ -79,7 +79,7 @@ class CrossRoutingContextReader { vector m_outgoingNodes; vector m_neighborMwmList; - vector m_adjacencyMatrix; + vector m_adjacencyMatrix; m4::Tree m_ingoingIndex; public: @@ -89,7 +89,7 @@ public: bool FindIngoingNodeByPoint(ms::LatLon const & point, IngoingCrossNode & node) const; - WritedEdgeWeightT GetAdjacencyCost(IngoingCrossNode const & ingoing, + TWrittenEdgeWeight GetAdjacencyCost(IngoingCrossNode const & ingoing, OutgoingCrossNode const & outgoing) const; void GetAllIngoingNodes(vector & nodes) const; @@ -101,7 +101,7 @@ class CrossRoutingContextWriter { vector m_ingoingNodes; vector m_outgoingNodes; - vector m_adjacencyMatrix; + vector m_adjacencyMatrix; vector m_neighborMwmList; size_t GetIndexInAdjMatrix(IngoingEdgeIteratorT ingoing, OutgoingEdgeIteratorT outgoing) const; @@ -109,15 +109,15 @@ class CrossRoutingContextWriter public: void Save(Writer & w) const; - void AddIngoingNode(WritedNodeID const nodeId, ms::LatLon const & point); + void AddIngoingNode(TWrittenNodeId const nodeId, ms::LatLon const & point); - void AddOutgoingNode(WritedNodeID const nodeId, string const & targetMwm, + void AddOutgoingNode(TWrittenNodeId const nodeId, string const & targetMwm, ms::LatLon const & point); void ReserveAdjacencyMatrix(); void SetAdjacencyCost(IngoingEdgeIteratorT ingoing, OutgoingEdgeIteratorT outgoin, - WritedEdgeWeightT value); + TWrittenEdgeWeight value); pair GetIngoingIterators() const; From 4ea126d0d9177ba0ba685007ebfad986f34c0c6e Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Thu, 29 Oct 2015 17:40:12 +0300 Subject: [PATCH 10/11] ForEach pattern for CrossContext reader. --- routing/cross_mwm_road_graph.cpp | 49 ++++++++++--------- routing/cross_routing_context.cpp | 35 +++++-------- routing/cross_routing_context.hpp | 7 ++- .../cross_section_tests.cpp | 35 ++++++------- routing/routing_tests/cross_routing_tests.cpp | 20 ++++++-- 5 files changed, 75 insertions(+), 71 deletions(-) diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 211d2781a8..273ad99f51 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -23,7 +23,12 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode) // Load source data. vector outgoingNodes; - startMapping->m_crossContext.GetAllOutgoingNodes(outgoingNodes); + + startMapping->m_crossContext.ForEachOutgoingNode([&outgoingNodes](OutgoingCrossNode const & node) + { + outgoingNodes.push_back(node); + }); + size_t const outSize = outgoingNodes.size(); // Can't find the route if there are no routes outside source map. if (!outSize) @@ -80,7 +85,10 @@ IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode) // Load source data. vector ingoingNodes; - finalMapping->m_crossContext.GetAllIngoingNodes(ingoingNodes); + finalMapping->m_crossContext.ForEachIngoingNode([&ingoingNodes](IngoingCrossNode const & node) + { + ingoingNodes.push_back(node); + }); size_t const ingoingSize = ingoingNodes.size(); // If there is no routes inside target map. if (ingoingSize == 0) @@ -179,31 +187,24 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, { LOG(LDEBUG, ("Several nodes stores in one border point.", v.toNode.point)); vector ingoingNodes; - currentContext.GetAllIngoingNodes(ingoingNodes); - for(auto const & node : ingoingNodes) - { - if (node.m_nodeId == v.toNode.node) - { - ingoingNode = node; - break; - } - } + currentContext.ForEachIngoingNode([&ingoingNode, &v](IngoingCrossNode const & node) + { + if (node.m_nodeId == v.toNode.node) + ingoingNode = node; + }); } - vector outgoingNodes; - currentContext.GetAllOutgoingNodes(outgoingNodes); - // Find outs. Generate adjacency list. - for (auto const & node : outgoingNodes) - { - EdgeWeight const outWeight = currentContext.GetAdjacencyCost(ingoingNode, node); - if (outWeight != kInvalidContextEdgeWeight && outWeight != 0) - { - BorderCross target = FindNextMwmNode(node, currentMapping); - if (target.toNode.IsValid()) - adj.emplace_back(target, outWeight); - } - } + currentContext.ForEachOutgoingNode([&, this](OutgoingCrossNode const & node) + { + EdgeWeight const outWeight = currentContext.GetAdjacencyCost(ingoingNode, node); + if (outWeight != kInvalidContextEdgeWeight && outWeight != 0) + { + BorderCross target = FindNextMwmNode(node, currentMapping); + if (target.toNode.IsValid()) + adj.emplace_back(target, outWeight); + } + }); } double CrossMwmGraph::HeuristicCostEstimate(BorderCross const & v, BorderCross const & w) const diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 64410ebd5a..2e59af3084 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -3,13 +3,18 @@ #include "indexer/mercator.hpp" #include "indexer/point_to_int64.hpp" +namespace +{ +uint32_t constexpr kCoordBits = POINT_COORD_BITS; + +double constexpr kMwmCrossingNodeEqualityRadiusMeters = 5.0; +} // namespace + namespace routing { -static uint32_t const g_coordBits = POINT_COORD_BITS; - void OutgoingCrossNode::Save(Writer & w) const { - uint64_t point = PointToInt64(m2::PointD(m_point.lon, m_point.lat), g_coordBits); + uint64_t point = PointToInt64(m2::PointD(m_point.lon, m_point.lat), kCoordBits); char buff[sizeof(m_nodeId) + sizeof(point) + sizeof(m_outgoingIndex)]; *reinterpret_cast(&buff[0]) = m_nodeId; *reinterpret_cast(&(buff[sizeof(m_nodeId)])) = point; @@ -22,7 +27,7 @@ size_t OutgoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyInd char buff[sizeof(m_nodeId) + sizeof(uint64_t) + sizeof(m_outgoingIndex)]; r.Read(pos, buff, sizeof(buff)); m_nodeId = *reinterpret_cast(&buff[0]); - m2::PointD bufferPoint = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), g_coordBits); + m2::PointD bufferPoint = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), kCoordBits); m_point = ms::LatLon(bufferPoint.y, bufferPoint.x); m_outgoingIndex = *reinterpret_cast(&(buff[sizeof(m_nodeId) + sizeof(uint64_t)])); m_adjacencyIndex = adjacencyIndex; @@ -31,7 +36,7 @@ size_t OutgoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyInd void IngoingCrossNode::Save(Writer & w) const { - uint64_t point = PointToInt64(m2::PointD(m_point.lon, m_point.lat), g_coordBits); + uint64_t point = PointToInt64(m2::PointD(m_point.lon, m_point.lat), kCoordBits); char buff[sizeof(m_nodeId) + sizeof(point)]; *reinterpret_cast(&buff[0]) = m_nodeId; *reinterpret_cast(&(buff[sizeof(m_nodeId)])) = point; @@ -43,7 +48,7 @@ size_t IngoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyInde char buff[sizeof(m_nodeId) + sizeof(uint64_t)]; r.Read(pos, buff, sizeof(buff)); m_nodeId = *reinterpret_cast(&buff[0]); - m2::PointD bufferPoint = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), g_coordBits); + m2::PointD bufferPoint = Int64ToPoint(*reinterpret_cast(&(buff[sizeof(m_nodeId)])), kCoordBits); m_point = ms::LatLon(bufferPoint.y, bufferPoint.x); m_adjacencyIndex = adjacencyIndex; return pos + sizeof(buff); @@ -95,7 +100,8 @@ bool CrossRoutingContextReader::FindIngoingNodeByPoint(ms::LatLon const & point, IngoingCrossNode & node) const { bool found = false; - m_ingoingIndex.ForEachInRect(MercatorBounds::RectByCenterXYAndSizeInMeters({point.lat, point.lon}, 5), + m_ingoingIndex.ForEachInRect(MercatorBounds::RectByCenterXYAndSizeInMeters({point.lat, point.lon}, + kMwmCrossingNodeEqualityRadiusMeters), [&found, &node](IngoingCrossNode const & nd) { node = nd; @@ -124,21 +130,6 @@ TWrittenEdgeWeight CrossRoutingContextReader::GetAdjacencyCost(IngoingCrossNode return cost_index < m_adjacencyMatrix.size() ? m_adjacencyMatrix[cost_index] : kInvalidContextEdgeWeight; } -void CrossRoutingContextReader::GetAllIngoingNodes(vector & nodes) const -{ - m_ingoingIndex.ForEach([&nodes](IngoingCrossNode const & node) - { - nodes.push_back(node); - }); -} - -// It is not absolutelty effective, because we plan to change internal storage to avoid backward A* -// So we can't just return a reference. -void CrossRoutingContextReader::GetAllOutgoingNodes(vector & nodes) const -{ - nodes = m_outgoingNodes; -} - void CrossRoutingContextWriter::Save(Writer & w) const { uint32_t size = static_cast(m_ingoingNodes.size()); diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index 16a2707696..65e615c6ea 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -92,8 +92,11 @@ public: TWrittenEdgeWeight GetAdjacencyCost(IngoingCrossNode const & ingoing, OutgoingCrossNode const & outgoing) const; - void GetAllIngoingNodes(vector & nodes) const; - void GetAllOutgoingNodes(vector & nodes) const; + template + void ForEachIngoingNode(TFunctor f) const {m_ingoingIndex.ForEach(f);} + + template + void ForEachOutgoingNode(TFunctor f) const {for_each(m_outgoingNodes.cbegin(), m_outgoingNodes.cend(), f);} }; /// Helper class to generate cross context section in mwm.routing file diff --git a/routing/routing_integration_tests/cross_section_tests.cpp b/routing/routing_integration_tests/cross_section_tests.cpp index 9944730df0..3d0b5d166d 100644 --- a/routing/routing_integration_tests/cross_section_tests.cpp +++ b/routing/routing_integration_tests/cross_section_tests.cpp @@ -38,26 +38,23 @@ UNIT_TEST(CheckCrossSections) FilesMappingContainer container(file.GetPath(MapOptions::CarRouting)); crossReader.Load(container.GetReader(ROUTING_CROSS_CONTEXT_TAG)); - vector ingoingNodes; - crossReader.GetAllIngoingNodes(ingoingNodes); - for (auto const & node : ingoingNodes) - { - if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) - { - ingoingErrors++; - break; - } - } + bool error = false; + crossReader.ForEachIngoingNode([&error](IngoingCrossNode const & node) + { + if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) + error = true; + }); + if (error) + ingoingErrors++; - vector outgoingNodes; - for (auto const & node : outgoingNodes) - { - if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) - { - outgoingErrors++; - break; - } - } + error = false; + crossReader.ForEachOutgoingNode([&error](OutgoingCrossNode const & node) + { + if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) + error = true; + }); + if (error) + outgoingErrors++; } TEST_EQUAL(ingoingErrors, 0, ("Some countries have zero point incomes.")); TEST_EQUAL(outgoingErrors, 0, ("Some countries have zero point exits.")); diff --git a/routing/routing_tests/cross_routing_tests.cpp b/routing/routing_tests/cross_routing_tests.cpp index 58e3108081..f9c591ef57 100644 --- a/routing/routing_tests/cross_routing_tests.cpp +++ b/routing/routing_tests/cross_routing_tests.cpp @@ -56,13 +56,19 @@ UNIT_TEST(TestContextSerialization) MemReader reader(buffer.data(), buffer.size()); newContext.Load(reader); vector ingoingNodes; - newContext.GetAllIngoingNodes(ingoingNodes); + newContext.ForEachIngoingNode([&ingoingNodes](IngoingCrossNode const & node) + { + ingoingNodes.push_back(node); + }); TEST_EQUAL(ingoingNodes.size(), 2, ()); TEST_EQUAL(ingoingNodes[0].m_nodeId, 1, ()); TEST_EQUAL(ingoingNodes[1].m_nodeId, 2, ()); vector outgoingNodes; - newContext.GetAllOutgoingNodes(outgoingNodes); + newContext.ForEachOutgoingNode([&outgoingNodes](OutgoingCrossNode const & node) + { + outgoingNodes.push_back(node); + }); TEST_EQUAL(outgoingNodes.size(), 2, ()); TEST_EQUAL(outgoingNodes[0].m_nodeId, 3, ()); TEST_EQUAL(newContext.GetOutgoingMwmName(outgoingNodes[0]), string("foo"), ()); @@ -95,9 +101,15 @@ UNIT_TEST(TestAdjacencyMatrix) MemReader reader(buffer.data(), buffer.size()); newContext.Load(reader); vector ingoingNodes; - newContext.GetAllIngoingNodes(ingoingNodes); + newContext.ForEachIngoingNode([&ingoingNodes](IngoingCrossNode const & node) + { + ingoingNodes.push_back(node); + }); vector outgoingNodes; - newContext.GetAllOutgoingNodes(outgoingNodes); + newContext.ForEachOutgoingNode([&outgoingNodes](OutgoingCrossNode const & node) + { + outgoingNodes.push_back(node); + }); TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[0], outgoingNodes[0]), 5, ()); TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[1], outgoingNodes[0]), 9, ()); TEST_EQUAL(newContext.GetAdjacencyCost(ingoingNodes[2], outgoingNodes[0]), From c3ce5330d082c34c297c6f67c803af008b054dea Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Fri, 30 Oct 2015 16:09:53 +0300 Subject: [PATCH 11/11] PR fix. --- routing/cross_mwm_road_graph.cpp | 1 - routing/cross_routing_context.cpp | 8 +++++--- routing/cross_routing_context.hpp | 10 ++++++++-- .../routing_integration_tests/cross_section_tests.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 273ad99f51..330eb8a12b 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -186,7 +186,6 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, if (ingoingNode.m_nodeId != v.toNode.node) { LOG(LDEBUG, ("Several nodes stores in one border point.", v.toNode.point)); - vector ingoingNodes; currentContext.ForEachIngoingNode([&ingoingNode, &v](IngoingCrossNode const & node) { if (node.m_nodeId == v.toNode.node) diff --git a/routing/cross_routing_context.cpp b/routing/cross_routing_context.cpp index 2e59af3084..9705abe141 100644 --- a/routing/cross_routing_context.cpp +++ b/routing/cross_routing_context.cpp @@ -7,7 +7,7 @@ namespace { uint32_t constexpr kCoordBits = POINT_COORD_BITS; -double constexpr kMwmCrossingNodeEqualityRadiusMeters = 5.0; +double constexpr kMwmCrossingNodeEqualityRadiusDegrees = 0.001; } // namespace namespace routing @@ -100,8 +100,10 @@ bool CrossRoutingContextReader::FindIngoingNodeByPoint(ms::LatLon const & point, IngoingCrossNode & node) const { bool found = false; - m_ingoingIndex.ForEachInRect(MercatorBounds::RectByCenterXYAndSizeInMeters({point.lat, point.lon}, - kMwmCrossingNodeEqualityRadiusMeters), + m_ingoingIndex.ForEachInRect(m2::RectD(point.lat - kMwmCrossingNodeEqualityRadiusDegrees, + point.lon - kMwmCrossingNodeEqualityRadiusDegrees, + point.lat + kMwmCrossingNodeEqualityRadiusDegrees, + point.lon + kMwmCrossingNodeEqualityRadiusDegrees), [&found, &node](IngoingCrossNode const & nd) { node = nd; diff --git a/routing/cross_routing_context.hpp b/routing/cross_routing_context.hpp index 65e615c6ea..c50cb7e37d 100644 --- a/routing/cross_routing_context.hpp +++ b/routing/cross_routing_context.hpp @@ -93,10 +93,16 @@ public: OutgoingCrossNode const & outgoing) const; template - void ForEachIngoingNode(TFunctor f) const {m_ingoingIndex.ForEach(f);} + void ForEachIngoingNode(TFunctor f) const + { + m_ingoingIndex.ForEach(f); + } template - void ForEachOutgoingNode(TFunctor f) const {for_each(m_outgoingNodes.cbegin(), m_outgoingNodes.cend(), f);} + void ForEachOutgoingNode(TFunctor f) const + { + for_each(m_outgoingNodes.cbegin(), m_outgoingNodes.cend(), f); + } }; /// Helper class to generate cross context section in mwm.routing file diff --git a/routing/routing_integration_tests/cross_section_tests.cpp b/routing/routing_integration_tests/cross_section_tests.cpp index 3d0b5d166d..6a5b89dda0 100644 --- a/routing/routing_integration_tests/cross_section_tests.cpp +++ b/routing/routing_integration_tests/cross_section_tests.cpp @@ -41,8 +41,8 @@ UNIT_TEST(CheckCrossSections) bool error = false; crossReader.ForEachIngoingNode([&error](IngoingCrossNode const & node) { - if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) - error = true; + if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) + error = true; }); if (error) ingoingErrors++; @@ -50,8 +50,8 @@ UNIT_TEST(CheckCrossSections) error = false; crossReader.ForEachOutgoingNode([&error](OutgoingCrossNode const & node) { - if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) - error = true; + if (node.m_point.EqualDxDy(ms::LatLon::Zero(), kPointEquality)) + error = true; }); if (error) outgoingErrors++;