BorderCross now separate structure

This commit is contained in:
Lev Dragunov 2015-06-01 12:31:40 +03:00 committed by Alex Zolotarev
parent 944e7766ff
commit 893231c309
3 changed files with 71 additions and 64 deletions

View file

@ -23,20 +23,19 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode)
// Load source data.
auto const mwmOutsIter = startMapping->m_crossContext.GetOutgoingIterators();
// Generate routing task from one source to several targets.
TRoutingNodes sources(1), targets;
size_t const outSize = distance(mwmOutsIter.first, mwmOutsIter.second);
targets.reserve(outSize);
// If there is no routes outside source map.
// Can't find the route if there is no routes outside source map.
if (!outSize)
return IRouter::RouteNotFound;
// 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);
vector<EdgeWeight> weights;
sources[0] = FeatureGraphNode(startNode.node, true /* isStartNode */, startNode.mwmName);
vector<EdgeWeight> weights;
FindWeightsMatrix(sources, targets, startMapping->m_dataFacade, weights);
if (find_if(weights.begin(), weights.end(), &IsValidEdgeWeight) == weights.end())
return IRouter::StartPointNotFound;
@ -45,8 +44,8 @@ IRouter::ResultCode CrossMwmGraph::SetStartNode(CrossNode const & startNode)
{
if (IsValidEdgeWeight(weights[i]))
{
TCrossPair nextNode = FindNextMwmNode(*(mwmOutsIter.first + i), startMapping);
if (nextNode.second.IsValid())
BorderCross nextNode = FindNextMwmNode(*(mwmOutsIter.first + i), startMapping);
if (nextNode.toNode.IsValid())
dummyEdges.emplace_back(nextNode, weights[i]);
}
}
@ -90,14 +89,14 @@ IRouter::ResultCode CrossMwmGraph::SetFinalNode(CrossNode const & finalNode)
CrossNode start(iNode.m_nodeId, finalNode.mwmName,
MercatorBounds::FromLatLon(iNode.m_point.y, iNode.m_point.x));
vector<CrossWeightedEdge> dummyEdges;
dummyEdges.emplace_back(make_pair(finalNode, finalNode), weights[i]);
dummyEdges.emplace_back(BorderCross(finalNode, finalNode), weights[i]);
m_virtualEdges.insert(make_pair(start, dummyEdges));
}
}
return IRouter::NoError;
}
TCrossPair CrossMwmGraph::FindNextMwmNode(OutgoingCrossNode const & startNode,
BorderCross CrossMwmGraph::FindNextMwmNode(OutgoingCrossNode const & startNode,
TRoutingMappingPtr const & currentMapping) const
{
m2::PointD const & startPoint = startNode.m_point;
@ -107,37 +106,39 @@ TCrossPair CrossMwmGraph::FindNextMwmNode(OutgoingCrossNode const & startNode,
nextMapping = m_indexManager.GetMappingByName(nextMwm);
// If we haven't this routing file, we skip this path.
if (!nextMapping->IsValid())
return TCrossPair();
return BorderCross();
nextMapping->LoadCrossContext();
auto income_iters = nextMapping->m_crossContext.GetIngoingIterators();
for (auto i = income_iters.first; i < income_iters.second; ++i)
auto incomeIters = nextMapping->m_crossContext.GetIngoingIterators();
for (auto i = incomeIters.first; i < incomeIters.second; ++i)
{
m2::PointD const & targetPoint = i->m_point;
if (ms::DistanceOnEarth(startPoint.y, startPoint.x, targetPoint.y, targetPoint.x) <
kMwmCrossingNodeEqualityRadiusMeters)
return make_pair(CrossNode(startNode.m_nodeId, currentMapping->GetName(),
MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x)),
CrossNode(i->m_nodeId, nextMwm,
MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x)));
{
return BorderCross(CrossNode(startNode.m_nodeId, currentMapping->GetName(),
MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x)),
CrossNode(i->m_nodeId, nextMwm,
MercatorBounds::FromLatLon(targetPoint.y, targetPoint.x)));
}
}
return TCrossPair();
return BorderCross();
}
void CrossMwmGraph::GetOutgoingEdgesListImpl(TCrossPair const & v,
void CrossMwmGraph::GetOutgoingEdgesListImpl(BorderCross const & v,
vector<CrossWeightedEdge> & adj) const
{
// Check for virtual edges.
adj.clear();
auto const it = m_virtualEdges.find(v.second);
auto const it = m_virtualEdges.find(v.toNode);
if (it != m_virtualEdges.end())
{
adj.insert(adj.end(), it->second.begin(), it->second.end());
return;
}
// Loading cross roating section.
TRoutingMappingPtr currentMapping = m_indexManager.GetMappingByName(v.second.mwmName);
// Loading cross routing section.
TRoutingMappingPtr currentMapping = m_indexManager.GetMappingByName(v.toNode.mwmName);
ASSERT(currentMapping->IsValid(), ());
currentMapping->LoadCrossContext();
@ -146,31 +147,31 @@ void CrossMwmGraph::GetOutgoingEdgesListImpl(TCrossPair const & v,
auto outRange = currentContext.GetOutgoingIterators();
// Find income node.
auto iit = inRange.first;
while (iit != inRange.second)
auto inIt = inRange.first;
while (inIt != inRange.second)
{
if (iit->m_nodeId == v.second.node)
if (inIt->m_nodeId == v.toNode.node)
break;
++iit;
++inIt;
}
CHECK(iit != inRange.second, ());
CHECK(inIt != inRange.second, ());
// Find outs. Generate adjacency list.
for (auto oit = outRange.first; oit != outRange.second; ++oit)
for (auto oitIt = outRange.first; oitIt != outRange.second; ++oitIt)
{
EdgeWeight const outWeight = currentContext.GetAdjacencyCost(iit, oit);
EdgeWeight const outWeight = currentContext.GetAdjacencyCost(inIt, oitIt);
if (outWeight != INVALID_CONTEXT_EDGE_WEIGHT && outWeight != 0)
{
TCrossPair target = FindNextMwmNode(*oit, currentMapping);
if (target.second.IsValid())
BorderCross target = FindNextMwmNode(*oitIt, currentMapping);
if (target.toNode.IsValid())
adj.emplace_back(target, outWeight);
}
}
}
double CrossMwmGraph::HeuristicCostEstimateImpl(TCrossPair const & v, TCrossPair const & w) const
double CrossMwmGraph::HeuristicCostEstimateImpl(BorderCross const & v, BorderCross const & w) const
{
return ms::DistanceOnEarth(v.second.point.y, v.second.point.x,
w.second.point.y, w.second.point.x) / kMediumSpeedMPS;
return ms::DistanceOnEarth(v.toNode.point.y, v.toNode.point.x,
w.toNode.point.y, w.toNode.point.x) / kMediumSpeedMPS;
}
} // namespace routing

View file

@ -4,10 +4,10 @@
#include "osrm_router.hpp"
#include "router.hpp"
#include "base/graph.hpp"
#include "indexer/index.hpp"
#include "base/graph.hpp"
namespace routing
{
/// OSRM graph node representation with graph mwm name and border crossing point.
@ -21,6 +21,7 @@ struct CrossNode
: node(node), mwmName(mwmName), point(point)
{
}
CrossNode() : node(INVALID_NODE_ID), point(m2::PointD::Zero()) {}
inline bool IsValid() const { return node != INVALID_NODE_ID; }
@ -33,11 +34,9 @@ inline bool operator==(CrossNode const & a, CrossNode const & b)
inline bool operator<(CrossNode const & a, CrossNode const & b)
{
if (a.node < b.node)
return true;
else if (a.node == b.node)
return a.mwmName < b.mwmName;
return false;
if (a.node != b.node)
return a.node < b.node;
return a.mwmName < b.mwmName;
}
inline string DebugPrint(CrossNode const & t)
@ -48,16 +47,23 @@ inline string DebugPrint(CrossNode const & t)
}
/// Representation of border crossing. Contains node on previous map and node on next map.
using TCrossPair = pair<CrossNode, CrossNode>;
struct BorderCross
{
CrossNode fromNode;
CrossNode toNode;
inline bool operator==(TCrossPair const & a, TCrossPair const & b) { return a.first == b.first; }
BorderCross(CrossNode const & from, CrossNode const & to) : fromNode(from), toNode(to) {}
BorderCross() : fromNode(), toNode() {}
};
inline bool operator<(TCrossPair const & a, TCrossPair const & b) { return a.first < b.first; }
inline bool operator==(BorderCross const & a, BorderCross const & b) { return a.toNode == b.toNode; }
inline string DebugPrint(TCrossPair const & t)
inline bool operator<(BorderCross const & a, BorderCross const & b) { return a.toNode < b.toNode; }
inline string DebugPrint(BorderCross const & t)
{
ostringstream out;
out << "Border cross form: " << DebugPrint(t.first) << " to: " << DebugPrint(t.second) << "\n";
out << "Border cross from: " << DebugPrint(t.fromNode) << " to: " << DebugPrint(t.toNode) << "\n";
return out.str();
}
@ -65,18 +71,18 @@ inline string DebugPrint(TCrossPair const & t)
class CrossWeightedEdge
{
public:
explicit CrossWeightedEdge(TCrossPair const & target, double weight) : target(target), weight(weight) {}
CrossWeightedEdge(BorderCross const & target, double weight) : target(target), weight(weight) {}
inline TCrossPair const & GetTarget() const { return target; }
inline BorderCross const & GetTarget() const { return target; }
inline double GetWeight() const { return weight; }
private:
TCrossPair target;
BorderCross target;
double weight;
};
/// A graph used for cross mwm routing.
class CrossMwmGraph : public Graph<TCrossPair, CrossWeightedEdge, CrossMwmGraph>
class CrossMwmGraph : public Graph<BorderCross, CrossWeightedEdge, CrossMwmGraph>
{
public:
explicit CrossMwmGraph(RoutingIndexManager & indexManager) : m_indexManager(indexManager) {}
@ -85,19 +91,19 @@ public:
IRouter::ResultCode SetFinalNode(CrossNode const & finalNode);
private:
friend class Graph<TCrossPair, CrossWeightedEdge, CrossMwmGraph>;
friend class Graph<BorderCross, CrossWeightedEdge, CrossMwmGraph>;
TCrossPair FindNextMwmNode(OutgoingCrossNode const & startNode,
BorderCross FindNextMwmNode(OutgoingCrossNode const & startNode,
TRoutingMappingPtr const & currentMapping) const;
// Graph<CrossNode, CrossWeightedEdge, CrossMwmGraph> implementation:
void GetOutgoingEdgesListImpl(TCrossPair const & v, vector<CrossWeightedEdge> & adj) const;
void GetIngoingEdgesListImpl(TCrossPair const & v, vector<CrossWeightedEdge> & adj) const
// Graph<BorderCross, CrossWeightedEdge, CrossMwmGraph> implementation:
void GetOutgoingEdgesListImpl(BorderCross const & v, vector<CrossWeightedEdge> & adj) const;
void GetIngoingEdgesListImpl(BorderCross const & v, vector<CrossWeightedEdge> & adj) const
{
ASSERT(!"IMPL", ());
}
double HeuristicCostEstimateImpl(TCrossPair const & v, TCrossPair const & w) const;
double HeuristicCostEstimateImpl(BorderCross const & v, BorderCross const & w) const;
map<CrossNode, vector<CrossWeightedEdge> > m_virtualEdges;
mutable RoutingIndexManager m_indexManager;

View file

@ -7,8 +7,8 @@ namespace routing
using TAlgorithm = AStarAlgorithm<CrossMwmGraph>;
/// Function to run AStar Algorithm from the base.
IRouter::ResultCode CalculateRoute(TCrossPair const & startPos, TCrossPair const & finalPos,
CrossMwmGraph const & roadGraph, vector<TCrossPair> & route,
IRouter::ResultCode CalculateRoute(BorderCross const & startPos, BorderCross const & finalPos,
CrossMwmGraph const & roadGraph, vector<BorderCross> & route,
RoutingVisualizerFn const & routingVisualizer)
{
TAlgorithm m_algo;
@ -17,9 +17,9 @@ IRouter::ResultCode CalculateRoute(TCrossPair const & startPos, TCrossPair const
TAlgorithm::OnVisitedVertexCallback onVisitedVertex = nullptr;
if (routingVisualizer)
{
onVisitedVertex = [&routingVisualizer](TCrossPair const & cross)
onVisitedVertex = [&routingVisualizer](BorderCross const & cross)
{
routingVisualizer(cross.first.point);
routingVisualizer(cross.fromNode.point);
};
}
@ -79,7 +79,7 @@ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes,
return IRouter::EndPointNotFound;
// Finding path through maps.
vector<TCrossPair> tempRoad;
vector<BorderCross> tempRoad;
code = CalculateRoute({startNode, startNode}, {finalNode, finalNode}, roadGraph, tempRoad,
routingVisualizer);
if (code != IRouter::NoError)
@ -88,8 +88,8 @@ IRouter::ResultCode CalculateCrossMwmPath(TRoutingNodes const & startGraphNodes,
// Final path conversion to output type.
for (size_t i = 0; i < tempRoad.size() - 1; ++i)
{
route.emplace_back(tempRoad[i].second.node, tempRoad[i + 1].first.node,
tempRoad[i].second.mwmName);
route.emplace_back(tempRoad[i].toNode.node, tempRoad[i + 1].fromNode.node,
tempRoad[i].toNode.mwmName);
}
if (!route.empty())