first international road

This commit is contained in:
Lev Dragunov 2015-01-28 17:18:39 +03:00 committed by Alex Zolotarev
parent 34f5f3f906
commit ef052e433e
3 changed files with 166 additions and 9 deletions

View file

@ -35,6 +35,15 @@ public:
return make_pair(m_outgoingNodes.cbegin(), m_outgoingNodes.cend());
}
int getAdjacencyCost(std::vector<size_t>::const_iterator ingoing_iter, std::vector<std::pair<size_t,size_t>>::const_iterator outgoin_iter) const
{
size_t ingoing_index = std::distance(m_ingoingNodes.cbegin(), ingoing_iter);
size_t outgoing_index = std::distance(m_outgoingNodes.cbegin(), outgoin_iter);
ASSERT_LESS(ingoing_index, m_ingoingNodes.size(), ("ingoing index out of range"));
ASSERT_LESS(outgoing_index, m_outgoingNodes.size(), ("outgoing index out of range"));
return m_adjacencyMatrix[m_ingoingNodes.size() * ingoing_index + outgoing_index];
}
void Load(Reader const & r)
{
size_t size, pos=0;

View file

@ -26,6 +26,8 @@
#include "../3party/osrm/osrm-backend/RoutingAlgorithms/ShortestPathRouting.h"
#include "../3party/osrm/osrm-backend/RoutingAlgorithms/ManyToManyRouting.h"
#include "../std/queue.hpp"
namespace routing
{
@ -824,10 +826,18 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt
EdgeWeight finalWeight = numeric_limits<EdgeWeight>::max();
CheckedPathT finalPath;
struct pathChecker{
bool operator() (CheckedPathT const & a, CheckedPathT const & b) const {
return getPathWeight(b)<getPathWeight(a); // backward sort
}
};
priority_queue<CheckedPathT, vector<CheckedPathT>, pathChecker> crossTasks;
CheckedOutsT checkedOuts;
for (size_t i=0; i<sources.size(); ++i)
{
@ -838,6 +848,7 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt
{
found = true;
string const & nextMwm = startContext.getOutgoingMwmName((out_iterators.first+j)->second);
LOG(LINFO, ("Next mwm", nextMwm));
RoutingMappingPtrT nextMapping;
try
{
@ -852,7 +863,17 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt
size_t nextNodeId = FindNextMwmNode(startMapping, tNodeId, nextMapping);
if(!nextNodeId)
continue;
if (nextMwm == finalMapping->GetName())
checkedOuts.insert(make_pair(tNodeId, startMapping->GetName()));
if (nextMwm != finalMapping->GetName())
{
CheckedPathT tmpPath;
FeatureGraphNode tmpNode;
OsrmRouter::GenerateRoutingTaskFromNodeId(nextNodeId, tmpNode);
tmpPath.push_back({startMapping->GetName(), sources[i], targets[j], weights[ i*sources.size() + j]});
tmpPath.push_back({nextMapping->GetName(), tmpNode, tmpNode, 0});
crossTasks.push(tmpPath);
}
else
{
auto it = income_iterators.second;
for (auto k=income_iterators.first; k < income_iterators.second; ++k)
@ -863,7 +884,7 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt
if (it == income_iterators.second)
continue;
int p=0;
size_t targetWeight = target_weights[distance(income_iterators.first, it)];
EdgeWeight targetWeight = target_weights[distance(income_iterators.first, it)];
if (targetWeight == numeric_limits<EdgeWeight>::max())
for (p=1; p<income_sources.size(); ++p)
{
@ -878,8 +899,8 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt
{
finalWeight = newWeight;
finalPath.clear();
finalPath.push_back({startMapping->GetName(), sources[i], targets[j]});
finalPath.push_back({finalMapping->GetName(), income_sources[distance(income_iterators.first, it)], income_targets[p]});
finalPath.push_back({startMapping->GetName(), sources[i], targets[j], weights[ i*sources.size() + j]});
finalPath.push_back({finalMapping->GetName(), income_sources[distance(income_iterators.first, it)], income_targets[p], targetWeight});
}
}
}
@ -888,9 +909,129 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt
break;
}
if (crossTasks.size())
{
while (getPathWeight(crossTasks.top())<finalWeight)
{
CheckedPathT const & topTask = crossTasks.top();
RoutePathCross const & cross = topTask.back();
RoutingMappingPtrT currentMapping;
try
{
currentMapping = m_indexManager.GetMappingByName(cross.mwmName, m_pIndex);
}
catch (OsrmRouter::ResultCode e)
{
crossTasks.pop();
continue; //There is no outgoing mwm
}
currentMapping->LoadFacade();
currentMapping->Map();
CrossRoutingContext const & currentContext = currentMapping->dataFacade.getRoutingContext();
auto current_in_iterators = currentContext.GetIngoingIterators();
auto current_out_iterators = currentContext.GetOutgoingIterators();
//find income number
//auto const iit = find(current_in_iterators.first, current_in_iterators.second, cross.startNode.m_node.forward_node_id);
auto iit = current_in_iterators.second;
for (auto q = current_in_iterators.first; q<current_in_iterators.second; ++q)
if (*q==cross.startNode.m_node.forward_node_id)
{
iit = q;
break;
}
ASSERT(iit != current_in_iterators.second, ());
//find outs
for (auto oit=current_out_iterators.first; oit!= current_out_iterators.second; ++oit)
{
const EdgeWeight outWeight = currentContext.getAdjacencyCost(iit, oit);
if (outWeight != numeric_limits<EdgeWeight>::max())
{
if (getPathWeight(topTask)+outWeight < finalWeight)
{
string const & nextMwm = currentContext.getOutgoingMwmName(oit->second);
RoutingMappingPtrT nextMapping;
try
{
nextMapping = m_indexManager.GetMappingByName(nextMwm, m_pIndex);
}
catch (OsrmRouter::ResultCode e)
{
continue; //There is no outgoing mwm
}
nextMapping->Map();
nextMapping->LoadFacade();
size_t tNodeId = oit->first;
auto const outNode = make_pair(tNodeId, startMapping->GetName());
if (checkedOuts.find(outNode)!=checkedOuts.end())
continue;
checkedOuts.insert(outNode);
size_t nextNodeId = FindNextMwmNode(currentMapping, tNodeId, nextMapping);
if(!nextNodeId)
continue;
if (nextMwm != finalMapping->GetName())
{
CheckedPathT tmpPath(crossTasks.top());
crossTasks.pop();
FeatureGraphNode startNode, stopNode, tmpNode;
OsrmRouter::GenerateRoutingTaskFromNodeId(nextNodeId, tmpNode);
OsrmRouter::GenerateRoutingTaskFromNodeId(*iit, startNode);
OsrmRouter::GenerateRoutingTaskFromNodeId(oit->first, stopNode);
tmpPath.push_back({currentMapping->GetName(), startNode, stopNode, outWeight});
tmpPath.push_back({nextMapping->GetName(), tmpNode, tmpNode, 0});
crossTasks.push(tmpPath);
}
else
{
auto it = income_iterators.second;
for (auto k=income_iterators.first; k < income_iterators.second; ++k)
{
if (*k==nextNodeId)
it=k;
}
if (it == income_iterators.second)
continue;
int p=0;
EdgeWeight targetWeight = target_weights[distance(income_iterators.first, it)];
if (targetWeight == numeric_limits<EdgeWeight>::max())
for (p=1; p<income_sources.size(); ++p)
{
targetWeight = target_weights[p*income_targets.size()+distance(income_iterators.first, it)];
if (targetWeight != numeric_limits<EdgeWeight>::max())
break;
}
if (targetWeight == numeric_limits<EdgeWeight>::max())
continue;
const EdgeWeight newWeight = getPathWeight(topTask) + outWeight + targetWeight;
if (newWeight<finalWeight)
{
finalWeight = newWeight;
finalPath = CheckedPathT(crossTasks.top());
finalPath.pop_back();
FeatureGraphNode startNode, stopNode;
OsrmRouter::GenerateRoutingTaskFromNodeId(*iit, startNode);
OsrmRouter::GenerateRoutingTaskFromNodeId(oit->first, stopNode);
finalPath.push_back({currentMapping->GetName(), startNode, stopNode, outWeight});
finalPath.push_back({finalMapping->GetName(), income_sources[distance(income_iterators.first, it)], income_targets[p], targetWeight});
}
}
}
}
}
//CrossRoutingContext const & targetContext = finalMapping->dataFacade.getRoutingContext();
//auto income_iterators = targetContext.GetIngoingIterators();
crossTasks.pop();
if (!crossTasks.size())
break;
}
}
LOG(LINFO, ("Facade data", startMapping->dataFacade.GetNumberOfNodes()));
startMapping->Unmap();
startMapping->FreeFacade();
if (finalWeight< numeric_limits<EdgeWeight>::max())
return MakeRouteFromCrossesPath(finalPath, route);
else

View file

@ -9,6 +9,7 @@
#include "../base/mutex.hpp"
#include "../std/function.hpp"
#include "../std/numeric.hpp"
#include "../std/atomic.hpp"
#include "../3party/osrm/osrm-backend/DataStructures/QueryEdge.h"
@ -239,15 +240,21 @@ protected:
ResultCode CalculateRouteImpl(m2::PointD const & startPt, m2::PointD const & startDr, m2::PointD const & finalPt, Route & route);
private:
typedef pair<size_t,string> MwmOut;
typedef set<MwmOut> CheckedOuts;
typedef pair<size_t,string> MwmOutT;
typedef set<MwmOutT> CheckedOutsT;
struct RoutePathCross {
string mwmName;
FeatureGraphNode startNode;
FeatureGraphNode targetNode;
EdgeWeight weight;
};
typedef vector<RoutePathCross> CheckedPathT;
static EdgeWeight getPathWeight(CheckedPathT const & path)
{
return accumulate(path.begin(), path.end(), 0, [](EdgeWeight sum, RoutePathCross const & elem){return sum+elem.weight;});
}
ResultCode MakeRouteFromCrossesPath(CheckedPathT const & path, Route & route);
NodeID GetTurnTargetNode(NodeID src, NodeID trg, QueryEdge::EdgeData const & edgeData, RoutingMappingPtrT const & routingMapping);
void GetPossibleTurns(NodeID node,