Remove IngoingCrossNode duplication inside a CrossRoutingContext class.

This commit is contained in:
Lev Dragunov 2015-10-26 16:38:38 +03:00
parent b9349c6ece
commit 4f3964bd76
7 changed files with 64 additions and 77 deletions

View file

@ -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<IngoingCrossNode> 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<EdgeWeight> 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<IngoingCrossNode> 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<BorderCross> 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);
}

View file

@ -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;
}
};

View file

@ -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<IngoingEdgeIteratorT, IngoingEdgeIteratorT> CrossRoutingContextReader::GetIngoingIterators()
const
{
return make_pair(m_ingoingNodes.cbegin(), m_ingoingNodes.cend());
}
pair<OutgoingEdgeIteratorT, OutgoingEdgeIteratorT> 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<IngoingCrossNode> & nodes) const
{
m_ingoingIndex.ForEach([&nodes](IngoingCrossNode const & node)
{
nodes.push_back(node);
});
}
void CrossRoutingContextWriter::Save(Writer & w) const
{
uint32_t size = static_cast<uint32_t>(m_ingoingNodes.size());

View file

@ -77,7 +77,6 @@ using OutgoingEdgeIteratorT = vector<OutgoingCrossNode>::const_iterator;
class CrossRoutingContextReader
{
vector<OutgoingCrossNode> m_outgoingNodes;
vector<IngoingCrossNode> m_ingoingNodes;
vector<string> m_neighborMwmList;
vector<WritedEdgeWeightT> m_adjacencyMatrix;
m4::Tree<IngoingCrossNode> m_ingoingIndex;
@ -87,14 +86,14 @@ public:
const string & GetOutgoingMwmName(OutgoingCrossNode const & mwmIndex) const;
pair<IngoingEdgeIteratorT, IngoingEdgeIteratorT> GetIngoingIterators() const;
bool FindIngoingNodeByPoint(m2::PointD const & point, IngoingCrossNode & node) const;
pair<OutgoingEdgeIteratorT, OutgoingEdgeIteratorT> GetOutgoingIterators() const;
WritedEdgeWeightT GetAdjacencyCost(IngoingCrossNode const & ingoing,
OutgoingCrossNode const & outgoing) const;
void GetAllIngoingNodes(vector<IngoingCrossNode> & nodes) const;
};
/// Helper class to generate cross context section in mwm.routing file

View file

@ -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

View file

@ -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<IngoingCrossNode> 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)
{

View file

@ -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<IngoingCrossNode> 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<IngoingCrossNode> 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"));
}