Merge branch 'master' of
https://DennisOSRM@github.com/DennisOSRM/Project-OSRM.git
This commit is contained in:
commit
a88ad71be6
@ -39,7 +39,7 @@ class DouglasPeucker {
|
||||
private:
|
||||
typedef std::pair<std::size_t, std::size_t> PairOfPoints;
|
||||
//Stack to simulate the recursion
|
||||
SimpleStack<PairOfPoints > recursionStack;
|
||||
std::stack<PairOfPoints > recursionStack;
|
||||
|
||||
double ComputeDistanceOfPointToLine(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target) {
|
||||
double r;
|
||||
@ -81,7 +81,7 @@ public:
|
||||
std::size_t leftBorderOfRange = 0;
|
||||
std::size_t rightBorderOfRange = 1;
|
||||
//Sweep linerarily over array and identify those ranges that need to be checked
|
||||
recursionStack.hint(inputVector.size());
|
||||
// recursionStack.hint(inputVector.size());
|
||||
do {
|
||||
assert(inputVector[leftBorderOfRange].necessary);
|
||||
assert(inputVector[inputVector.size()-1].necessary);
|
||||
|
@ -41,519 +41,539 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
class Contractor {
|
||||
|
||||
private:
|
||||
struct _EdgeBasedContractorEdgeData {
|
||||
_EdgeBasedContractorEdgeData() :
|
||||
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) :
|
||||
distance(_distance), originalEdges(_originalEdges), via(_via), nameID(_nameID), turnInstruction(_turnInstruction), shortcut(_shortcut), forward(_forward), backward(_backward) {}
|
||||
unsigned distance;
|
||||
unsigned originalEdges;
|
||||
unsigned via;
|
||||
unsigned nameID;
|
||||
short turnInstruction;
|
||||
bool shortcut:1;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
} data;
|
||||
struct _EdgeBasedContractorEdgeData {
|
||||
_EdgeBasedContractorEdgeData() :
|
||||
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) :
|
||||
distance(_distance), originalEdges(_originalEdges), via(_via), nameID(_nameID), turnInstruction(_turnInstruction), shortcut(_shortcut), forward(_forward), backward(_backward) {}
|
||||
unsigned distance;
|
||||
unsigned originalEdges;
|
||||
unsigned via;
|
||||
unsigned nameID;
|
||||
short turnInstruction;
|
||||
bool shortcut:1;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
} data;
|
||||
|
||||
struct _HeapData {
|
||||
short hop;
|
||||
bool target;
|
||||
_HeapData() : hop(0), target(false) {}
|
||||
_HeapData( short h, bool t ) : hop(h), target(t) {}
|
||||
};
|
||||
struct _HeapData {
|
||||
short hop;
|
||||
bool target;
|
||||
_HeapData() : hop(0), target(false) {}
|
||||
_HeapData( short h, bool t ) : hop(h), target(t) {}
|
||||
};
|
||||
|
||||
typedef DynamicGraph< _EdgeBasedContractorEdgeData > _DynamicGraph;
|
||||
typedef BinaryHeap< NodeID, NodeID, int, _HeapData > _Heap;
|
||||
typedef _DynamicGraph::InputEdge _ImportEdge;
|
||||
typedef DynamicGraph< _EdgeBasedContractorEdgeData > _DynamicGraph;
|
||||
typedef BinaryHeap< NodeID, NodeID, int, _HeapData > _Heap;
|
||||
typedef _DynamicGraph::InputEdge _ImportEdge;
|
||||
|
||||
struct _ThreadData {
|
||||
_Heap heap;
|
||||
std::vector< _ImportEdge > insertedEdges;
|
||||
std::vector< NodeID > neighbours;
|
||||
_ThreadData( NodeID nodes ): heap( nodes ) {
|
||||
}
|
||||
};
|
||||
struct _ThreadData {
|
||||
_Heap heap;
|
||||
std::vector< _ImportEdge > insertedEdges;
|
||||
std::vector< NodeID > neighbours;
|
||||
_ThreadData( NodeID nodes ): heap( nodes ) {
|
||||
}
|
||||
};
|
||||
|
||||
struct _PriorityData {
|
||||
int depth;
|
||||
NodeID bias;
|
||||
_PriorityData() : depth(0), bias(0) { }
|
||||
};
|
||||
struct _PriorityData {
|
||||
int depth;
|
||||
NodeID bias;
|
||||
_PriorityData() : depth(0), bias(0) { }
|
||||
};
|
||||
|
||||
struct _ContractionInformation {
|
||||
int edgesDeleted;
|
||||
int edgesAdded;
|
||||
int originalEdgesDeleted;
|
||||
int originalEdgesAdded;
|
||||
_ContractionInformation() : edgesDeleted(0), edgesAdded(0), originalEdgesDeleted(0), originalEdgesAdded(0) {}
|
||||
};
|
||||
struct _ContractionInformation {
|
||||
int edgesDeleted;
|
||||
int edgesAdded;
|
||||
int originalEdgesDeleted;
|
||||
int originalEdgesAdded;
|
||||
_ContractionInformation() : edgesDeleted(0), edgesAdded(0), originalEdgesDeleted(0), originalEdgesAdded(0) {}
|
||||
};
|
||||
|
||||
struct _NodePartitionor {
|
||||
bool operator()( std::pair< NodeID, bool > & nodeData ) const {
|
||||
return !nodeData.second;
|
||||
}
|
||||
};
|
||||
struct _NodePartitionor {
|
||||
bool operator()( std::pair< NodeID, bool > & nodeData ) const {
|
||||
return !nodeData.second;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
template< class InputEdge >
|
||||
Contractor( int nodes, std::vector< InputEdge >& inputEdges, const double eqf = 8.4, const double oqf = 4.1, const double df = 3.)
|
||||
: edgeQuotionFactor(eqf), originalQuotientFactor(oqf), depthFactor(df) {
|
||||
std::vector< _ImportEdge > edges;
|
||||
edges.reserve( 2 * inputEdges.size() );
|
||||
BOOST_FOREACH(InputEdge & currentEdge, inputEdges) {
|
||||
_ImportEdge edge;
|
||||
edge.source = currentEdge.source();
|
||||
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());
|
||||
template< class InputEdge >
|
||||
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) {
|
||||
std::vector< _ImportEdge > edges;
|
||||
edges.reserve( 2 * inputEdges.size() );
|
||||
BOOST_FOREACH(InputEdge & currentEdge, inputEdges) {
|
||||
_ImportEdge edge;
|
||||
edge.source = currentEdge.source();
|
||||
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());
|
||||
|
||||
assert( edge.data.distance > 0 );
|
||||
assert( edge.data.distance > 0 );
|
||||
#ifdef NDEBUG
|
||||
if ( edge.data.distance > 24 * 60 * 60 * 10 ) {
|
||||
std::cout << "Edge Weight too large -> May lead to invalid CH" << std::endl;
|
||||
continue;
|
||||
}
|
||||
if ( edge.data.distance > 24 * 60 * 60 * 10 ) {
|
||||
std::cout << "Edge Weight too large -> May lead to invalid CH" << std::endl;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
edges.push_back( edge );
|
||||
std::swap( edge.source, edge.target );
|
||||
edge.data.forward = currentEdge.isBackward();
|
||||
edge.data.backward = currentEdge.isForward();
|
||||
edges.push_back( edge );
|
||||
}
|
||||
//remove data from memory
|
||||
std::vector< InputEdge >().swap( inputEdges );
|
||||
edges.push_back( edge );
|
||||
std::swap( edge.source, edge.target );
|
||||
edge.data.forward = currentEdge.isBackward();
|
||||
edge.data.backward = currentEdge.isForward();
|
||||
edges.push_back( edge );
|
||||
}
|
||||
//remove data from memory
|
||||
std::vector< InputEdge >().swap( inputEdges );
|
||||
|
||||
#ifdef _GLIBCXX_PARALLEL
|
||||
__gnu_parallel::sort( edges.begin(), edges.end() );
|
||||
__gnu_parallel::sort( edges.begin(), edges.end() );
|
||||
#else
|
||||
sort( edges.begin(), edges.end() );
|
||||
sort( edges.begin(), edges.end() );
|
||||
#endif
|
||||
NodeID edge = 0;
|
||||
for ( NodeID i = 0; i < edges.size(); ) {
|
||||
const NodeID source = edges[i].source;
|
||||
const NodeID target = edges[i].target;
|
||||
const NodeID via = edges[i].data.via;
|
||||
const short turnType = edges[i].data.turnInstruction;
|
||||
//remove eigenloops
|
||||
if ( source == target ) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
_ImportEdge forwardEdge;
|
||||
_ImportEdge backwardEdge;
|
||||
forwardEdge.source = backwardEdge.source = source;
|
||||
forwardEdge.target = backwardEdge.target = target;
|
||||
forwardEdge.data.forward = backwardEdge.data.backward = true;
|
||||
forwardEdge.data.backward = backwardEdge.data.forward = false;
|
||||
forwardEdge.data.turnInstruction = backwardEdge.data.turnInstruction = turnType;
|
||||
forwardEdge.data.nameID = backwardEdge.data.nameID = edges[i].data.nameID;
|
||||
forwardEdge.data.shortcut = backwardEdge.data.shortcut = false;
|
||||
forwardEdge.data.via = backwardEdge.data.via = via;
|
||||
forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1;
|
||||
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
|
||||
//remove parallel edges
|
||||
while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) {
|
||||
if ( edges[i].data.forward )
|
||||
forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance );
|
||||
if ( edges[i].data.backward )
|
||||
backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance );
|
||||
i++;
|
||||
}
|
||||
//merge edges (s,t) and (t,s) into bidirectional edge
|
||||
if ( forwardEdge.data.distance == backwardEdge.data.distance ) {
|
||||
if ( (int)forwardEdge.data.distance != std::numeric_limits< int >::max() ) {
|
||||
forwardEdge.data.backward = true;
|
||||
edges[edge++] = forwardEdge;
|
||||
}
|
||||
} else { //insert seperate edges
|
||||
if ( ((int)forwardEdge.data.distance) != std::numeric_limits< int >::max() ) {
|
||||
edges[edge++] = forwardEdge;
|
||||
}
|
||||
if ( (int)backwardEdge.data.distance != std::numeric_limits< int >::max() ) {
|
||||
edges[edge++] = backwardEdge;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "ok" << std::endl << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl;
|
||||
edges.resize( edge );
|
||||
_graph.reset( new _DynamicGraph( nodes, edges ) );
|
||||
std::vector< _ImportEdge >().swap( edges );
|
||||
}
|
||||
NodeID edge = 0;
|
||||
for ( NodeID i = 0; i < edges.size(); ) {
|
||||
const NodeID source = edges[i].source;
|
||||
const NodeID target = edges[i].target;
|
||||
const NodeID via = edges[i].data.via;
|
||||
const short turnType = edges[i].data.turnInstruction;
|
||||
//remove eigenloops
|
||||
if ( source == target ) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
_ImportEdge forwardEdge;
|
||||
_ImportEdge backwardEdge;
|
||||
forwardEdge.source = backwardEdge.source = source;
|
||||
forwardEdge.target = backwardEdge.target = target;
|
||||
forwardEdge.data.forward = backwardEdge.data.backward = true;
|
||||
forwardEdge.data.backward = backwardEdge.data.forward = false;
|
||||
forwardEdge.data.turnInstruction = backwardEdge.data.turnInstruction = turnType;
|
||||
forwardEdge.data.nameID = backwardEdge.data.nameID = edges[i].data.nameID;
|
||||
forwardEdge.data.shortcut = backwardEdge.data.shortcut = false;
|
||||
forwardEdge.data.via = backwardEdge.data.via = via;
|
||||
forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1;
|
||||
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
|
||||
//remove parallel edges
|
||||
while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) {
|
||||
if ( edges[i].data.forward )
|
||||
forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance );
|
||||
if ( edges[i].data.backward )
|
||||
backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance );
|
||||
i++;
|
||||
}
|
||||
//merge edges (s,t) and (t,s) into bidirectional edge
|
||||
if ( forwardEdge.data.distance == backwardEdge.data.distance ) {
|
||||
if ( (int)forwardEdge.data.distance != std::numeric_limits< int >::max() ) {
|
||||
forwardEdge.data.backward = true;
|
||||
edges[edge++] = forwardEdge;
|
||||
}
|
||||
} else { //insert seperate edges
|
||||
if ( ((int)forwardEdge.data.distance) != std::numeric_limits< int >::max() ) {
|
||||
edges[edge++] = forwardEdge;
|
||||
}
|
||||
if ( (int)backwardEdge.data.distance != std::numeric_limits< int >::max() ) {
|
||||
edges[edge++] = backwardEdge;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "ok" << std::endl << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl;
|
||||
edges.resize( edge );
|
||||
_graph.reset( new _DynamicGraph( nodes, edges ) );
|
||||
std::vector< _ImportEdge >().swap( edges );
|
||||
}
|
||||
|
||||
~Contractor() { }
|
||||
~Contractor() { }
|
||||
|
||||
void Run() {
|
||||
const NodeID numberOfNodes = _graph->GetNumberOfNodes();
|
||||
Percent p (numberOfNodes);
|
||||
void Run() {
|
||||
const NodeID numberOfNodes = _graph->GetNumberOfNodes();
|
||||
Percent p (numberOfNodes);
|
||||
|
||||
unsigned maxThreads = omp_get_max_threads();
|
||||
std::vector < _ThreadData* > threadData;
|
||||
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
||||
threadData.push_back( new _ThreadData( numberOfNodes ) );
|
||||
}
|
||||
std::cout << "Contractor is using " << maxThreads << " threads" << std::endl;
|
||||
unsigned maxThreads = omp_get_max_threads();
|
||||
std::vector < _ThreadData* > threadData;
|
||||
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
||||
threadData.push_back( new _ThreadData( numberOfNodes ) );
|
||||
}
|
||||
std::cout << "Contractor is using " << maxThreads << " threads" << std::endl;
|
||||
|
||||
NodeID numberOfContractedNodes = 0;
|
||||
std::vector< std::pair< NodeID, bool > > remainingNodes( numberOfNodes );
|
||||
std::vector< double > nodePriority( numberOfNodes );
|
||||
std::vector< _PriorityData > nodeData( numberOfNodes );
|
||||
NodeID numberOfContractedNodes = 0;
|
||||
std::vector< std::pair< NodeID, bool > > remainingNodes( numberOfNodes );
|
||||
std::vector< double > nodePriority( numberOfNodes );
|
||||
std::vector< _PriorityData > nodeData( numberOfNodes );
|
||||
|
||||
//initialize the variables
|
||||
//initialize the variables
|
||||
#pragma omp parallel for schedule ( guided )
|
||||
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
|
||||
remainingNodes[x].first = x;
|
||||
std::random_shuffle( remainingNodes.begin(), remainingNodes.end() );
|
||||
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
|
||||
nodeData[remainingNodes[x].first].bias = x;
|
||||
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
|
||||
remainingNodes[x].first = x;
|
||||
std::random_shuffle( remainingNodes.begin(), remainingNodes.end() );
|
||||
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
|
||||
nodeData[remainingNodes[x].first].bias = x;
|
||||
|
||||
std::cout << "initializing elimination PQ ..." << std::flush;
|
||||
std::cout << "initializing elimination PQ ..." << std::flush;
|
||||
#pragma omp parallel
|
||||
{
|
||||
_ThreadData* data = threadData[omp_get_thread_num()];
|
||||
{
|
||||
_ThreadData* data = threadData[omp_get_thread_num()];
|
||||
#pragma omp parallel for schedule ( guided )
|
||||
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) {
|
||||
nodePriority[x] = _Evaluate( data, &nodeData[x], x );
|
||||
}
|
||||
}
|
||||
std::cout << "ok" << std::endl << "preprocessing ..." << std::flush;
|
||||
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) {
|
||||
nodePriority[x] = _Evaluate( data, &nodeData[x], x, false );
|
||||
}
|
||||
}
|
||||
std::cout << "ok" << std::endl << "preprocessing ..." << std::flush;
|
||||
|
||||
while ( numberOfContractedNodes < numberOfNodes ) {
|
||||
const int last = ( int ) remainingNodes.size();
|
||||
while ( numberOfContractedNodes < numberOfNodes ) {
|
||||
bool topOnePercent = (numberOfNodes - numberOfContractedNodes) > 0.01*numberOfNodes;
|
||||
const int last = ( int ) remainingNodes.size();
|
||||
#pragma omp parallel
|
||||
{
|
||||
//determine independent node set
|
||||
_ThreadData* const data = threadData[omp_get_thread_num()];
|
||||
{
|
||||
//determine independent node set
|
||||
_ThreadData* const data = threadData[omp_get_thread_num()];
|
||||
#pragma omp for schedule ( guided )
|
||||
for ( int i = 0; i < last; ++i ) {
|
||||
const NodeID node = remainingNodes[i].first;
|
||||
remainingNodes[i].second = _IsIndependent( nodePriority, nodeData, data, node );
|
||||
}
|
||||
}
|
||||
_NodePartitionor functor;
|
||||
const std::vector < std::pair < NodeID, bool > >::const_iterator first = stable_partition( remainingNodes.begin(), remainingNodes.end(), functor );
|
||||
const int firstIndependent = first - remainingNodes.begin();
|
||||
//contract independent nodes
|
||||
for ( int i = 0; i < last; ++i ) {
|
||||
const NodeID node = remainingNodes[i].first;
|
||||
remainingNodes[i].second = _IsIndependent( nodePriority, nodeData, data, node );
|
||||
}
|
||||
}
|
||||
_NodePartitionor functor;
|
||||
const std::vector < std::pair < NodeID, bool > >::const_iterator first = stable_partition( remainingNodes.begin(), remainingNodes.end(), functor );
|
||||
const int firstIndependent = first - remainingNodes.begin();
|
||||
//contract independent nodes
|
||||
#pragma omp parallel
|
||||
{
|
||||
_ThreadData* data = threadData[omp_get_thread_num()];
|
||||
{
|
||||
_ThreadData* data = threadData[omp_get_thread_num()];
|
||||
#pragma omp for schedule ( guided ) nowait
|
||||
for ( int position = firstIndependent ; position < last; ++position ) {
|
||||
NodeID x = remainingNodes[position].first;
|
||||
_Contract< false > ( data, x );
|
||||
nodePriority[x] = -1;
|
||||
}
|
||||
std::sort( data->insertedEdges.begin(), data->insertedEdges.end() );
|
||||
}
|
||||
for ( int position = firstIndependent ; position < last; ++position ) {
|
||||
NodeID x = remainingNodes[position].first;
|
||||
if(topOnePercent)
|
||||
_Contract< false, true > ( data, x );
|
||||
else
|
||||
_Contract< false, false > ( data, x );
|
||||
nodePriority[x] = -1;
|
||||
}
|
||||
std::sort( data->insertedEdges.begin(), data->insertedEdges.end() );
|
||||
}
|
||||
#pragma omp parallel
|
||||
{
|
||||
_ThreadData* data = threadData[omp_get_thread_num()];
|
||||
{
|
||||
_ThreadData* data = threadData[omp_get_thread_num()];
|
||||
#pragma omp for schedule ( guided ) nowait
|
||||
for ( int position = firstIndependent ; position < last; ++position ) {
|
||||
NodeID x = remainingNodes[position].first;
|
||||
_DeleteIncomingEdges( data, x );
|
||||
}
|
||||
}
|
||||
//insert new edges
|
||||
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
||||
_ThreadData& data = *threadData[threadNum];
|
||||
for ( int i = 0; i < ( int ) data.insertedEdges.size(); ++i ) {
|
||||
const _ImportEdge& edge = data.insertedEdges[i];
|
||||
_graph->InsertEdge( edge.source, edge.target, edge.data );
|
||||
}
|
||||
data.insertedEdges.clear();
|
||||
}
|
||||
//update priorities
|
||||
for ( int position = firstIndependent ; position < last; ++position ) {
|
||||
NodeID x = remainingNodes[position].first;
|
||||
_DeleteIncomingEdges( data, x );
|
||||
}
|
||||
}
|
||||
//insert new edges
|
||||
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
||||
_ThreadData& data = *threadData[threadNum];
|
||||
for ( int i = 0; i < ( int ) data.insertedEdges.size(); ++i ) {
|
||||
const _ImportEdge& edge = data.insertedEdges[i];
|
||||
_DynamicGraph::EdgeIterator currentEdgeID = _graph->FindEdge(edge.source, edge.target);
|
||||
if(currentEdgeID != _graph->EndEdges(edge.source)) {
|
||||
_DynamicGraph::EdgeData & currentEdgeData = _graph->GetEdgeData(currentEdgeID);
|
||||
if(edge.data.forward == currentEdgeData.forward && edge.data.backward == currentEdgeData.backward ) {
|
||||
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
|
||||
{
|
||||
_ThreadData* data = threadData[omp_get_thread_num()];
|
||||
{
|
||||
_ThreadData* data = threadData[omp_get_thread_num()];
|
||||
#pragma omp for schedule ( guided ) nowait
|
||||
for ( int position = firstIndependent ; position < last; ++position ) {
|
||||
NodeID x = remainingNodes[position].first;
|
||||
_UpdateNeighbours( nodePriority, nodeData, data, x );
|
||||
}
|
||||
}
|
||||
//remove contracted nodes from the pool
|
||||
numberOfContractedNodes += last - firstIndependent;
|
||||
remainingNodes.resize( firstIndependent );
|
||||
std::vector< std::pair< NodeID, bool > >( remainingNodes ).swap( remainingNodes );
|
||||
p.printStatus(numberOfContractedNodes);
|
||||
}
|
||||
for ( int position = firstIndependent ; position < last; ++position ) {
|
||||
NodeID x = remainingNodes[position].first;
|
||||
_UpdateNeighbours( nodePriority, nodeData, data, x, topOnePercent );
|
||||
}
|
||||
}
|
||||
//remove contracted nodes from the pool
|
||||
numberOfContractedNodes += last - firstIndependent;
|
||||
remainingNodes.resize( firstIndependent );
|
||||
std::vector< std::pair< NodeID, bool > >( remainingNodes ).swap( remainingNodes );
|
||||
p.printStatus(numberOfContractedNodes);
|
||||
}
|
||||
|
||||
for ( unsigned threadNum = 0; threadNum < maxThreads; threadNum++ ) {
|
||||
delete threadData[threadNum];
|
||||
}
|
||||
}
|
||||
for ( unsigned threadNum = 0; threadNum < maxThreads; threadNum++ ) {
|
||||
delete threadData[threadNum];
|
||||
}
|
||||
}
|
||||
|
||||
template< class Edge >
|
||||
void GetEdges( std::vector< Edge >& edges ) {
|
||||
NodeID numberOfNodes = _graph->GetNumberOfNodes();
|
||||
for ( NodeID node = 0; node < numberOfNodes; ++node ) {
|
||||
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; edge++ ) {
|
||||
const NodeID target = _graph->GetTarget( edge );
|
||||
const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge );
|
||||
Edge newEdge;
|
||||
newEdge.source = node;
|
||||
newEdge.target = target;
|
||||
newEdge.data.distance = data.distance;
|
||||
newEdge.data.shortcut = data.shortcut;
|
||||
newEdge.data.via = data.via;
|
||||
newEdge.data.nameID = data.nameID;
|
||||
newEdge.data.turnInstruction = data.turnInstruction;
|
||||
newEdge.data.forward = data.forward;
|
||||
newEdge.data.backward = data.backward;
|
||||
edges.push_back( newEdge );
|
||||
}
|
||||
}
|
||||
}
|
||||
template< class Edge >
|
||||
void GetEdges( std::vector< Edge >& edges ) {
|
||||
NodeID numberOfNodes = _graph->GetNumberOfNodes();
|
||||
for ( NodeID node = 0; node < numberOfNodes; ++node ) {
|
||||
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; edge++ ) {
|
||||
const NodeID target = _graph->GetTarget( edge );
|
||||
const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge );
|
||||
Edge newEdge;
|
||||
newEdge.source = node;
|
||||
newEdge.target = target;
|
||||
newEdge.data.distance = data.distance;
|
||||
newEdge.data.shortcut = data.shortcut;
|
||||
newEdge.data.via = data.via;
|
||||
newEdge.data.nameID = data.nameID;
|
||||
newEdge.data.turnInstruction = data.turnInstruction;
|
||||
newEdge.data.forward = data.forward;
|
||||
newEdge.data.backward = data.backward;
|
||||
edges.push_back( newEdge );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
unsigned targetsFound = 0;
|
||||
while ( heap.Size() > 0 ) {
|
||||
const NodeID node = heap.DeleteMin();
|
||||
const int distance = heap.GetKey( node );
|
||||
const short currentHop = heap.GetData( node ).hop+1;
|
||||
int nodes = 0;
|
||||
unsigned targetsFound = 0;
|
||||
while ( heap.Size() > 0 ) {
|
||||
const NodeID node = heap.DeleteMin();
|
||||
const int distance = heap.GetKey( node );
|
||||
const short currentHop = heap.GetData( node ).hop+1;
|
||||
|
||||
if ( ++nodes > maxNodes )
|
||||
return;
|
||||
//Destination settled?
|
||||
if ( distance > maxDistance )
|
||||
return;
|
||||
if ( ++nodes > maxNodes )
|
||||
return;
|
||||
//Destination settled?
|
||||
if ( distance > maxDistance )
|
||||
return;
|
||||
|
||||
if ( heap.GetData( node ).target ) {
|
||||
++targetsFound;
|
||||
if ( targetsFound >= numTargets )
|
||||
return;
|
||||
}
|
||||
if ( heap.GetData( node ).target ) {
|
||||
++targetsFound;
|
||||
if ( targetsFound >= numTargets )
|
||||
return;
|
||||
}
|
||||
|
||||
if(currentHop >= hopLimit)
|
||||
if(currentHop >= hopLimit)
|
||||
continue;
|
||||
|
||||
//iterate over all edges of node
|
||||
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) {
|
||||
const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge );
|
||||
if ( !data.forward )
|
||||
continue;
|
||||
const NodeID to = _graph->GetTarget( edge );
|
||||
const int toDistance = distance + data.distance;
|
||||
//iterate over all edges of node
|
||||
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) {
|
||||
const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge );
|
||||
if ( !data.forward )
|
||||
continue;
|
||||
const NodeID to = _graph->GetTarget( edge );
|
||||
const int toDistance = distance + data.distance;
|
||||
|
||||
//New Node discovered -> Add to Heap + Node Info Storage
|
||||
if ( !heap.WasInserted( to ) )
|
||||
heap.Insert( to, toDistance, _HeapData(currentHop, false) );
|
||||
//New Node discovered -> Add to Heap + Node Info Storage
|
||||
if ( !heap.WasInserted( to ) )
|
||||
heap.Insert( to, toDistance, _HeapData(currentHop, false) );
|
||||
|
||||
//Found a shorter Path -> Update distance
|
||||
else if ( toDistance < heap.GetKey( to ) ) {
|
||||
heap.DecreaseKey( to, toDistance );
|
||||
heap.GetData( to ).hop = currentHop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Found a shorter Path -> Update distance
|
||||
else if ( toDistance < heap.GetKey( to ) ) {
|
||||
heap.DecreaseKey( to, toDistance );
|
||||
heap.GetData( to ).hop = currentHop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node ){
|
||||
_ContractionInformation stats;
|
||||
double _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node, bool topOnePercent ){
|
||||
_ContractionInformation stats;
|
||||
|
||||
//perform simulated contraction
|
||||
_Contract< true > ( data, node, &stats );
|
||||
//perform simulated contraction
|
||||
if(topOnePercent)
|
||||
_Contract< true, true > ( data, node, &stats );
|
||||
else
|
||||
_Contract< true, false > ( data, node, &stats );
|
||||
|
||||
// Result will contain the priority
|
||||
if ( stats.edgesDeleted == 0 || stats.originalEdgesDeleted == 0 )
|
||||
return depthFactor * nodeData->depth;
|
||||
return edgeQuotionFactor * ((( double ) stats.edgesAdded ) / stats.edgesDeleted ) + originalQuotientFactor * ((( double ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + depthFactor * nodeData->depth;
|
||||
}
|
||||
// Result will contain the priority
|
||||
if ( stats.edgesDeleted == 0 || stats.originalEdgesDeleted == 0 )
|
||||
return 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 ) {
|
||||
_Heap& heap = data->heap;
|
||||
int insertedEdgesSize = data->insertedEdges.size();
|
||||
std::vector< _ImportEdge >& insertedEdges = data->insertedEdges;
|
||||
template< bool Simulate, bool topOnePercent >
|
||||
bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) {
|
||||
_Heap& heap = data->heap;
|
||||
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 ) {
|
||||
const _EdgeBasedContractorEdgeData& inData = _graph->GetEdgeData( inEdge );
|
||||
const NodeID source = _graph->GetTarget( inEdge );
|
||||
if ( Simulate ) {
|
||||
assert( stats != NULL );
|
||||
++stats->edgesDeleted;
|
||||
stats->originalEdgesDeleted += inData.originalEdges;
|
||||
}
|
||||
if ( !inData.backward )
|
||||
continue;
|
||||
for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) {
|
||||
const _EdgeBasedContractorEdgeData& inData = _graph->GetEdgeData( inEdge );
|
||||
const NodeID source = _graph->GetTarget( inEdge );
|
||||
if ( Simulate ) {
|
||||
assert( stats != NULL );
|
||||
++stats->edgesDeleted;
|
||||
stats->originalEdgesDeleted += inData.originalEdges;
|
||||
}
|
||||
if ( !inData.backward )
|
||||
continue;
|
||||
|
||||
heap.Clear();
|
||||
heap.Insert( source, 0, _HeapData() );
|
||||
if ( node != source )
|
||||
heap.Insert( node, inData.distance, _HeapData() );
|
||||
int maxDistance = 0;
|
||||
unsigned numTargets = 0;
|
||||
heap.Clear();
|
||||
heap.Insert( source, 0, _HeapData() );
|
||||
if ( node != source )
|
||||
heap.Insert( node, inData.distance, _HeapData() );
|
||||
int maxDistance = 0;
|
||||
unsigned numTargets = 0;
|
||||
|
||||
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
|
||||
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
|
||||
if ( !outData.forward )
|
||||
continue;
|
||||
const NodeID target = _graph->GetTarget( outEdge );
|
||||
const int pathDistance = inData.distance + outData.distance;
|
||||
maxDistance = std::max( maxDistance, pathDistance );
|
||||
if ( !heap.WasInserted( target ) ) {
|
||||
heap.Insert( target, pathDistance, _HeapData( 0, true ) );
|
||||
++numTargets;
|
||||
} else if ( pathDistance < heap.GetKey( target ) ) {
|
||||
heap.DecreaseKey( target, pathDistance );
|
||||
}
|
||||
}
|
||||
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
|
||||
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
|
||||
if ( !outData.forward )
|
||||
continue;
|
||||
const NodeID target = _graph->GetTarget( outEdge );
|
||||
const int pathDistance = inData.distance + outData.distance;
|
||||
maxDistance = std::max( maxDistance, pathDistance );
|
||||
if ( !heap.WasInserted( target ) ) {
|
||||
heap.Insert( target, pathDistance, _HeapData( 0, true ) );
|
||||
++numTargets;
|
||||
} else if ( pathDistance < heap.GetKey( target ) ) {
|
||||
heap.DecreaseKey( target, pathDistance );
|
||||
}
|
||||
}
|
||||
|
||||
if( Simulate )
|
||||
_Dijkstra( maxDistance, numTargets, 1000, 5, data );
|
||||
else
|
||||
_Dijkstra( maxDistance, numTargets, 2000, 7, data );
|
||||
if( Simulate )
|
||||
_Dijkstra( maxDistance, numTargets, 1000, (true ? INT_MAX : 5), data );
|
||||
else
|
||||
_Dijkstra( maxDistance, numTargets, 2000, (true ? INT_MAX : 7), data );
|
||||
|
||||
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
|
||||
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
|
||||
if ( !outData.forward )
|
||||
continue;
|
||||
const NodeID target = _graph->GetTarget( outEdge );
|
||||
const int pathDistance = inData.distance + outData.distance;
|
||||
const int distance = heap.GetKey( target );
|
||||
if ( pathDistance <= distance ) {
|
||||
if ( Simulate ) {
|
||||
assert( stats != NULL );
|
||||
stats->edgesAdded+=2;
|
||||
stats->originalEdgesAdded += 2* ( outData.originalEdges + inData.originalEdges );
|
||||
} else {
|
||||
_ImportEdge newEdge;
|
||||
newEdge.source = source;
|
||||
newEdge.target = target;
|
||||
newEdge.data = _EdgeBasedContractorEdgeData( pathDistance, outData.originalEdges + inData.originalEdges, node, 0, inData.turnInstruction, true, true, false);;
|
||||
insertedEdges.push_back( newEdge );
|
||||
std::swap( newEdge.source, newEdge.target );
|
||||
newEdge.data.forward = false;
|
||||
newEdge.data.backward = true;
|
||||
insertedEdges.push_back( newEdge );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !Simulate ) {
|
||||
for ( int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; ++i ) {
|
||||
bool found = false;
|
||||
for ( int other = i + 1 ; other < iend ; ++other ) {
|
||||
if ( insertedEdges[other].source != insertedEdges[i].source )
|
||||
continue;
|
||||
if ( insertedEdges[other].target != insertedEdges[i].target )
|
||||
continue;
|
||||
if ( insertedEdges[other].data.distance != insertedEdges[i].data.distance )
|
||||
continue;
|
||||
if ( insertedEdges[other].data.shortcut != insertedEdges[i].data.shortcut )
|
||||
continue;
|
||||
insertedEdges[other].data.forward |= insertedEdges[i].data.forward;
|
||||
insertedEdges[other].data.backward |= insertedEdges[i].data.backward;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if ( !found )
|
||||
insertedEdges[insertedEdgesSize++] = insertedEdges[i];
|
||||
}
|
||||
insertedEdges.resize( insertedEdgesSize );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
|
||||
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
|
||||
if ( !outData.forward )
|
||||
continue;
|
||||
const NodeID target = _graph->GetTarget( outEdge );
|
||||
const int pathDistance = inData.distance + outData.distance;
|
||||
const int distance = heap.GetKey( target );
|
||||
if ( pathDistance <= distance ) {
|
||||
if ( Simulate ) {
|
||||
assert( stats != NULL );
|
||||
stats->edgesAdded+=2;
|
||||
stats->originalEdgesAdded += 2* ( outData.originalEdges + inData.originalEdges );
|
||||
} else {
|
||||
_ImportEdge newEdge;
|
||||
newEdge.source = source;
|
||||
newEdge.target = target;
|
||||
newEdge.data = _EdgeBasedContractorEdgeData( pathDistance, outData.originalEdges + inData.originalEdges, node, 0, inData.turnInstruction, true, true, false);;
|
||||
insertedEdges.push_back( newEdge );
|
||||
std::swap( newEdge.source, newEdge.target );
|
||||
newEdge.data.forward = false;
|
||||
newEdge.data.backward = true;
|
||||
insertedEdges.push_back( newEdge );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !Simulate ) {
|
||||
for ( int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; ++i ) {
|
||||
bool found = false;
|
||||
for ( int other = i + 1 ; other < iend ; ++other ) {
|
||||
if ( insertedEdges[other].source != insertedEdges[i].source )
|
||||
continue;
|
||||
if ( insertedEdges[other].target != insertedEdges[i].target )
|
||||
continue;
|
||||
if ( insertedEdges[other].data.distance != insertedEdges[i].data.distance )
|
||||
continue;
|
||||
if ( insertedEdges[other].data.shortcut != insertedEdges[i].data.shortcut )
|
||||
continue;
|
||||
insertedEdges[other].data.forward |= insertedEdges[i].data.forward;
|
||||
insertedEdges[other].data.backward |= insertedEdges[i].data.backward;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if ( !found )
|
||||
insertedEdges[insertedEdgesSize++] = insertedEdges[i];
|
||||
}
|
||||
insertedEdges.resize( insertedEdgesSize );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void _DeleteIncomingEdges( _ThreadData* data, NodeID node ) {
|
||||
std::vector< NodeID >& neighbours = data->neighbours;
|
||||
neighbours.clear();
|
||||
void _DeleteIncomingEdges( _ThreadData* data, NodeID node ) {
|
||||
std::vector< NodeID >& neighbours = data->neighbours;
|
||||
neighbours.clear();
|
||||
|
||||
//find all neighbours
|
||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
|
||||
const NodeID u = _graph->GetTarget( e );
|
||||
if ( u != node )
|
||||
neighbours.push_back( u );
|
||||
}
|
||||
//eliminate duplicate entries ( forward + backward edges )
|
||||
std::sort( neighbours.begin(), neighbours.end() );
|
||||
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
||||
//find all neighbours
|
||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
|
||||
const NodeID u = _graph->GetTarget( e );
|
||||
if ( u != node )
|
||||
neighbours.push_back( u );
|
||||
}
|
||||
//eliminate duplicate entries ( forward + backward edges )
|
||||
std::sort( neighbours.begin(), neighbours.end() );
|
||||
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
||||
|
||||
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
|
||||
// const NodeID u = neighbours[i];
|
||||
_graph->DeleteEdgesTo( neighbours[i], node );
|
||||
}
|
||||
}
|
||||
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
|
||||
// const NodeID u = neighbours[i];
|
||||
_graph->DeleteEdgesTo( neighbours[i], node );
|
||||
}
|
||||
}
|
||||
|
||||
bool _UpdateNeighbours( std::vector< double > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node ) {
|
||||
std::vector< NodeID >& neighbours = data->neighbours;
|
||||
neighbours.clear();
|
||||
bool _UpdateNeighbours( std::vector< double > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node, bool topOnePercent ) {
|
||||
std::vector< NodeID >& neighbours = data->neighbours;
|
||||
neighbours.clear();
|
||||
|
||||
//find all neighbours
|
||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
|
||||
const NodeID u = _graph->GetTarget( e );
|
||||
if ( u == node )
|
||||
continue;
|
||||
neighbours.push_back( u );
|
||||
nodeData[u].depth = (std::max)(nodeData[node].depth + 1, nodeData[u].depth );
|
||||
}
|
||||
//eliminate duplicate entries ( forward + backward edges )
|
||||
std::sort( neighbours.begin(), neighbours.end() );
|
||||
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
||||
//find all neighbours
|
||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
|
||||
const NodeID u = _graph->GetTarget( e );
|
||||
if ( u == node )
|
||||
continue;
|
||||
neighbours.push_back( u );
|
||||
nodeData[u].depth = (std::max)(nodeData[node].depth + 1, nodeData[u].depth );
|
||||
}
|
||||
//eliminate duplicate entries ( forward + backward edges )
|
||||
std::sort( neighbours.begin(), neighbours.end() );
|
||||
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
||||
|
||||
int neighbourSize = ( int ) neighbours.size();
|
||||
for ( int i = 0, e = neighbourSize; i < e; ++i ) {
|
||||
const NodeID u = neighbours[i];
|
||||
priorities[u] = _Evaluate( data, &( nodeData )[u], u );
|
||||
}
|
||||
int neighbourSize = ( int ) neighbours.size();
|
||||
for ( int i = 0, e = neighbourSize; i < e; ++i ) {
|
||||
const NodeID u = neighbours[i];
|
||||
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 ) {
|
||||
const double priority = priorities[node];
|
||||
bool _IsIndependent( const std::vector< double >& priorities, const std::vector< _PriorityData >& nodeData, _ThreadData* const data, NodeID node ) {
|
||||
const double priority = priorities[node];
|
||||
|
||||
std::vector< NodeID >& neighbours = data->neighbours;
|
||||
neighbours.clear();
|
||||
std::vector< NodeID >& neighbours = data->neighbours;
|
||||
neighbours.clear();
|
||||
|
||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
|
||||
const NodeID target = _graph->GetTarget( e );
|
||||
const double targetPriority = priorities[target];
|
||||
assert( targetPriority >= 0 );
|
||||
//found a neighbour with lower priority?
|
||||
if ( priority > targetPriority )
|
||||
return false;
|
||||
//tie breaking
|
||||
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
|
||||
return false;
|
||||
neighbours.push_back( target );
|
||||
}
|
||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
|
||||
const NodeID target = _graph->GetTarget( e );
|
||||
const double targetPriority = priorities[target];
|
||||
assert( targetPriority >= 0 );
|
||||
//found a neighbour with lower priority?
|
||||
if ( priority > targetPriority )
|
||||
return false;
|
||||
//tie breaking
|
||||
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
|
||||
return false;
|
||||
neighbours.push_back( target );
|
||||
}
|
||||
|
||||
std::sort( neighbours.begin(), neighbours.end() );
|
||||
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
||||
std::sort( neighbours.begin(), neighbours.end() );
|
||||
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
||||
|
||||
//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 ) {
|
||||
const NodeID u = *i;
|
||||
//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 ) {
|
||||
const NodeID u = *i;
|
||||
|
||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( u ) ; e < _graph->EndEdges( u ) ; ++e ) {
|
||||
const NodeID target = _graph->GetTarget( e );
|
||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( u ) ; e < _graph->EndEdges( u ) ; ++e ) {
|
||||
const NodeID target = _graph->GetTarget( e );
|
||||
|
||||
const double targetPriority = priorities[target];
|
||||
assert( targetPriority >= 0 );
|
||||
//found a neighbour with lower priority?
|
||||
if ( priority > targetPriority )
|
||||
return false;
|
||||
//tie breaking
|
||||
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const double targetPriority = priorities[target];
|
||||
assert( targetPriority >= 0 );
|
||||
//found a neighbour with lower priority?
|
||||
if ( priority > targetPriority )
|
||||
return false;
|
||||
//tie breaking
|
||||
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::shared_ptr<_DynamicGraph> _graph;
|
||||
double edgeQuotionFactor;
|
||||
double originalQuotientFactor;
|
||||
double depthFactor;
|
||||
boost::shared_ptr<_DynamicGraph> _graph;
|
||||
double edgeQuotionFactor;
|
||||
double originalQuotientFactor;
|
||||
double depthFactor;
|
||||
};
|
||||
|
||||
#endif // CONTRACTOR_H_INCLUDED
|
||||
|
@ -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( (data1.nameID == data2.nameID) && (0 != data1.nameID))
|
||||
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;
|
||||
|
||||
double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
|
||||
|
@ -151,19 +151,19 @@ public:
|
||||
//run two-Target Dijkstra routing step.
|
||||
while(_forwardHeap->Size() + _backwardHeap->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){
|
||||
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle1, &_localUpperbound1, 2*offset);
|
||||
_RoutingStep<false>(_backwardHeap, _forwardHeap, &middle1, &_localUpperbound1, 2*offset);
|
||||
}
|
||||
}
|
||||
if(_backwardHeap2->Size() > 0) {
|
||||
while(_forwardHeap2->Size() + _backwardHeap2->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){
|
||||
_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) ;
|
||||
offset += (phantomNodes.targetPhantom.isBidirected() ? std::max(phantomNodes.targetPhantom.weight1, phantomNodes.targetPhantom.weight2) : phantomNodes.targetPhantom.weight1) ;
|
||||
|
||||
while(_forwardHeap->Size() + _backwardHeap->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){
|
||||
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound, 2*offset);
|
||||
_RoutingStep<false>(_backwardHeap, _forwardHeap, &middle, &_upperbound, 2*offset);
|
||||
}
|
||||
}
|
||||
|
||||
// INFO("dist: " << _upperbound);
|
||||
if ( _upperbound == INT_MAX ) {
|
||||
return _upperbound;
|
||||
@ -341,7 +339,6 @@ public:
|
||||
std::deque<NodeID> packedPath;
|
||||
_RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middle, packedPath);
|
||||
|
||||
|
||||
//Setting weights to correspond with that of the actual chosen path
|
||||
if(packedPath[0] == phantomNodes.startPhantom.edgeBasedNode && phantomNodes.startPhantom.isBidirected()) {
|
||||
// INFO("Setting weight1=" << phantomNodes.startPhantom.weight1 << " to that of weight2=" << phantomNodes.startPhantom.weight2);
|
||||
@ -414,8 +411,8 @@ private:
|
||||
// std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, int *_upperbound, const int edgeBasedOffset) const {
|
||||
template<bool forwardDirection>
|
||||
inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset) const {
|
||||
const NodeID node = _forwardHeap->DeleteMin();
|
||||
const int distance = _forwardHeap->GetKey(node);
|
||||
// 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 {
|
||||
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.
|
||||
for(unsigned i = sizeOfPackedPath-1; i > 0; --i){
|
||||
|
@ -66,12 +66,11 @@ public:
|
||||
"\"status_message\": \"Cannot find route between points\",";
|
||||
}
|
||||
|
||||
descriptionFactory.Run(config.z, durationOfTrip);
|
||||
|
||||
descriptionFactory.Run(config.z, durationOfTrip);
|
||||
reply.content += "\"route_summary\": {"
|
||||
"\"total_distance\":";
|
||||
reply.content += descriptionFactory.summary.lengthString;
|
||||
reply.content += ","
|
||||
reply.content += ","
|
||||
"\"total_time\":";
|
||||
reply.content += descriptionFactory.summary.durationString;
|
||||
reply.content += ","
|
||||
@ -107,9 +106,9 @@ public:
|
||||
roundAbout.nameID = segment.nameID;
|
||||
roundAbout.startIndex = prefixSumOfNecessarySegments;
|
||||
} else {
|
||||
if(0 != prefixSumOfNecessarySegments)
|
||||
if(0 != prefixSumOfNecessarySegments){
|
||||
reply.content += ",";
|
||||
|
||||
}
|
||||
reply.content += "[\"";
|
||||
if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) {
|
||||
reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout];
|
||||
|
@ -29,7 +29,7 @@
|
||||
//======================
|
||||
// OBJECTS
|
||||
//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_WEBSITE = 'http://map.project-osrm.org/';//location.host
|
||||
|
||||
|
@ -26,7 +26,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "ObjectForPluginStruct.h"
|
||||
#include "BasePlugin.h"
|
||||
#include "RouteParameters.h"
|
||||
|
||||
#include "../Util/StringUtil.h"
|
||||
#include "../DataStructures/NodeInformationHelpDesk.h"
|
||||
|
||||
/*
|
||||
@ -57,33 +57,47 @@ public:
|
||||
_Coordinate 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
|
||||
reply.status = http::Reply::ok;
|
||||
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>");
|
||||
|
||||
std::stringstream out1;
|
||||
out1 << setprecision(10);
|
||||
out1 << "<name>Nearest Place in map to " << lat/100000. << "," << lon/100000. << "</name>";
|
||||
reply.content.append(out1.str());
|
||||
reply.content.append("<Point>");
|
||||
|
||||
std::stringstream out2;
|
||||
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\"";
|
||||
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 Locate (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;
|
||||
return;
|
||||
}
|
||||
private:
|
||||
|
@ -62,82 +62,47 @@ public:
|
||||
//query to helpdesk
|
||||
_Coordinate 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 JSONParameter;
|
||||
switch(descriptorType){
|
||||
case 1:
|
||||
//json
|
||||
//json
|
||||
|
||||
JSONParameter = routeParameters.options.Find("jsonp");
|
||||
if("" != JSONParameter) {
|
||||
reply.content += JSONParameter;
|
||||
reply.content += "(\n";
|
||||
}
|
||||
|
||||
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;
|
||||
JSONParameter = routeParameters.options.Find("jsonp");
|
||||
if("" != JSONParameter) {
|
||||
reply.content += JSONParameter;
|
||||
reply.content += "(";
|
||||
}
|
||||
|
||||
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:
|
||||
NodeInformationHelpDesk * nodeHelpDesk;
|
||||
|
@ -119,14 +119,12 @@ public:
|
||||
}
|
||||
rawRoute.rawViaNodeCoordinates.push_back(targetCoord);
|
||||
vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size());
|
||||
|
||||
for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) {
|
||||
searchEngine->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i]);
|
||||
}
|
||||
|
||||
unsigned distance = 0;
|
||||
//single route or via point routing
|
||||
if(0 == routeParameters.viaPoints.size()) {
|
||||
if(2 == rawRoute.rawViaNodeCoordinates.size()) {
|
||||
PhantomNodes segmentPhantomNodes;
|
||||
segmentPhantomNodes.startPhantom = phantomNodeVector[0];
|
||||
segmentPhantomNodes.targetPhantom = phantomNodeVector[1];
|
||||
@ -145,7 +143,6 @@ public:
|
||||
if(INT_MAX == distance ) {
|
||||
DEBUG( "Error occurred, single path not found" );
|
||||
}
|
||||
|
||||
reply.status = http::Reply::ok;
|
||||
|
||||
BaseDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > > * desc;
|
||||
@ -197,7 +194,6 @@ public:
|
||||
desc->SetConfig(descriptorConfig);
|
||||
|
||||
desc->Run(reply, rawRoute, phantomNodes, *searchEngine, distance);
|
||||
|
||||
if("" != JSONParameter) {
|
||||
reply.content += ")\n";
|
||||
}
|
||||
|
@ -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.Append(CCFLAGS = ['-lboost_regex', '-lboost_iostreams', '-lbz2', '-lz', '-lprotobuf'])
|
||||
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()
|
||||
|
||||
|
@ -52,10 +52,11 @@ enum CompressionType {
|
||||
|
||||
struct Request {
|
||||
std::string uri;
|
||||
boost::asio::ip::address endpoint;
|
||||
};
|
||||
|
||||
struct Reply {
|
||||
Reply() : status(ok) { content.reserve(1000000); }
|
||||
Reply() : status(ok) { content.reserve(2 << 20); }
|
||||
enum status_type {
|
||||
ok = 200,
|
||||
badRequest = 400,
|
||||
@ -63,9 +64,9 @@ struct Reply {
|
||||
} status;
|
||||
|
||||
std::vector<Header> headers;
|
||||
std::string content;
|
||||
std::vector<boost::asio::const_buffer> toBuffers();
|
||||
std::vector<boost::asio::const_buffer> HeaderstoBuffers();
|
||||
std::string content;
|
||||
static Reply stockReply(status_type status);
|
||||
void setSize(unsigned size) {
|
||||
for (std::size_t i = 0; i < headers.size(); ++i) {
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
|
||||
/// Start the first asynchronous operation for the connection.
|
||||
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:
|
||||
@ -68,7 +68,7 @@ private:
|
||||
// std::cout << "[debug] using deflate" << std::endl;
|
||||
// if(compressionType == noCompression)
|
||||
// std::cout << "[debug] no compression" << std::endl;
|
||||
|
||||
request.endpoint = TCPsocket.remote_endpoint().address();
|
||||
requestHandler.handle_request(request, reply);
|
||||
|
||||
Header compressionHeader;
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
void handle_request(const Request& req, Reply& rep){
|
||||
//parse command
|
||||
std::string request(req.uri);
|
||||
// INFO( "[r] " << request );
|
||||
INFO( req.endpoint.to_string() << " " << request );
|
||||
std::string command;
|
||||
std::size_t firstAmpPosition = request.find_first_of("?");
|
||||
command = request.substr(1,firstAmpPosition-1);
|
||||
|
10
server.ini
10
server.ini
@ -2,8 +2,8 @@ Threads = 8
|
||||
IP = 0.0.0.0
|
||||
Port = 5000
|
||||
|
||||
hsgrData=/opt/osm/germany.osrm.hsgr
|
||||
nodesData=/opt/osm/germany.osrm.nodes
|
||||
ramIndex=/opt/osm/germany.osrm.ramIndex
|
||||
fileIndex=/opt/osm/germany.osrm.fileIndex
|
||||
namesData=/opt/osm/germany.osrm.names
|
||||
hsgrData=/opt/osm/berlin.osrm.hsgr
|
||||
nodesData=/opt/osm/berlin.osrm.nodes
|
||||
ramIndex=/opt/osm/berlin.osrm.ramIndex
|
||||
fileIndex=/opt/osm/berlin.osrm.fileIndex
|
||||
namesData=/opt/osm/berlin.osrm.names
|
||||
|
@ -45,4 +45,4 @@
|
||||
defaultSpeed = 5
|
||||
trafficLightPenalty = 15
|
||||
obeyBollards = no
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user