This commit is contained in:
DennisOSRM 2011-12-31 16:19:00 +01:00
commit 44c07e9504
9 changed files with 475 additions and 485 deletions

View File

@ -41,529 +41,526 @@ or see http://www.gnu.org/licenses/agpl.txt.
class Contractor { class Contractor {
private: private:
struct _EdgeBasedContractorEdgeData { struct _EdgeBasedContractorEdgeData {
unsigned distance; unsigned distance;
unsigned originalEdges; unsigned originalEdges;
unsigned via; unsigned via;
unsigned nameID; unsigned nameID;
short turnInstruction; short turnInstruction;
bool shortcut:1; bool shortcut:1;
bool forward:1; bool forward:1;
bool backward:1; bool backward:1;
} data; } data;
struct _HeapData { struct _HeapData {
bool target; bool target;
_HeapData() : target(false) {} _HeapData() : target(false) {}
_HeapData( bool t ) : target(t) {} _HeapData( bool t ) : target(t) {}
}; };
typedef DynamicGraph< _EdgeBasedContractorEdgeData > _DynamicGraph; typedef DynamicGraph< _EdgeBasedContractorEdgeData > _DynamicGraph;
typedef BinaryHeap< NodeID, NodeID, int, _HeapData> _Heap; typedef BinaryHeap< NodeID, NodeID, int, _HeapData> _Heap;
typedef _DynamicGraph::InputEdge _ImportEdge; typedef _DynamicGraph::InputEdge _ImportEdge;
struct _ThreadData { struct _ThreadData {
_Heap heap; _Heap heap;
std::vector< _ImportEdge > insertedEdges; std::vector< _ImportEdge > insertedEdges;
std::vector< NodeID > neighbours; std::vector< NodeID > neighbours;
_ThreadData( NodeID nodes ): heap( nodes ) { _ThreadData( NodeID nodes ): heap( nodes ) {
} }
}; };
struct _PriorityData { struct _PriorityData {
int depth; int depth;
NodeID bias; NodeID bias;
_PriorityData() : depth(0), bias(0) { } _PriorityData() : depth(0), bias(0) { }
}; };
struct _ContractionInformation { struct _ContractionInformation {
int edgesDeleted; int edgesDeleted;
int edgesAdded; int edgesAdded;
int originalEdgesDeleted; int originalEdgesDeleted;
int originalEdgesAdded; int originalEdgesAdded;
_ContractionInformation() { _ContractionInformation() : edgesDeleted(0), edgesAdded(0), originalEdgesDeleted(0), originalEdgesAdded(0) {}
edgesAdded = edgesDeleted = originalEdgesAdded = originalEdgesDeleted = 0; };
}
};
struct _NodePartitionor { struct _NodePartitionor {
bool operator()( std::pair< NodeID, bool > nodeData ) { bool operator()( std::pair< NodeID, bool > nodeData ) {
return !nodeData.second; return !nodeData.second;
} }
}; };
public: public:
template< class InputEdge > template< class InputEdge >
Contractor( int nodes, std::vector< InputEdge >& inputEdges, unsigned eqf = 2, unsigned oqf = 1, unsigned df = 1) : edgeQuotionFactor(eqf), originalQuotientFactor(oqf), depthFactor(df) { Contractor( int nodes, std::vector< InputEdge >& inputEdges, unsigned eqf = 2, unsigned oqf = 1, unsigned df = 1) : edgeQuotionFactor(eqf), originalQuotientFactor(oqf), depthFactor(df) {
std::vector< _ImportEdge > edges; std::vector< _ImportEdge > edges;
edges.reserve( 2 * inputEdges.size() ); edges.reserve( 2 * inputEdges.size() );
for ( typename std::vector< InputEdge >::const_iterator i = inputEdges.begin(), e = inputEdges.end(); i != e; ++i ) { for ( typename std::vector< InputEdge >::const_iterator i = inputEdges.begin(), e = inputEdges.end(); i != e; ++i ) {
_ImportEdge edge; _ImportEdge edge;
edge.source = i->source(); edge.source = i->source();
edge.target = i->target(); edge.target = i->target();
edge.data.distance = (std::max)((int)i->weight(), 1 ); edge.data.distance = (std::max)((int)i->weight(), 1 );
assert( edge.data.distance > 0 ); assert( edge.data.distance > 0 );
#ifdef NDEBUG #ifdef NDEBUG
if ( edge.data.distance > 24 * 60 * 60 * 10 ) { if ( edge.data.distance > 24 * 60 * 60 * 10 ) {
std::cout << "Edge Weight too large -> May lead to invalid CH" << std::endl; std::cout << "Edge Weight too large -> May lead to invalid CH" << std::endl;
continue; continue;
} }
#endif #endif
edge.data.shortcut = false; edge.data.shortcut = false;
edge.data.nameID = i->getNameIDOfTurnTarget(); edge.data.nameID = i->getNameIDOfTurnTarget();
edge.data.via = i->via(); edge.data.via = i->via();
edge.data.turnInstruction = i->turnInstruction(); edge.data.turnInstruction = i->turnInstruction();
edge.data.forward = i->isForward(); edge.data.forward = i->isForward();
edge.data.backward = i->isBackward(); edge.data.backward = i->isBackward();
edge.data.originalEdges = 1; edge.data.originalEdges = 1;
edges.push_back( edge ); edges.push_back( edge );
std::swap( edge.source, edge.target ); std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward(); edge.data.forward = i->isBackward();
edge.data.backward = i->isForward(); edge.data.backward = i->isForward();
edges.push_back( edge ); edges.push_back( edge );
} }
//remove data from memory //remove data from memory
inputEdges.clear(); inputEdges.clear();
std::vector< InputEdge >().swap( inputEdges ); std::vector< InputEdge >().swap( inputEdges );
#ifdef _GLIBCXX_PARALLEL #ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort( edges.begin(), edges.end() ); __gnu_parallel::sort( edges.begin(), edges.end() );
#else #else
sort( edges.begin(), edges.end() ); sort( edges.begin(), edges.end() );
#endif #endif
NodeID edge = 0; NodeID edge = 0;
for ( NodeID i = 0; i < edges.size(); ) { for ( NodeID i = 0; i < edges.size(); ) {
const NodeID source = edges[i].source; const NodeID source = edges[i].source;
const NodeID target = edges[i].target; const NodeID target = edges[i].target;
const NodeID via = edges[i].data.via; const NodeID via = edges[i].data.via;
const short turnType = edges[i].data.turnInstruction; const short turnType = edges[i].data.turnInstruction;
//remove eigenloops //remove eigenloops
if ( source == target ) { if ( source == target ) {
i++; i++;
continue; continue;
} }
_ImportEdge forwardEdge; _ImportEdge forwardEdge;
_ImportEdge backwardEdge; _ImportEdge backwardEdge;
forwardEdge.source = backwardEdge.source = source; forwardEdge.source = backwardEdge.source = source;
forwardEdge.target = backwardEdge.target = target; forwardEdge.target = backwardEdge.target = target;
forwardEdge.data.forward = backwardEdge.data.backward = true; forwardEdge.data.forward = backwardEdge.data.backward = true;
forwardEdge.data.backward = backwardEdge.data.forward = false; forwardEdge.data.backward = backwardEdge.data.forward = false;
forwardEdge.data.turnInstruction = backwardEdge.data.turnInstruction = turnType; forwardEdge.data.turnInstruction = backwardEdge.data.turnInstruction = turnType;
forwardEdge.data.nameID = backwardEdge.data.nameID = edges[i].data.nameID; forwardEdge.data.nameID = backwardEdge.data.nameID = edges[i].data.nameID;
forwardEdge.data.shortcut = backwardEdge.data.shortcut = false; forwardEdge.data.shortcut = backwardEdge.data.shortcut = false;
forwardEdge.data.via = backwardEdge.data.via = via; forwardEdge.data.via = backwardEdge.data.via = via;
forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1; forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1;
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max(); forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
//remove parallel edges //remove parallel edges
while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) { while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) {
if ( edges[i].data.forward ) if ( edges[i].data.forward )
forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance ); forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance );
if ( edges[i].data.backward ) if ( edges[i].data.backward )
backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance ); backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance );
i++; i++;
} }
//merge edges (s,t) and (t,s) into bidirectional edge //merge edges (s,t) and (t,s) into bidirectional edge
if ( forwardEdge.data.distance == backwardEdge.data.distance ) { if ( forwardEdge.data.distance == backwardEdge.data.distance ) {
if ( (int)forwardEdge.data.distance != std::numeric_limits< int >::max() ) { if ( (int)forwardEdge.data.distance != std::numeric_limits< int >::max() ) {
forwardEdge.data.backward = true; forwardEdge.data.backward = true;
edges[edge++] = forwardEdge; edges[edge++] = forwardEdge;
} }
} else { //insert seperate edges } else { //insert seperate edges
if ( ((int)forwardEdge.data.distance) != std::numeric_limits< int >::max() ) { if ( ((int)forwardEdge.data.distance) != std::numeric_limits< int >::max() ) {
edges[edge++] = forwardEdge; edges[edge++] = forwardEdge;
} }
if ( (int)backwardEdge.data.distance != std::numeric_limits< int >::max() ) { if ( (int)backwardEdge.data.distance != std::numeric_limits< int >::max() ) {
edges[edge++] = backwardEdge; edges[edge++] = backwardEdge;
} }
} }
} }
std::cout << "ok" << std::endl << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl; std::cout << "ok" << std::endl << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl;
edges.resize( edge ); edges.resize( edge );
_graph.reset( new _DynamicGraph( nodes, edges ) ); _graph.reset( new _DynamicGraph( nodes, edges ) );
std::vector< _ImportEdge >().swap( edges ); std::vector< _ImportEdge >().swap( edges );
} }
~Contractor() { } ~Contractor() { }
void Run() { void Run() {
const NodeID numberOfNodes = _graph->GetNumberOfNodes(); const NodeID numberOfNodes = _graph->GetNumberOfNodes();
Percent p (numberOfNodes); Percent p (numberOfNodes);
unsigned maxThreads = omp_get_max_threads(); unsigned maxThreads = omp_get_max_threads();
std::vector < _ThreadData* > threadData; std::vector < _ThreadData* > threadData;
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) { for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
threadData.push_back( new _ThreadData( numberOfNodes ) ); threadData.push_back( new _ThreadData( numberOfNodes ) );
} }
std::cout << "Contractor is using " << maxThreads << " threads" << std::endl; std::cout << "Contractor is using " << maxThreads << " threads" << std::endl;
NodeID levelID = 0; NodeID numberOfContractedNodes = 0;
std::vector< std::pair< NodeID, bool > > remainingNodes( numberOfNodes ); std::vector< std::pair< NodeID, bool > > remainingNodes( numberOfNodes );
std::vector< double > nodePriority( numberOfNodes ); std::vector< double > nodePriority( numberOfNodes );
std::vector< _PriorityData > nodeData( numberOfNodes ); std::vector< _PriorityData > nodeData( numberOfNodes );
//initialize the variables //initialize the variables
#pragma omp parallel for schedule ( guided ) #pragma omp parallel for schedule ( guided )
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) for ( int x = 0; x < ( int ) numberOfNodes; ++x )
remainingNodes[x].first = x; remainingNodes[x].first = x;
std::random_shuffle( remainingNodes.begin(), remainingNodes.end() ); std::random_shuffle( remainingNodes.begin(), remainingNodes.end() );
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) for ( int x = 0; x < ( int ) numberOfNodes; ++x )
nodeData[remainingNodes[x].first].bias = x; nodeData[remainingNodes[x].first].bias = x;
std::cout << "initializing elimination PQ ..." << std::flush; std::cout << "initializing elimination PQ ..." << std::flush;
#pragma omp parallel #pragma omp parallel
{ {
_ThreadData* data = threadData[omp_get_thread_num()]; _ThreadData* data = threadData[omp_get_thread_num()];
#pragma omp parallel for schedule ( guided ) #pragma omp parallel for schedule ( guided )
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) { for ( int x = 0; x < ( int ) numberOfNodes; ++x ) {
nodePriority[x] = _Evaluate( data, &nodeData[x], x ); nodePriority[x] = _Evaluate( data, &nodeData[x], x );
} }
} }
std::cout << "ok" << std::endl << "preprocessing ..." << std::flush; std::cout << "ok" << std::endl << "preprocessing ..." << std::flush;
while ( levelID < numberOfNodes ) { while ( numberOfContractedNodes < numberOfNodes ) {
const int last = ( int ) remainingNodes.size(); const int last = ( int ) remainingNodes.size();
#pragma omp parallel #pragma omp parallel
{ {
//determine independent node set //determine independent node set
_ThreadData* const data = threadData[omp_get_thread_num()]; _ThreadData* const data = threadData[omp_get_thread_num()];
#pragma omp for schedule ( guided ) #pragma omp for schedule ( guided )
for ( int i = 0; i < last; ++i ) { for ( int i = 0; i < last; ++i ) {
const NodeID node = remainingNodes[i].first; const NodeID node = remainingNodes[i].first;
remainingNodes[i].second = _IsIndependent( nodePriority, nodeData, data, node ); remainingNodes[i].second = _IsIndependent( nodePriority, nodeData, data, node );
} }
} }
_NodePartitionor functor; _NodePartitionor functor;
const std::vector < std::pair < NodeID, bool > >::const_iterator first = stable_partition( remainingNodes.begin(), remainingNodes.end(), functor ); const std::vector < std::pair < NodeID, bool > >::const_iterator first = stable_partition( remainingNodes.begin(), remainingNodes.end(), functor );
const int firstIndependent = first - remainingNodes.begin(); const int firstIndependent = first - remainingNodes.begin();
//contract independent nodes //contract independent nodes
#pragma omp parallel #pragma omp parallel
{ {
_ThreadData* data = threadData[omp_get_thread_num()]; _ThreadData* data = threadData[omp_get_thread_num()];
#pragma omp for schedule ( guided ) nowait #pragma omp for schedule ( guided ) nowait
for ( int position = firstIndependent ; position < last; ++position ) { for ( int position = firstIndependent ; position < last; ++position ) {
NodeID x = remainingNodes[position].first; NodeID x = remainingNodes[position].first;
_Contract< false > ( data, x ); _Contract< false > ( data, x );
nodePriority[x] = -1; nodePriority[x] = -1;
} }
std::sort( data->insertedEdges.begin(), data->insertedEdges.end() ); std::sort( data->insertedEdges.begin(), data->insertedEdges.end() );
} }
#pragma omp parallel #pragma omp parallel
{ {
_ThreadData* data = threadData[omp_get_thread_num()]; _ThreadData* data = threadData[omp_get_thread_num()];
#pragma omp for schedule ( guided ) nowait #pragma omp for schedule ( guided ) nowait
for ( int position = firstIndependent ; position < last; ++position ) { for ( int position = firstIndependent ; position < last; ++position ) {
NodeID x = remainingNodes[position].first; NodeID x = remainingNodes[position].first;
_DeleteIncomingEdges( data, x ); _DeleteIncomingEdges( data, x );
} }
} }
//insert new edges //insert new edges
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) { for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
_ThreadData& data = *threadData[threadNum]; _ThreadData& data = *threadData[threadNum];
for ( int i = 0; i < ( int ) data.insertedEdges.size(); ++i ) { for ( int i = 0; i < ( int ) data.insertedEdges.size(); ++i ) {
const _ImportEdge& edge = data.insertedEdges[i]; const _ImportEdge& edge = data.insertedEdges[i];
_graph->InsertEdge( edge.source, edge.target, edge.data ); _graph->InsertEdge( edge.source, edge.target, edge.data );
} }
std::vector< _ImportEdge >().swap( data.insertedEdges ); data.insertedEdges.clear();
} }
//update priorities //update priorities
#pragma omp parallel #pragma omp parallel
{ {
_ThreadData* data = threadData[omp_get_thread_num()]; _ThreadData* data = threadData[omp_get_thread_num()];
#pragma omp for schedule ( guided ) nowait #pragma omp for schedule ( guided ) nowait
for ( int position = firstIndependent ; position < last; ++position ) { for ( int position = firstIndependent ; position < last; ++position ) {
NodeID x = remainingNodes[position].first; NodeID x = remainingNodes[position].first;
_UpdateNeighbours( &nodePriority, &nodeData, data, x ); _UpdateNeighbours( nodePriority, nodeData, data, x );
} }
} }
//remove contracted nodes from the pool //remove contracted nodes from the pool
levelID += last - firstIndependent; numberOfContractedNodes += last - firstIndependent;
remainingNodes.resize( firstIndependent ); remainingNodes.resize( firstIndependent );
std::vector< std::pair< NodeID, bool > >( remainingNodes ).swap( remainingNodes ); std::vector< std::pair< NodeID, bool > >( remainingNodes ).swap( remainingNodes );
p.printStatus(levelID); p.printStatus(numberOfContractedNodes);
} }
for ( unsigned threadNum = 0; threadNum < maxThreads; threadNum++ ) { for ( unsigned threadNum = 0; threadNum < maxThreads; threadNum++ ) {
delete threadData[threadNum]; delete threadData[threadNum];
} }
} }
template< class Edge > template< class Edge >
void GetEdges( std::vector< Edge >& edges ) { void GetEdges( std::vector< Edge >& edges ) {
NodeID numberOfNodes = _graph->GetNumberOfNodes(); NodeID numberOfNodes = _graph->GetNumberOfNodes();
for ( NodeID node = 0; node < numberOfNodes; ++node ) { for ( NodeID node = 0; node < numberOfNodes; ++node ) {
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; edge++ ) { for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; edge++ ) {
const NodeID target = _graph->GetTarget( edge ); const NodeID target = _graph->GetTarget( edge );
const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge ); const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge );
Edge newEdge; Edge newEdge;
newEdge.source = node; newEdge.source = node;
newEdge.target = target; newEdge.target = target;
newEdge.data.distance = data.distance; newEdge.data.distance = data.distance;
newEdge.data.shortcut = data.shortcut; newEdge.data.shortcut = data.shortcut;
newEdge.data.via = data.via; newEdge.data.via = data.via;
newEdge.data.nameID = data.nameID; newEdge.data.nameID = data.nameID;
newEdge.data.turnInstruction = data.turnInstruction; newEdge.data.turnInstruction = data.turnInstruction;
newEdge.data.forward = data.forward; newEdge.data.forward = data.forward;
newEdge.data.backward = data.backward; newEdge.data.backward = data.backward;
edges.push_back( newEdge ); edges.push_back( newEdge );
} }
} }
} }
private: private:
void _Dijkstra( const int maxDistance, const unsigned numTargets, const int maxNodes, _ThreadData* data ){ inline void _Dijkstra( const int maxDistance, const unsigned numTargets, const int maxNodes, _ThreadData* const data ){
_Heap& heap = data->heap; _Heap& heap = data->heap;
int nodes = 0; int nodes = 0;
unsigned targetsFound = 0; unsigned targetsFound = 0;
while ( heap.Size() > 0 ) { while ( heap.Size() > 0 ) {
const NodeID node = heap.DeleteMin(); const NodeID node = heap.DeleteMin();
const int distance = heap.GetKey( node ); const int distance = heap.GetKey( node );
if ( nodes++ > maxNodes ) if ( nodes++ > maxNodes )
return; return;
//Destination settled? //Destination settled?
if ( distance > maxDistance ) if ( distance > maxDistance )
return; return;
if ( heap.GetData( node ).target ) { if ( heap.GetData( node ).target ) {
targetsFound++; targetsFound++;
if ( targetsFound >= numTargets ) if ( targetsFound >= numTargets )
return; return;
} }
//iterate over all edges of node //iterate over all edges of node
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) { for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) {
const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge ); const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge );
if ( !data.forward ) if ( !data.forward )
continue; continue;
const NodeID to = _graph->GetTarget( edge ); const NodeID to = _graph->GetTarget( edge );
const int toDistance = distance + data.distance; const int toDistance = distance + data.distance;
//New Node discovered -> Add to Heap + Node Info Storage //New Node discovered -> Add to Heap + Node Info Storage
if ( !heap.WasInserted( to ) ) if ( !heap.WasInserted( to ) )
heap.Insert( to, toDistance, _HeapData() ); heap.Insert( to, toDistance, _HeapData() );
//Found a shorter Path -> Update distance //Found a shorter Path -> Update distance
else if ( toDistance < heap.GetKey( to ) ) { else if ( toDistance < heap.GetKey( to ) ) {
heap.DecreaseKey( to, toDistance ); heap.DecreaseKey( to, toDistance );
//heap.GetData( to ).hops = hops + 1; //heap.GetData( to ).hops = hops + 1;
} }
} }
} }
} }
double _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node ){ double _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node ){
_ContractionInformation stats; _ContractionInformation stats;
//perform simulated contraction //perform simulated contraction
_Contract< true > ( data, node, &stats ); _Contract< true > ( data, node, &stats );
// Result will contain the priority // Result will contain the priority
if ( stats.edgesDeleted == 0 || stats.originalEdgesDeleted == 0 ) if ( stats.edgesDeleted == 0 || stats.originalEdgesDeleted == 0 )
return depthFactor * nodeData->depth; return depthFactor * nodeData->depth;
return edgeQuotionFactor * ((( double ) stats.edgesAdded ) / stats.edgesDeleted ) + originalQuotientFactor * ((( double ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + depthFactor * nodeData->depth; return edgeQuotionFactor * ((( double ) stats.edgesAdded ) / stats.edgesDeleted ) + originalQuotientFactor * ((( double ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + depthFactor * nodeData->depth;
} }
template< bool Simulate > bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) { template< bool Simulate >
_Heap& heap = data->heap; bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) {
int insertedEdgesSize = data->insertedEdges.size(); _Heap& heap = data->heap;
std::vector< _ImportEdge >& insertedEdges = data->insertedEdges; int insertedEdgesSize = data->insertedEdges.size();
std::vector< _ImportEdge >& insertedEdges = data->insertedEdges;
for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) { for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) {
const _EdgeBasedContractorEdgeData& inData = _graph->GetEdgeData( inEdge ); const _EdgeBasedContractorEdgeData& inData = _graph->GetEdgeData( inEdge );
const NodeID source = _graph->GetTarget( inEdge ); const NodeID source = _graph->GetTarget( inEdge );
if ( Simulate ) { if ( Simulate ) {
assert( stats != NULL ); assert( stats != NULL );
stats->edgesDeleted++; stats->edgesDeleted++;
stats->originalEdgesDeleted += inData.originalEdges; stats->originalEdgesDeleted += inData.originalEdges;
} }
if ( !inData.backward ) if ( !inData.backward )
continue; continue;
heap.Clear(); heap.Clear();
heap.Insert( source, 0, _HeapData() ); heap.Insert( source, 0, _HeapData() );
if ( node != source ) if ( node != source )
heap.Insert( node, inData.distance, _HeapData() ); heap.Insert( node, inData.distance, _HeapData() );
int maxDistance = 0; int maxDistance = 0;
unsigned numTargets = 0; unsigned numTargets = 0;
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) { for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge ); const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward ) if ( !outData.forward )
continue; continue;
const NodeID target = _graph->GetTarget( outEdge ); const NodeID target = _graph->GetTarget( outEdge );
const int pathDistance = inData.distance + outData.distance; const int pathDistance = inData.distance + outData.distance;
maxDistance = std::max( maxDistance, pathDistance ); maxDistance = std::max( maxDistance, pathDistance );
if ( !heap.WasInserted( target ) ) { if ( !heap.WasInserted( target ) ) {
heap.Insert( target, pathDistance, _HeapData( true ) ); heap.Insert( target, pathDistance, _HeapData( true ) );
numTargets++; numTargets++;
} else if ( pathDistance < heap.GetKey( target ) ) { } else if ( pathDistance < heap.GetKey( target ) ) {
heap.DecreaseKey( target, pathDistance ); heap.DecreaseKey( target, pathDistance );
} }
} }
if( Simulate ) if( Simulate )
_Dijkstra( maxDistance, numTargets, 500, data ); _Dijkstra( maxDistance, numTargets, 500, data );
else else
_Dijkstra( maxDistance, numTargets, 1000, data ); _Dijkstra( maxDistance, numTargets, 1000, data );
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) { for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge ); const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward ) if ( !outData.forward )
continue; continue;
const NodeID target = _graph->GetTarget( outEdge ); const NodeID target = _graph->GetTarget( outEdge );
const int pathDistance = inData.distance + outData.distance; const int pathDistance = inData.distance + outData.distance;
const int distance = heap.GetKey( target ); const int distance = heap.GetKey( target );
if ( pathDistance <= distance ) { if ( pathDistance <= distance ) {
if ( Simulate ) { if ( Simulate ) {
assert( stats != NULL ); assert( stats != NULL );
stats->edgesAdded+=2; stats->edgesAdded+=2;
stats->originalEdgesAdded += 2* ( outData.originalEdges + inData.originalEdges ); stats->originalEdgesAdded += 2* ( outData.originalEdges + inData.originalEdges );
} else { } else {
_ImportEdge newEdge; _ImportEdge newEdge;
newEdge.source = source; newEdge.source = source;
newEdge.target = target; newEdge.target = target;
newEdge.data.distance = pathDistance; newEdge.data.distance = pathDistance;
newEdge.data.forward = true; newEdge.data.forward = true;
newEdge.data.backward = false; newEdge.data.backward = false;
newEdge.data.via = node; newEdge.data.via = node;
newEdge.data.shortcut = true; newEdge.data.shortcut = true;
newEdge.data.turnInstruction = inData.turnInstruction; newEdge.data.turnInstruction = inData.turnInstruction;
newEdge.data.originalEdges = outData.originalEdges + inData.originalEdges; newEdge.data.originalEdges = outData.originalEdges + inData.originalEdges;
insertedEdges.push_back( newEdge ); insertedEdges.push_back( newEdge );
std::swap( newEdge.source, newEdge.target ); std::swap( newEdge.source, newEdge.target );
newEdge.data.forward = false; newEdge.data.forward = false;
newEdge.data.backward = true; newEdge.data.backward = true;
insertedEdges.push_back( newEdge ); insertedEdges.push_back( newEdge );
} }
} }
} }
} }
if ( !Simulate ) { if ( !Simulate ) {
for ( int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; i++ ) { for ( int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; i++ ) {
bool found = false; bool found = false;
for ( int other = i + 1 ; other < iend ; ++other ) { for ( int other = i + 1 ; other < iend ; ++other ) {
if ( insertedEdges[other].source != insertedEdges[i].source ) if ( insertedEdges[other].source != insertedEdges[i].source )
continue; continue;
if ( insertedEdges[other].target != insertedEdges[i].target ) if ( insertedEdges[other].target != insertedEdges[i].target )
continue; continue;
if ( insertedEdges[other].data.distance != insertedEdges[i].data.distance ) if ( insertedEdges[other].data.distance != insertedEdges[i].data.distance )
continue; continue;
if ( insertedEdges[other].data.shortcut != insertedEdges[i].data.shortcut ) if ( insertedEdges[other].data.shortcut != insertedEdges[i].data.shortcut )
continue; continue;
insertedEdges[other].data.forward |= insertedEdges[i].data.forward; insertedEdges[other].data.forward |= insertedEdges[i].data.forward;
insertedEdges[other].data.backward |= insertedEdges[i].data.backward; insertedEdges[other].data.backward |= insertedEdges[i].data.backward;
found = true; found = true;
break; break;
} }
if ( !found ) if ( !found )
insertedEdges[insertedEdgesSize++] = insertedEdges[i]; insertedEdges[insertedEdgesSize++] = insertedEdges[i];
} }
insertedEdges.resize( insertedEdgesSize ); insertedEdges.resize( insertedEdgesSize );
} }
return true; return true;
} }
bool _DeleteIncomingEdges( _ThreadData* data, NodeID node ) { bool _DeleteIncomingEdges( _ThreadData* data, NodeID node ) {
std::vector< NodeID >& neighbours = data->neighbours; std::vector< NodeID >& neighbours = data->neighbours;
neighbours.clear(); neighbours.clear();
//find all neighbours //find all neighbours
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) { for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
const NodeID u = _graph->GetTarget( e ); const NodeID u = _graph->GetTarget( e );
if ( u == node ) if ( u == node )
continue; continue;
neighbours.push_back( u ); neighbours.push_back( u );
} }
//eliminate duplicate entries ( forward + backward edges ) //eliminate duplicate entries ( forward + backward edges )
std::sort( neighbours.begin(), neighbours.end() ); std::sort( neighbours.begin(), neighbours.end() );
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() ); neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) { for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
const NodeID u = neighbours[i]; const NodeID u = neighbours[i];
_graph->DeleteEdgesTo( u, node ); _graph->DeleteEdgesTo( u, node );
} }
return true; return true;
} }
bool _UpdateNeighbours( std::vector< double >* priorities, std::vector< _PriorityData >* const nodeData, _ThreadData* const data, NodeID node ) { bool _UpdateNeighbours( std::vector< double > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node ) {
std::vector< NodeID >& neighbours = data->neighbours; std::vector< NodeID >& neighbours = data->neighbours;
neighbours.clear(); neighbours.clear();
std::vector< NodeID>().swap(neighbours);
//find all neighbours //find all neighbours
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) { for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
const NodeID u = _graph->GetTarget( e ); const NodeID u = _graph->GetTarget( e );
if ( u == node ) if ( u == node )
continue; continue;
neighbours.push_back( u ); neighbours.push_back( u );
( *nodeData )[u].depth = (std::max)(( *nodeData )[node].depth + 1, ( *nodeData )[u].depth ); nodeData[u].depth = (std::max)(nodeData[node].depth + 1, nodeData[u].depth );
} }
//eliminate duplicate entries ( forward + backward edges ) //eliminate duplicate entries ( forward + backward edges )
std::sort( neighbours.begin(), neighbours.end() ); std::sort( neighbours.begin(), neighbours.end() );
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() ); neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) { for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
const NodeID u = neighbours[i]; const NodeID u = neighbours[i];
( *priorities )[u] = _Evaluate( data, &( *nodeData )[u], u ); priorities[u] = _Evaluate( data, &( nodeData )[u], u );
} }
return true; return true;
} }
bool _IsIndependent( const std::vector< double >& priorities, const std::vector< _PriorityData >& nodeData, _ThreadData* const data, NodeID node ) { bool _IsIndependent( const std::vector< double >& priorities, const std::vector< _PriorityData >& nodeData, _ThreadData* const data, NodeID node ) {
const double priority = priorities[node]; const double priority = priorities[node];
std::vector< NodeID >& neighbours = data->neighbours; std::vector< NodeID >& neighbours = data->neighbours;
neighbours.clear(); neighbours.clear();
std::vector< NodeID>().swap(neighbours);
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) { for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
const NodeID target = _graph->GetTarget( e ); const NodeID target = _graph->GetTarget( e );
const double targetPriority = priorities[target]; const double targetPriority = priorities[target];
assert( targetPriority >= 0 ); assert( targetPriority >= 0 );
//found a neighbour with lower priority? //found a neighbour with lower priority?
if ( priority > targetPriority ) if ( priority > targetPriority )
return false; return false;
//tie breaking //tie breaking
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias ) if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
return false; return false;
neighbours.push_back( target ); neighbours.push_back( target );
} }
std::sort( neighbours.begin(), neighbours.end() ); std::sort( neighbours.begin(), neighbours.end() );
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() ); neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
//examine all neighbours that are at most 2 hops away //examine all neighbours that are at most 2 hops away
for ( std::vector< NodeID >::const_iterator i = neighbours.begin(), lastNode = neighbours.end(); i != lastNode; ++i ) { for ( std::vector< NodeID >::const_iterator i = neighbours.begin(), lastNode = neighbours.end(); i != lastNode; ++i ) {
const NodeID u = *i; const NodeID u = *i;
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( u ) ; e < _graph->EndEdges( u ) ; ++e ) { for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( u ) ; e < _graph->EndEdges( u ) ; ++e ) {
const NodeID target = _graph->GetTarget( e ); const NodeID target = _graph->GetTarget( e );
const double targetPriority = priorities[target]; const double targetPriority = priorities[target];
assert( targetPriority >= 0 ); assert( targetPriority >= 0 );
//found a neighbour with lower priority? //found a neighbour with lower priority?
if ( priority > targetPriority ) if ( priority > targetPriority )
return false; return false;
//tie breaking //tie breaking
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias ) if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
return false; return false;
} }
} }
return true; return true;
} }
boost::shared_ptr<_DynamicGraph> _graph; boost::shared_ptr<_DynamicGraph> _graph;
unsigned edgeQuotionFactor; unsigned edgeQuotionFactor;
unsigned originalQuotientFactor; unsigned originalQuotientFactor;
unsigned depthFactor; unsigned depthFactor;
}; };
#endif // CONTRACTOR_H_INCLUDED #endif // CONTRACTOR_H_INCLUDED

View File

@ -104,7 +104,7 @@ void EdgeBasedGraphFactory::Run() {
std::vector<_Restriction>::iterator restrictionIterator = inputRestrictions.begin(); std::vector<_Restriction>::iterator restrictionIterator = inputRestrictions.begin();
Percent p(_nodeBasedGraph->GetNumberOfNodes()); Percent p(_nodeBasedGraph->GetNumberOfNodes());
int numberOfResolvedRestrictions(0); int numberOfSkippedTurns(0);
int nodeBasedEdgeCounter(0); int nodeBasedEdgeCounter(0);
NodeID onlyToNode(0); NodeID onlyToNode(0);
@ -122,6 +122,7 @@ void EdgeBasedGraphFactory::Run() {
//Check every turn restriction originating from this edge if it is an 'only_*'-turn. //Check every turn restriction originating from this edge if it is an 'only_*'-turn.
if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) { if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) {
//copying iterator, so we can loop over restrictions without forgetting currect position.
std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator; std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator;
do { do {
if(v == secondRestrictionIterator->viaNode) { if(v == secondRestrictionIterator->viaNode) {
@ -161,12 +162,13 @@ void EdgeBasedGraphFactory::Run() {
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2);
//if (u,v,w) is a forbidden turn, continue //if (u,v,w) is a forbidden turn, continue
bool isTurnRestricted(false);
if(isOnlyAllowed && w != onlyToNode) { if(isOnlyAllowed && w != onlyToNode) {
// INFO("skipped turn <" << u << "," << v << "," << w << ">, only allowing <" << u << "," << v << "," << onlyToNode << ">"); //We are at an only_-restriction but not at the right turn.
++numberOfSkippedTurns;
continue; continue;
} }
bool isTurnRestricted(false);
if( u != w ) { //only add an edge if turn is not a U-turn if( u != w ) { //only add an edge if turn is not a U-turn
if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) { if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) {
std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator; std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator;
@ -227,7 +229,7 @@ void EdgeBasedGraphFactory::Run() {
edgeBasedNodes.push_back(currentNode); edgeBasedNodes.push_back(currentNode);
} }
} else { } else {
++numberOfResolvedRestrictions; ++numberOfSkippedTurns;
} }
} }
} }
@ -238,7 +240,7 @@ void EdgeBasedGraphFactory::Run() {
edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() ); edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() );
INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges"); INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges");
INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << (double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter); INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << (double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter);
INFO("Edge-based graph obeys " << numberOfResolvedRestrictions << " turn restrictions, " << (inputRestrictions.size() - numberOfResolvedRestrictions )<< " skipped."); INFO("Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << inputRestrictions.size() << " restrictions.");
INFO("Generated " << edgeBasedNodes.size() << " edge based nodes"); INFO("Generated " << edgeBasedNodes.size() << " edge based nodes");
} }

View File

@ -59,7 +59,7 @@ public:
void printIncrement() void printIncrement()
{ {
#pragma omp atomic #pragma omp atomic
_current_value++; ++_current_value;
printStatus(_current_value); printStatus(_current_value);
} }
private: private:

View File

@ -33,8 +33,8 @@ public:
BasePlugin() { } BasePlugin() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis) //Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BasePlugin() { } virtual ~BasePlugin() { }
virtual std::string GetDescriptor() = 0; virtual std::string GetDescriptor() const = 0;
virtual std::string GetVersionString() = 0; virtual std::string GetVersionString() const = 0 ;
virtual void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) = 0; virtual void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) = 0;
}; };

View File

@ -17,7 +17,9 @@ class HelloWorldPlugin : public BasePlugin {
public: public:
HelloWorldPlugin() {} HelloWorldPlugin() {}
virtual ~HelloWorldPlugin() { /*std::cout << GetDescriptor() << " destructor" << std::endl;*/ } virtual ~HelloWorldPlugin() { /*std::cout << GetDescriptor() << " destructor" << std::endl;*/ }
std::string GetDescriptor() { return std::string("hello"); } std::string GetDescriptor() const { return std::string("hello"); }
std::string GetVersionString() const { return std::string("0.1a"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
std::cout << "[hello world]: runnning handler" << std::endl; std::cout << "[hello world]: runnning handler" << std::endl;
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
@ -36,7 +38,6 @@ public:
reply.content.append(content.str()); reply.content.append(content.str());
reply.content.append("</body></html>"); reply.content.append("</body></html>");
} }
std::string GetVersionString() { return std::string("0.1a"); }
}; };
#endif /* HELLOWORLDPLUGIN_H_ */ #endif /* HELLOWORLDPLUGIN_H_ */

View File

@ -37,8 +37,8 @@ public:
LocatePlugin(ObjectsForQueryStruct * objects) { LocatePlugin(ObjectsForQueryStruct * objects) {
nodeHelpDesk = objects->nodeHelpDesk; nodeHelpDesk = objects->nodeHelpDesk;
} }
std::string GetDescriptor() { return std::string("locate"); } std::string GetDescriptor() const { return std::string("locate"); }
std::string GetVersionString() { return std::string("0.3 (DL)"); } std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if(routeParameters.parameters.size() != 2) { if(routeParameters.parameters.size() != 2) {

View File

@ -43,8 +43,8 @@ public:
descriptorTable.Set("kml", 0); descriptorTable.Set("kml", 0);
descriptorTable.Set("json", 1); descriptorTable.Set("json", 1);
} }
std::string GetDescriptor() { return std::string("nearest"); } std::string GetDescriptor() const { return std::string("nearest"); }
std::string GetVersionString() { return std::string("0.3 (DL)"); } std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if(routeParameters.parameters.size() != 2) { if(routeParameters.parameters.size() != 2) {

View File

@ -22,10 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define RAWROUTEDATA_H_ #define RAWROUTEDATA_H_
struct RawRouteData { struct RawRouteData {
void Resize() {
unsigned size = rawViaNodeCoordinates.size()-1;
segmentEndCoordinates.resize(size);
}
std::vector< _PathData > computedRouted; std::vector< _PathData > computedRouted;
std::vector< PhantomNodes > segmentEndCoordinates; std::vector< PhantomNodes > segmentEndCoordinates;
std::vector< _Coordinate > rawViaNodeCoordinates; std::vector< _Coordinate > rawViaNodeCoordinates;

View File

@ -68,8 +68,8 @@ public:
DELETE( searchEngine ); DELETE( searchEngine );
} }
std::string GetDescriptor() { return pluginDescriptorString; } std::string GetDescriptor() const { return pluginDescriptorString; }
std::string GetVersionString() { return std::string("0.3 (DL)"); } std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if(0 == routeParameters.options["start"].size() || 0 == routeParameters.options["dest"].size() ) { if(0 == routeParameters.options["start"].size() || 0 == routeParameters.options["dest"].size() ) {
@ -109,7 +109,7 @@ public:
} }
int vialat = static_cast<int>(100000.*atof(textCoord[0].c_str())); int vialat = static_cast<int>(100000.*atof(textCoord[0].c_str()));
int vialon = static_cast<int>(100000.*atof(textCoord[1].c_str())); int vialon = static_cast<int>(100000.*atof(textCoord[1].c_str()));
INFO("[debug] via" << i << ": " << vialat << "," << vialon); // INFO("[debug] via" << i << ": " << vialat << "," << vialon);
_Coordinate viaCoord(vialat, vialon); _Coordinate viaCoord(vialat, vialon);
if(false == checkCoord(viaCoord)) { if(false == checkCoord(viaCoord)) {
reply = http::Reply::stockReply(http::Reply::badRequest); reply = http::Reply::stockReply(http::Reply::badRequest);
@ -124,8 +124,6 @@ public:
searchEngine->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i]); searchEngine->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i]);
} }
rawRoute.Resize();
unsigned distance = 0; unsigned distance = 0;
//single route or via point routing //single route or via point routing
if(0 == routeParameters.viaPoints.size()) { if(0 == routeParameters.viaPoints.size()) {
@ -133,23 +131,16 @@ public:
segmentPhantomNodes.startPhantom = phantomNodeVector[0]; segmentPhantomNodes.startPhantom = phantomNodeVector[0];
segmentPhantomNodes.targetPhantom = phantomNodeVector[1]; segmentPhantomNodes.targetPhantom = phantomNodeVector[1];
distance = searchEngine->ComputeRoute(segmentPhantomNodes, rawRoute.computedRouted); distance = searchEngine->ComputeRoute(segmentPhantomNodes, rawRoute.computedRouted);
rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes);
//put segments at correct position of routes raw data
rawRoute.segmentEndCoordinates[0] = (segmentPhantomNodes);
} else { } else {
//Getting the shortest via path is a dynamic programming problem and is solved as such. //Getting the shortest via path is a dynamic programming problem and is solved as such.
std::vector<PhantomNodes> phantomNodes;
for(unsigned i = 0; i < phantomNodeVector.size()-1; ++i) { for(unsigned i = 0; i < phantomNodeVector.size()-1; ++i) {
PhantomNodes segmentPhantomNodes; PhantomNodes segmentPhantomNodes;
segmentPhantomNodes.startPhantom = phantomNodeVector[i]; segmentPhantomNodes.startPhantom = phantomNodeVector[i];
segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1]; segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1];
phantomNodes.push_back(segmentPhantomNodes); rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes);
} }
distance = searchEngine->ComputeViaRoute(phantomNodes, rawRoute.computedRouted); distance = searchEngine->ComputeViaRoute(rawRoute.segmentEndCoordinates, rawRoute.computedRouted);
//put segments at correct position of routes raw data
// rawRoute.segmentEndCoordinates[i] = (segmentPhantomNodes);
// rawRoute.routeSegments[i] = path;
} }
if(INT_MAX == distance ) { if(INT_MAX == distance ) {
DEBUG( "Error occurred, single path not found" ); DEBUG( "Error occurred, single path not found" );
@ -199,7 +190,10 @@ public:
PhantomNodes phantomNodes; PhantomNodes phantomNodes;
phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom; phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom;
// INFO("Start location: " << phantomNodes.startPhantom.location)
phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom; phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom;
// INFO("TargetLocation: " << phantomNodes.targetPhantom.location);
// INFO("Number of segments: " << rawRoute.segmentEndCoordinates.size());
desc->SetConfig(descriptorConfig); desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, *searchEngine, distance); desc->Run(reply, rawRoute, phantomNodes, *searchEngine, distance);