MwmId usage inside a cross mwm road graph.

This commit is contained in:
Lev Dragunov 2015-10-27 18:00:48 +03:00
parent 17f7099da6
commit af001ed07b
15 changed files with 77 additions and 64 deletions

View file

@ -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<EdgeWeight> costs;

View file

@ -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<EdgeWeight> 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<CrossWeightedEdge> 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<EdgeWeight> 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<BorderCross> 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<BorderCross> 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

View file

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

View file

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

View file

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

View file

@ -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<IngoingCrossNode> & 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,

View file

@ -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<WritedEdgeWeightT>::max();
static WritedEdgeWeightT const INVALID_CONTEXT_EDGE_NODE_ID = std::numeric_limits<uint32_t>::max();
static size_t constexpr kInvalidAdjacencyIndex = numeric_limits<size_t>::max();
WritedEdgeWeightT constexpr kInvalidContextEdgeNodeId = std::numeric_limits<uint32_t>::max();
WritedEdgeWeightT constexpr kInvalidContextEdgeWeight = std::numeric_limits<WritedEdgeWeightT>::max();
size_t constexpr kInvalidAdjacencyIndex = numeric_limits<size_t>::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)
{

View file

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

View file

@ -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();

View file

@ -189,8 +189,7 @@ EdgeWeight Point2PhantomNode::GetMinNodeWeight(NodeID node, m2::PointD const & p
return minWeight;
}
void Point2PhantomNode::MakeResult(vector<FeatureGraphNode> & res, size_t maxCount,
string const & mwmName)
void Point2PhantomNode::MakeResult(vector<FeatureGraphNode> & res, size_t maxCount)
{
vector<OsrmMappingTypes::FtSeg> segments;
@ -258,14 +257,14 @@ void Point2PhantomNode::MakeResult(vector<FeatureGraphNode> & 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());
}

View file

@ -49,7 +49,7 @@ public:
void operator()(FeatureType const & ft);
/// Makes OSRM tasks result vector.
void MakeResult(vector<FeatureGraphNode> & res, size_t maxCount, string const & mwmName);
void MakeResult(vector<FeatureGraphNode> & res, size_t maxCount);
private:
// Calculates distance in meters on the feature from startPoint to endPoint.

View file

@ -163,9 +163,9 @@ OsrmRouter::ResultCode OsrmRouter::MakeRouteFromCrossesPath(TCheckedPath const &
vector<m2::PointD> 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;
}

View file

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

View file

@ -106,6 +106,8 @@ public:
TRoutingMappingPtr GetMappingByName(string const & mapName);
TRoutingMappingPtr GetMappingById(Index::MwmId const & id);
template <class TFunctor>
void ForEachMapping(TFunctor toDo)
{
@ -116,6 +118,7 @@ public:
private:
TCountryFileFn m_countryFileFn;
// TODO (ldragunov) Rewrite to mwmId.
unordered_map<string, TRoutingMappingPtr> m_mapping;
MwmSet & m_index;
};

View file

@ -14,23 +14,22 @@ namespace
// Graph to convertions.
UNIT_TEST(TestCrossRouteConverter)
{
Index::MwmId aMap, bMap;
vector<BorderCross> 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"));
}
}