Merge branch 'master' of

https://DennisOSRM@github.com/DennisOSRM/Project-OSRM.git
This commit is contained in:
DennisOSRM 2012-02-23 16:29:55 +01:00
commit a88ad71be6
15 changed files with 570 additions and 578 deletions

View File

@ -39,7 +39,7 @@ class DouglasPeucker {
private: private:
typedef std::pair<std::size_t, std::size_t> PairOfPoints; typedef std::pair<std::size_t, std::size_t> PairOfPoints;
//Stack to simulate the recursion //Stack to simulate the recursion
SimpleStack<PairOfPoints > recursionStack; std::stack<PairOfPoints > recursionStack;
double ComputeDistanceOfPointToLine(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target) { double ComputeDistanceOfPointToLine(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target) {
double r; double r;
@ -81,7 +81,7 @@ public:
std::size_t leftBorderOfRange = 0; std::size_t leftBorderOfRange = 0;
std::size_t rightBorderOfRange = 1; std::size_t rightBorderOfRange = 1;
//Sweep linerarily over array and identify those ranges that need to be checked //Sweep linerarily over array and identify those ranges that need to be checked
recursionStack.hint(inputVector.size()); // recursionStack.hint(inputVector.size());
do { do {
assert(inputVector[leftBorderOfRange].necessary); assert(inputVector[leftBorderOfRange].necessary);
assert(inputVector[inputVector.size()-1].necessary); assert(inputVector[inputVector.size()-1].necessary);

View File

@ -41,519 +41,539 @@ or see http://www.gnu.org/licenses/agpl.txt.
class Contractor { class Contractor {
private: private:
struct _EdgeBasedContractorEdgeData { struct _EdgeBasedContractorEdgeData {
_EdgeBasedContractorEdgeData() : _EdgeBasedContractorEdgeData() :
distance(0), originalEdges(0), via(0), nameID(0), turnInstruction(0), shortcut(0), forward(0), backward(0) {} distance(0), originalEdges(0), via(0), nameID(0), turnInstruction(0), shortcut(0), forward(0), backward(0) {}
_EdgeBasedContractorEdgeData( unsigned _distance, unsigned _originalEdges, unsigned _via, unsigned _nameID, short _turnInstruction, bool _shortcut, bool _forward, bool _backward) : _EdgeBasedContractorEdgeData( unsigned _distance, unsigned _originalEdges, unsigned _via, unsigned _nameID, short _turnInstruction, bool _shortcut, bool _forward, bool _backward) :
distance(_distance), originalEdges(_originalEdges), via(_via), nameID(_nameID), turnInstruction(_turnInstruction), shortcut(_shortcut), forward(_forward), backward(_backward) {} distance(_distance), originalEdges(_originalEdges), via(_via), nameID(_nameID), turnInstruction(_turnInstruction), shortcut(_shortcut), forward(_forward), backward(_backward) {}
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 {
short hop; short hop;
bool target; bool target;
_HeapData() : hop(0), target(false) {} _HeapData() : hop(0), target(false) {}
_HeapData( short h, bool t ) : hop(h), target(t) {} _HeapData( short h, bool t ) : hop(h), 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() : edgesDeleted(0), edgesAdded(0), originalEdgesDeleted(0), originalEdgesAdded(0) {} _ContractionInformation() : edgesDeleted(0), edgesAdded(0), originalEdgesDeleted(0), originalEdgesAdded(0) {}
}; };
struct _NodePartitionor { struct _NodePartitionor {
bool operator()( std::pair< NodeID, bool > & nodeData ) const { bool operator()( std::pair< NodeID, bool > & nodeData ) const {
return !nodeData.second; return !nodeData.second;
} }
}; };
public: public:
template< class InputEdge > template< class InputEdge >
Contractor( int nodes, std::vector< InputEdge >& inputEdges, const double eqf = 8.4, const double oqf = 4.1, const double df = 3.) Contractor( int nodes, std::vector< InputEdge >& inputEdges, const double eqf = 2, const double oqf = 2, const double df = 1)
: edgeQuotionFactor(eqf), originalQuotientFactor(oqf), depthFactor(df) { : edgeQuotionFactor(eqf), originalQuotientFactor(oqf), depthFactor(df) {
std::vector< _ImportEdge > edges; std::vector< _ImportEdge > edges;
edges.reserve( 2 * inputEdges.size() ); edges.reserve( 2 * inputEdges.size() );
BOOST_FOREACH(InputEdge & currentEdge, inputEdges) { BOOST_FOREACH(InputEdge & currentEdge, inputEdges) {
_ImportEdge edge; _ImportEdge edge;
edge.source = currentEdge.source(); edge.source = currentEdge.source();
edge.target = currentEdge.target(); edge.target = currentEdge.target();
edge.data = _EdgeBasedContractorEdgeData( (std::max)((int)currentEdge.weight(), 1 ), 1, currentEdge.via(), currentEdge.getNameIDOfTurnTarget(), currentEdge.turnInstruction(), false, currentEdge.isForward(), currentEdge.isBackward()); edge.data = _EdgeBasedContractorEdgeData( (std::max)((int)currentEdge.weight(), 1 ), 1, currentEdge.via(), currentEdge.getNameIDOfTurnTarget(), currentEdge.turnInstruction(), false, currentEdge.isForward(), currentEdge.isBackward());
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
edges.push_back( edge ); edges.push_back( edge );
std::swap( edge.source, edge.target ); std::swap( edge.source, edge.target );
edge.data.forward = currentEdge.isBackward(); edge.data.forward = currentEdge.isBackward();
edge.data.backward = currentEdge.isForward(); edge.data.backward = currentEdge.isForward();
edges.push_back( edge ); edges.push_back( edge );
} }
//remove data from memory //remove data from memory
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 numberOfContractedNodes = 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, false );
} }
} }
std::cout << "ok" << std::endl << "preprocessing ..." << std::flush; std::cout << "ok" << std::endl << "preprocessing ..." << std::flush;
while ( numberOfContractedNodes < numberOfNodes ) { while ( numberOfContractedNodes < numberOfNodes ) {
const int last = ( int ) remainingNodes.size(); bool topOnePercent = (numberOfNodes - numberOfContractedNodes) > 0.01*numberOfNodes;
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 ); if(topOnePercent)
nodePriority[x] = -1; _Contract< false, true > ( data, x );
} else
std::sort( data->insertedEdges.begin(), data->insertedEdges.end() ); _Contract< false, false > ( data, x );
} nodePriority[x] = -1;
}
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 ); _DynamicGraph::EdgeIterator currentEdgeID = _graph->FindEdge(edge.source, edge.target);
} if(currentEdgeID != _graph->EndEdges(edge.source)) {
data.insertedEdges.clear(); _DynamicGraph::EdgeData & currentEdgeData = _graph->GetEdgeData(currentEdgeID);
} if(edge.data.forward == currentEdgeData.forward && edge.data.backward == currentEdgeData.backward ) {
//update priorities if(_graph->GetEdgeData(_graph->FindEdge(edge.source, edge.target)).distance <= edge.data.distance) {
continue;
}
if(currentEdgeData.distance > edge.data.distance) {
currentEdgeData.distance = edge.data.distance;
continue;
}
}
}
_graph->InsertEdge( edge.source, edge.target, edge.data );
}
data.insertedEdges.clear();
}
//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, topOnePercent );
} }
} }
//remove contracted nodes from the pool //remove contracted nodes from the pool
numberOfContractedNodes += 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(numberOfContractedNodes); 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:
inline void _Dijkstra( const int maxDistance, const unsigned numTargets, const int maxNodes, const short hopLimit, _ThreadData* const data ){ inline void _Dijkstra( const int maxDistance, const unsigned numTargets, const int maxNodes, const int hopLimit, _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 );
const short currentHop = heap.GetData( node ).hop+1; const short currentHop = heap.GetData( node ).hop+1;
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;
} }
if(currentHop >= hopLimit) if(currentHop >= hopLimit)
continue; continue;
//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(currentHop, false) ); heap.Insert( to, toDistance, _HeapData(currentHop, false) );
//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 ).hop = currentHop; heap.GetData( to ).hop = currentHop;
} }
} }
} }
} }
double _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node ){ double _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node, bool topOnePercent ){
_ContractionInformation stats; _ContractionInformation stats;
//perform simulated contraction //perform simulated contraction
_Contract< true > ( data, node, &stats ); if(topOnePercent)
_Contract< true, true > ( data, node, &stats );
else
_Contract< true, false > ( 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 > template< bool Simulate, bool topOnePercent >
bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) { bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) {
_Heap& heap = data->heap; _Heap& heap = data->heap;
int insertedEdgesSize = data->insertedEdges.size(); int insertedEdgesSize = data->insertedEdges.size();
std::vector< _ImportEdge >& insertedEdges = data->insertedEdges; 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( 0, true ) ); heap.Insert( target, pathDistance, _HeapData( 0, 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, 1000, 5, data ); _Dijkstra( maxDistance, numTargets, 1000, (true ? INT_MAX : 5), data );
else else
_Dijkstra( maxDistance, numTargets, 2000, 7, data ); _Dijkstra( maxDistance, numTargets, 2000, (true ? INT_MAX : 7), 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 = _EdgeBasedContractorEdgeData( pathDistance, outData.originalEdges + inData.originalEdges, node, 0, inData.turnInstruction, true, true, false);; newEdge.data = _EdgeBasedContractorEdgeData( pathDistance, outData.originalEdges + inData.originalEdges, node, 0, inData.turnInstruction, true, true, false);;
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;
} }
void _DeleteIncomingEdges( _ThreadData* data, NodeID node ) { void _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 )
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( neighbours[i], node ); _graph->DeleteEdgesTo( neighbours[i], node );
} }
} }
bool _UpdateNeighbours( std::vector< double > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node ) { bool _UpdateNeighbours( std::vector< double > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node, bool topOnePercent ) {
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 );
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() );
int neighbourSize = ( int ) neighbours.size(); int neighbourSize = ( int ) neighbours.size();
for ( int i = 0, e = neighbourSize; i < e; ++i ) { for ( int i = 0, e = neighbourSize; 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, topOnePercent );
} }
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();
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;
double edgeQuotionFactor; double edgeQuotionFactor;
double originalQuotientFactor; double originalQuotientFactor;
double depthFactor; double depthFactor;
}; };
#endif // CONTRACTOR_H_INCLUDED #endif // CONTRACTOR_H_INCLUDED

View File

@ -312,7 +312,7 @@ short EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const N
//If street names stay the same and if we are certain that it is not a roundabout, we skip it. //If street names stay the same and if we are certain that it is not a roundabout, we skip it.
if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) if( (data1.nameID == data2.nameID) && (0 != data1.nameID))
return TurnInstructions.NoTurn; return TurnInstructions.NoTurn;
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) == 1) ) if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) )
return TurnInstructions.NoTurn; return TurnInstructions.NoTurn;
double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]); double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);

View File

@ -151,19 +151,19 @@ public:
//run two-Target Dijkstra routing step. //run two-Target Dijkstra routing step.
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){ while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
if(_forwardHeap->Size() > 0){ if(_forwardHeap->Size() > 0){
_RoutingStep(_forwardHeap, _backwardHeap, true, &middle1, &_localUpperbound1, 2*offset); _RoutingStep<true>(_forwardHeap, _backwardHeap, &middle1, &_localUpperbound1, 2*offset);
} }
if(_backwardHeap->Size() > 0){ if(_backwardHeap->Size() > 0){
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle1, &_localUpperbound1, 2*offset); _RoutingStep<false>(_backwardHeap, _forwardHeap, &middle1, &_localUpperbound1, 2*offset);
} }
} }
if(_backwardHeap2->Size() > 0) { if(_backwardHeap2->Size() > 0) {
while(_forwardHeap2->Size() + _backwardHeap2->Size() > 0){ while(_forwardHeap2->Size() + _backwardHeap2->Size() > 0){
if(_forwardHeap2->Size() > 0){ if(_forwardHeap2->Size() > 0){
_RoutingStep(_forwardHeap2, _backwardHeap2, true, &middle2, &_localUpperbound2, 2*offset); _RoutingStep<true>(_forwardHeap2, _backwardHeap2, &middle2, &_localUpperbound2, 2*offset);
} }
if(_backwardHeap2->Size() > 0){ if(_backwardHeap2->Size() > 0){
_RoutingStep(_backwardHeap2, _forwardHeap2, false, &middle2, &_localUpperbound2, 2*offset); _RoutingStep<false>(_backwardHeap2, _forwardHeap2, &middle2, &_localUpperbound2, 2*offset);
} }
} }
} }
@ -324,16 +324,14 @@ public:
} }
int offset = (phantomNodes.startPhantom.isBidirected() ? std::max(phantomNodes.startPhantom.weight1, phantomNodes.startPhantom.weight2) : phantomNodes.startPhantom.weight1) ; int offset = (phantomNodes.startPhantom.isBidirected() ? std::max(phantomNodes.startPhantom.weight1, phantomNodes.startPhantom.weight2) : phantomNodes.startPhantom.weight1) ;
offset += (phantomNodes.targetPhantom.isBidirected() ? std::max(phantomNodes.targetPhantom.weight1, phantomNodes.targetPhantom.weight2) : phantomNodes.targetPhantom.weight1) ; offset += (phantomNodes.targetPhantom.isBidirected() ? std::max(phantomNodes.targetPhantom.weight1, phantomNodes.targetPhantom.weight2) : phantomNodes.targetPhantom.weight1) ;
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){ while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
if(_forwardHeap->Size() > 0){ if(_forwardHeap->Size() > 0){
_RoutingStep(_forwardHeap, _backwardHeap, true, &middle, &_upperbound, 2*offset); _RoutingStep<true>(_forwardHeap, _backwardHeap, &middle, &_upperbound, 2*offset);
} }
if(_backwardHeap->Size() > 0){ if(_backwardHeap->Size() > 0){
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound, 2*offset); _RoutingStep<false>(_backwardHeap, _forwardHeap, &middle, &_upperbound, 2*offset);
} }
} }
// INFO("dist: " << _upperbound); // INFO("dist: " << _upperbound);
if ( _upperbound == INT_MAX ) { if ( _upperbound == INT_MAX ) {
return _upperbound; return _upperbound;
@ -341,7 +339,6 @@ public:
std::deque<NodeID> packedPath; std::deque<NodeID> packedPath;
_RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middle, packedPath); _RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middle, packedPath);
//Setting weights to correspond with that of the actual chosen path //Setting weights to correspond with that of the actual chosen path
if(packedPath[0] == phantomNodes.startPhantom.edgeBasedNode && phantomNodes.startPhantom.isBidirected()) { if(packedPath[0] == phantomNodes.startPhantom.edgeBasedNode && phantomNodes.startPhantom.isBidirected()) {
// INFO("Setting weight1=" << phantomNodes.startPhantom.weight1 << " to that of weight2=" << phantomNodes.startPhantom.weight2); // INFO("Setting weight1=" << phantomNodes.startPhantom.weight1 << " to that of weight2=" << phantomNodes.startPhantom.weight2);
@ -414,8 +411,8 @@ private:
// std::cout << std::endl; // std::cout << std::endl;
} }
template<bool forwardDirection>
inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, int *_upperbound, const int edgeBasedOffset) const { inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset) const {
const NodeID node = _forwardHeap->DeleteMin(); const NodeID node = _forwardHeap->DeleteMin();
const int distance = _forwardHeap->GetKey(node); const int distance = _forwardHeap->GetKey(node);
// INFO((forwardDirection ? "[forw]" : "[back]") << " settled node " << node << " at distance " << distance); // INFO((forwardDirection ? "[forw]" : "[back]") << " settled node " << node << " at distance " << distance);
@ -485,7 +482,7 @@ private:
inline void _UnpackPath(std::deque<NodeID> & packedPath, std::vector<_PathData> & unpackedPath) const { inline void _UnpackPath(std::deque<NodeID> & packedPath, std::vector<_PathData> & unpackedPath) const {
const unsigned sizeOfPackedPath = packedPath.size(); const unsigned sizeOfPackedPath = packedPath.size();
SimpleStack<std::pair<NodeID, NodeID> > recursionStack(sizeOfPackedPath); std::stack<std::pair<NodeID, NodeID> > recursionStack;
//We have to push the path in reverse order onto the stack because it's LIFO. //We have to push the path in reverse order onto the stack because it's LIFO.
for(unsigned i = sizeOfPackedPath-1; i > 0; --i){ for(unsigned i = sizeOfPackedPath-1; i > 0; --i){

View File

@ -66,12 +66,11 @@ public:
"\"status_message\": \"Cannot find route between points\","; "\"status_message\": \"Cannot find route between points\",";
} }
descriptionFactory.Run(config.z, durationOfTrip); descriptionFactory.Run(config.z, durationOfTrip);
reply.content += "\"route_summary\": {" reply.content += "\"route_summary\": {"
"\"total_distance\":"; "\"total_distance\":";
reply.content += descriptionFactory.summary.lengthString; reply.content += descriptionFactory.summary.lengthString;
reply.content += "," reply.content += ","
"\"total_time\":"; "\"total_time\":";
reply.content += descriptionFactory.summary.durationString; reply.content += descriptionFactory.summary.durationString;
reply.content += "," reply.content += ","
@ -107,9 +106,9 @@ public:
roundAbout.nameID = segment.nameID; roundAbout.nameID = segment.nameID;
roundAbout.startIndex = prefixSumOfNecessarySegments; roundAbout.startIndex = prefixSumOfNecessarySegments;
} else { } else {
if(0 != prefixSumOfNecessarySegments) if(0 != prefixSumOfNecessarySegments){
reply.content += ","; reply.content += ",";
}
reply.content += "[\""; reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) { if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) {
reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout]; reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout];

View File

@ -29,7 +29,7 @@
//====================== //======================
// OBJECTS // OBJECTS
//Map //Map
var HOST_ROUTING_URL = 'http://141.3.24.68:5000/viaroute'; var HOST_ROUTING_URL = 'http://141.3.24.240:5000/viaroute';
//var HOST_ROUTING_URL = 'http://routingdemo.geofabrik.de/route-via/'; //var HOST_ROUTING_URL = 'http://routingdemo.geofabrik.de/route-via/';
var HOST_WEBSITE = 'http://map.project-osrm.org/';//location.host var HOST_WEBSITE = 'http://map.project-osrm.org/';//location.host

View File

@ -26,7 +26,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "ObjectForPluginStruct.h" #include "ObjectForPluginStruct.h"
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h" #include "RouteParameters.h"
#include "../Util/StringUtil.h"
#include "../DataStructures/NodeInformationHelpDesk.h" #include "../DataStructures/NodeInformationHelpDesk.h"
/* /*
@ -57,33 +57,47 @@ public:
_Coordinate result; _Coordinate result;
nodeHelpDesk->FindNearestNodeCoordForLatLon(_Coordinate(lat, lon), result); nodeHelpDesk->FindNearestNodeCoordForLatLon(_Coordinate(lat, lon), result);
std::string tmp;
std::string JSONParameter;
//json
JSONParameter = routeParameters.options.Find("jsonp");
if("" != JSONParameter) {
reply.content += JSONParameter;
reply.content += "(";
}
//Write to stream //Write to stream
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
reply.content.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); reply.content += ("{");
reply.content.append("<kml xmlns=\"http://www.opengis.net/kml/2.2\">"); reply.content += ("\"version\":0.3,");
reply.content.append("<Placemark>"); reply.content += ("\"status\":0,");
reply.content += ("\"result\":");
std::stringstream out1; convertInternalLatLonToString(result.lat, tmp);
out1 << setprecision(10); reply.content += "[";
out1 << "<name>Nearest Place in map to " << lat/100000. << "," << lon/100000. << "</name>"; reply.content += tmp;
reply.content.append(out1.str()); convertInternalLatLonToString(result.lon, tmp);
reply.content.append("<Point>"); reply.content += ", ";
reply.content += tmp;
std::stringstream out2; reply.content += "]";
out2 << setprecision(10); reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Locate (v0.3)\"";
out2 << "<coordinates>" << result.lon / 100000. << "," << result.lat / 100000. << "</coordinates>"; reply.content += ("}");
reply.content.append(out2.str()); reply.headers.resize(3);
reply.content.append("</Point>"); if("" != JSONParameter) {
reply.content.append("</Placemark>"); reply.content += ")";
reply.content.append("</kml>"); reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers.resize(3); reply.headers[2].name = "Content-Disposition";
reply.headers[0].name = "Content-Length"; reply.headers[2].value = "attachment; filename=\"location.js\"";
reply.headers[0].value = boost::lexical_cast<std::string>(reply.content.size()); } else {
reply.headers[1].name = "Content-Type"; reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/vnd.google-earth.kml+xml"; reply.headers[1].value = "application/x-javascript";
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"placemark.kml\""; reply.headers[2].value = "attachment; filename=\"location.json\"";
}
reply.headers[0].name = "Content-Length";
intToString(reply.content.size(), tmp);
reply.headers[0].value = tmp;
return; return;
} }
private: private:

View File

@ -62,82 +62,47 @@ public:
//query to helpdesk //query to helpdesk
_Coordinate result; _Coordinate result;
nodeHelpDesk->FindNearestPointOnEdge(_Coordinate(lat, lon), result); nodeHelpDesk->FindNearestPointOnEdge(_Coordinate(lat, lon), result);
unsigned descriptorType = descriptorTable[routeParameters.options.Find("output")];
std::stringstream out1;
std::stringstream out2;
std::string tmp; std::string tmp;
std::string JSONParameter; std::string JSONParameter;
switch(descriptorType){ //json
case 1:
//json
JSONParameter = routeParameters.options.Find("jsonp"); JSONParameter = routeParameters.options.Find("jsonp");
if("" != JSONParameter) { if("" != JSONParameter) {
reply.content += JSONParameter; reply.content += JSONParameter;
reply.content += "(\n"; reply.content += "(";
}
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
reply.content += ("\"status\":0,");
reply.content += ("\"status_message\":");
out1 << setprecision(10);
out1 << "\"Nearest Place in map to " << lat/100000. << "," << lon/100000. << "\",";
reply.content.append(out1.str());
reply.content += ("\"coordinate\": ");
out2 << setprecision(10);
out2 << "[" << result.lat / 100000. << "," << result.lon / 100000. << "]";
reply.content.append(out2.str());
reply.content += ("}");
reply.headers.resize(3);
reply.headers[0].name = "Content-Length";
intToString(reply.content.size(), tmp);
reply.headers[0].value = tmp;if("" != JSONParameter) {
reply.content += ")\n";
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"location.js\"";
} else {
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/x-javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"location.json\"";
}
break;
default:
reply.status = http::Reply::ok;
//Write to stream
reply.content.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
reply.content.append("<kml xmlns=\"http://www.opengis.net/kml/2.2\">");
reply.content.append("<Placemark>");
out1 << setprecision(10);
out1 << "<name>Nearest Place in map to " << lat/100000. << "," << lon/100000. << "</name>";
reply.content.append(out1.str());
reply.content.append("<Point>");
out2 << setprecision(10);
out2 << "<coordinates>" << result.lon / 100000. << "," << result.lat / 100000. << "</coordinates>";
reply.content.append(out2.str());
reply.content.append("</Point>");
reply.content.append("</Placemark>");
reply.content.append("</kml>");
reply.headers.resize(3);
reply.headers[0].name = "Content-Length";
reply.headers[0].value = boost::lexical_cast<std::string>(reply.content.size());
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/vnd.google-earth.kml+xml";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"placemark.kml\"";
break;
} }
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
reply.content += ("\"status\":0,");
reply.content += ("\"result\":");
convertInternalLatLonToString(result.lat, tmp);
reply.content += "[";
reply.content += tmp;
convertInternalLatLonToString(result.lon, tmp);
reply.content += ", ";
reply.content += tmp;
reply.content += "]";
reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Nearest (v0.3)\"";
reply.content += ("}");
reply.headers.resize(3);
if("" != JSONParameter) {
reply.content += ")";
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"location.js\"";
} else {
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/x-javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"location.json\"";
}
reply.headers[0].name = "Content-Length";
intToString(reply.content.size(), tmp);
reply.headers[0].value = tmp;
} }
private: private:
NodeInformationHelpDesk * nodeHelpDesk; NodeInformationHelpDesk * nodeHelpDesk;

View File

@ -119,14 +119,12 @@ public:
} }
rawRoute.rawViaNodeCoordinates.push_back(targetCoord); rawRoute.rawViaNodeCoordinates.push_back(targetCoord);
vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size()); vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size());
for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) { for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) {
searchEngine->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i]); searchEngine->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i]);
} }
unsigned distance = 0; unsigned distance = 0;
//single route or via point routing //single route or via point routing
if(0 == routeParameters.viaPoints.size()) { if(2 == rawRoute.rawViaNodeCoordinates.size()) {
PhantomNodes segmentPhantomNodes; PhantomNodes segmentPhantomNodes;
segmentPhantomNodes.startPhantom = phantomNodeVector[0]; segmentPhantomNodes.startPhantom = phantomNodeVector[0];
segmentPhantomNodes.targetPhantom = phantomNodeVector[1]; segmentPhantomNodes.targetPhantom = phantomNodeVector[1];
@ -145,7 +143,6 @@ public:
if(INT_MAX == distance ) { if(INT_MAX == distance ) {
DEBUG( "Error occurred, single path not found" ); DEBUG( "Error occurred, single path not found" );
} }
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
BaseDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > > * desc; BaseDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > > * desc;
@ -197,7 +194,6 @@ public:
desc->SetConfig(descriptorConfig); desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, *searchEngine, distance); desc->Run(reply, rawRoute, phantomNodes, *searchEngine, distance);
if("" != JSONParameter) { if("" != JSONParameter) {
reply.content += ")\n"; reply.content += ")\n";
} }

View File

@ -201,6 +201,6 @@ env.Program(target = 'osrm-extract', source = ["extractor.cpp", Glob('DataStruct
env.Program(target = 'osrm-prepare', source = ["createHierarchy.cpp", 'Contractor/EdgeBasedGraphFactory.cpp', Glob('Util/SRTMLookup/*.cpp'), Glob('Algorithms/*.cpp')]) env.Program(target = 'osrm-prepare', source = ["createHierarchy.cpp", 'Contractor/EdgeBasedGraphFactory.cpp', Glob('Util/SRTMLookup/*.cpp'), Glob('Algorithms/*.cpp')])
env.Append(CCFLAGS = ['-lboost_regex', '-lboost_iostreams', '-lbz2', '-lz', '-lprotobuf']) env.Append(CCFLAGS = ['-lboost_regex', '-lboost_iostreams', '-lbz2', '-lz', '-lprotobuf'])
env.Append(LINKFLAGS = ['-lboost_system']) env.Append(LINKFLAGS = ['-lboost_system'])
env.Program(target = 'osrm-routed', source = ["routed.cpp", 'Descriptors/DescriptionFactory.cpp', Glob('ThirdParty/*.cc')], CCFLAGS = ['-DROUTED']) env.Program(target = 'osrm-routed', source = ["routed.cpp", 'Descriptors/DescriptionFactory.cpp', Glob('ThirdParty/*.cc')], CCFLAGS = env['CCFLAGS'] + ['-DROUTED'])
env = conf.Finish() env = conf.Finish()

View File

@ -52,10 +52,11 @@ enum CompressionType {
struct Request { struct Request {
std::string uri; std::string uri;
boost::asio::ip::address endpoint;
}; };
struct Reply { struct Reply {
Reply() : status(ok) { content.reserve(1000000); } Reply() : status(ok) { content.reserve(2 << 20); }
enum status_type { enum status_type {
ok = 200, ok = 200,
badRequest = 400, badRequest = 400,
@ -63,9 +64,9 @@ struct Reply {
} status; } status;
std::vector<Header> headers; std::vector<Header> headers;
std::string content;
std::vector<boost::asio::const_buffer> toBuffers(); std::vector<boost::asio::const_buffer> toBuffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers(); std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::string content;
static Reply stockReply(status_type status); static Reply stockReply(status_type status);
void setSize(unsigned size) { void setSize(unsigned size) {
for (std::size_t i = 0; i < headers.size(); ++i) { for (std::size_t i = 0; i < headers.size(); ++i) {

View File

@ -50,7 +50,7 @@ public:
/// Start the first asynchronous operation for the connection. /// Start the first asynchronous operation for the connection.
void start() { void start() {
TCPsocket.async_read_some(boost::asio::buffer(incomingDataBuffer), strand.wrap( boost::bind(&Connection::handleRead, this->shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))); TCPsocket.async_read_some(boost::asio::buffer(incomingDataBuffer), strand.wrap( boost::bind(&Connection::handleRead, this->shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
} }
private: private:
@ -68,7 +68,7 @@ private:
// std::cout << "[debug] using deflate" << std::endl; // std::cout << "[debug] using deflate" << std::endl;
// if(compressionType == noCompression) // if(compressionType == noCompression)
// std::cout << "[debug] no compression" << std::endl; // std::cout << "[debug] no compression" << std::endl;
request.endpoint = TCPsocket.remote_endpoint().address();
requestHandler.handle_request(request, reply); requestHandler.handle_request(request, reply);
Header compressionHeader; Header compressionHeader;

View File

@ -51,7 +51,7 @@ public:
void handle_request(const Request& req, Reply& rep){ void handle_request(const Request& req, Reply& rep){
//parse command //parse command
std::string request(req.uri); std::string request(req.uri);
// INFO( "[r] " << request ); INFO( req.endpoint.to_string() << " " << request );
std::string command; std::string command;
std::size_t firstAmpPosition = request.find_first_of("?"); std::size_t firstAmpPosition = request.find_first_of("?");
command = request.substr(1,firstAmpPosition-1); command = request.substr(1,firstAmpPosition-1);

View File

@ -2,8 +2,8 @@ Threads = 8
IP = 0.0.0.0 IP = 0.0.0.0
Port = 5000 Port = 5000
hsgrData=/opt/osm/germany.osrm.hsgr hsgrData=/opt/osm/berlin.osrm.hsgr
nodesData=/opt/osm/germany.osrm.nodes nodesData=/opt/osm/berlin.osrm.nodes
ramIndex=/opt/osm/germany.osrm.ramIndex ramIndex=/opt/osm/berlin.osrm.ramIndex
fileIndex=/opt/osm/germany.osrm.fileIndex fileIndex=/opt/osm/berlin.osrm.fileIndex
namesData=/opt/osm/germany.osrm.names namesData=/opt/osm/berlin.osrm.names