forked from organicmaps/organicmaps
Remove IngoingCrossNode duplication inside a CrossRoutingContext class.
This commit is contained in:
parent
b9349c6ece
commit
4f3964bd76
7 changed files with 64 additions and 77 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue