forked from organicmaps/organicmaps
BorderCross now separate structure
This commit is contained in:
parent
944e7766ff
commit
893231c309
3 changed files with 71 additions and 64 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Add table
Reference in a new issue