Merge branch 'develop'

This commit is contained in:
Dennis Luxen 2013-08-15 15:54:31 +02:00
commit 9e46577f43
93 changed files with 2003 additions and 1500 deletions

View File

@ -10,7 +10,7 @@ before_script:
- bundle install - bundle install
- mkdir build - mkdir build
- cd build - cd build
- cmake .. - cmake .. $CMAKEOPTIONS
script: make script: make
after_script: after_script:
- cd .. - cd ..
@ -20,8 +20,8 @@ branches:
- master - master
- develop - develop
env: env:
- OPTIONS="-DCMAKE_BUILD_TYPE=Release" - CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release"
- OPTIONS="-DCMAKE_BUILD_TYPE=Debug" - CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug"
notifications: notifications:
irc: irc:
channels: channels:

View File

@ -62,10 +62,10 @@ CRC32::CRC32CFunctionPtr CRC32::detectBestCRC32C() {
unsigned ecx = cpuid(1); unsigned ecx = cpuid(1);
bool hasSSE42 = ecx & (1 << SSE42_BIT); bool hasSSE42 = ecx & (1 << SSE42_BIT);
if (hasSSE42) { if (hasSSE42) {
std::cout << "using hardware base sse computation" << std::endl; SimpleLogger().Write() << "using hardware base sse computation";
return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated; return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else { } else {
std::cout << "using software base sse computation" << std::endl; SimpleLogger().Write() << "using software base sse computation";
return &CRC32::SoftwareBasedCRC32; //crc32cSlicingBy8; return &CRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
} }
} }

View File

@ -21,6 +21,8 @@
#ifndef CRC32_H_ #ifndef CRC32_H_
#define CRC32_H_ #define CRC32_H_
#include "../Util/SimpleLogger.h"
#include <boost/crc.hpp> // for boost::crc_32_type #include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream> #include <iostream>

View File

@ -22,6 +22,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef ITERATORBASEDCRC32_H_ #ifndef ITERATORBASEDCRC32_H_
#define ITERATORBASEDCRC32_H_ #define ITERATORBASEDCRC32_H_
#include "../Util/SimpleLogger.h"
#include <boost/crc.hpp> // for boost::crc_32_type #include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream> #include <iostream>
@ -80,10 +82,10 @@ private:
unsigned ecx = cpuid(1); unsigned ecx = cpuid(1);
bool hasSSE42 = ecx & (1 << SSE42_BIT); bool hasSSE42 = ecx & (1 << SSE42_BIT);
if (hasSSE42) { if (hasSSE42) {
std::cout << "using hardware base sse computation" << std::endl; SimpleLogger().Write() << "using hardware based CRC32 computation";
return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated; return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else { } else {
std::cout << "using software base sse computation" << std::endl; SimpleLogger().Write() << "using software based CRC32 computation";
return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8; return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
} }
} }
@ -93,7 +95,7 @@ public:
crcFunction = detectBestCRC32C(); crcFunction = detectBestCRC32C();
} }
virtual ~IteratorbasedCRC32() {}; virtual ~IteratorbasedCRC32() { }
unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) { unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) {
unsigned crc = 0; unsigned crc = 0;

View File

@ -56,11 +56,14 @@ private:
} }
public: public:
inline void printEncodedString(const std::vector<SegmentInformation>& polyline, std::string &output) const { inline void printEncodedString(
const std::vector<SegmentInformation> & polyline,
std::string & output
) const {
std::vector<int> deltaNumbers; std::vector<int> deltaNumbers;
output += "\""; output += "\"";
if(!polyline.empty()) { if(!polyline.empty()) {
_Coordinate lastCoordinate = polyline[0].location; FixedPointCoordinate lastCoordinate = polyline[0].location;
deltaNumbers.push_back( lastCoordinate.lat ); deltaNumbers.push_back( lastCoordinate.lat );
deltaNumbers.push_back( lastCoordinate.lon ); deltaNumbers.push_back( lastCoordinate.lon );
for(unsigned i = 1; i < polyline.size(); ++i) { for(unsigned i = 1; i < polyline.size(); ++i) {
@ -76,7 +79,7 @@ public:
} }
inline void printEncodedString(const std::vector<_Coordinate>& polyline, std::string &output) const { inline void printEncodedString(const std::vector<FixedPointCoordinate>& polyline, std::string &output) const {
std::vector<int> deltaNumbers(2*polyline.size()); std::vector<int> deltaNumbers(2*polyline.size());
output += "\""; output += "\"";
if(!polyline.empty()) { if(!polyline.empty()) {
@ -91,7 +94,7 @@ public:
output += "\""; output += "\"";
} }
inline void printUnencodedString(std::vector<_Coordinate> & polyline, std::string & output) const { inline void printUnencodedString(std::vector<FixedPointCoordinate> & polyline, std::string & output) const {
output += "["; output += "[";
std::string tmp; std::string tmp;
for(unsigned i = 0; i < polyline.size(); i++) { for(unsigned i = 0; i < polyline.size(); i++) {

View File

@ -28,11 +28,13 @@ Strongly connected components using Tarjan's Algorithm
#include "../DataStructures/DeallocatingVector.h" #include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h" #include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
#include "../DataStructures/NodeCoords.h" #include "../DataStructures/QueryNode.h"
#include "../DataStructures/Percent.h" #include "../DataStructures/Percent.h"
#include "../DataStructures/Restriction.h" #include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/SimpleLogger.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/integer.hpp> #include <boost/integer.hpp>
@ -116,9 +118,21 @@ private:
DeallocatingVector<EdgeBasedNode> edgeBasedNodes; DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
public: public:
TarjanSCC(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) { TarjanSCC(
BOOST_FOREACH(_Restriction & restriction, irs) { int nodes,
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); std::vector<NodeBasedEdge> & inputEdges,
std::vector<NodeID> & bn,
std::vector<NodeID> & tl,
std::vector<TurnRestriction> & irs,
std::vector<NodeInfo> & nI
) :
inputNodeInfoList(nI),
numberOfTurnRestrictions(irs.size())
{
BOOST_FOREACH(const TurnRestriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(
restriction.fromNode, restriction.viaNode
);
unsigned index; unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource);
if(restrIter == _restrictionMap.end()) { if(restrIter == _restrictionMap.end()) {
@ -136,7 +150,9 @@ public:
} }
} }
_restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly)); _restrictionBucketVector.at(index).push_back(
std::make_pair(restriction.toNode, restriction.flags.isOnly)
);
} }
BOOST_FOREACH(NodeID id, bn) { BOOST_FOREACH(NodeID id, bn) {
@ -243,7 +259,7 @@ public:
bool beforeRecursion = recursionStack.top().first; bool beforeRecursion = recursionStack.top().first;
TarjanStackFrame currentFrame = recursionStack.top().second; TarjanStackFrame currentFrame = recursionStack.top().second;
NodeID v = currentFrame.v; NodeID v = currentFrame.v;
// INFO("popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion"); // SimpleLogger().Write() << "popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion";
recursionStack.pop(); recursionStack.pop();
if(beforeRecursion) { if(beforeRecursion) {
@ -256,45 +272,45 @@ public:
tarjanStack.push(v); tarjanStack.push(v);
tarjanNodes[v].onStack = true; tarjanNodes[v].onStack = true;
++index; ++index;
// INFO("pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink); // SimpleLogger().Write() << "pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink;
//Traverse outgoing edges //Traverse outgoing edges
for(TarjanDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { for(TarjanDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
TarjanDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2); TarjanDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2);
// INFO("traversing edge (" << v << "," << vprime << ")"); // SimpleLogger().Write() << "traversing edge (" << v << "," << vprime << ")";
if(UINT_MAX == tarjanNodes[vprime].index) { if(UINT_MAX == tarjanNodes[vprime].index) {
recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v))); recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v)));
} else { } else {
// INFO("Node " << vprime << " is already explored"); // SimpleLogger().Write() << "Node " << vprime << " is already explored";
if(tarjanNodes[vprime].onStack) { if(tarjanNodes[vprime].onStack) {
unsigned newLowlink = std::min(tarjanNodes[v].lowlink, tarjanNodes[vprime].index); unsigned newLowlink = std::min(tarjanNodes[v].lowlink, tarjanNodes[vprime].index);
// INFO("Setting lowlink[" << v << "] from " << tarjanNodes[v].lowlink << " to " << newLowlink); // SimpleLogger().Write() << "Setting lowlink[" << v << "] from " << tarjanNodes[v].lowlink << " to " << newLowlink;
tarjanNodes[v].lowlink = newLowlink; tarjanNodes[v].lowlink = newLowlink;
// } else { // } else {
// INFO("But node " << vprime << " is not on stack"); // SimpleLogger().Write() << "But node " << vprime << " is not on stack";
} }
} }
} }
} else { } else {
// INFO("we are at the end of recursion and checking node " << v); // SimpleLogger().Write() << "we are at the end of recursion and checking node " << v;
{ // setting lowlink in its own scope so it does not pollute namespace { // setting lowlink in its own scope so it does not pollute namespace
// NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent ); // NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent );
// INFO("parent=" << currentFrame.parent); // SimpleLogger().Write() << "parent=" << currentFrame.parent;
// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink); // SimpleLogger().Write() << "tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink;
//Note the index shift by 1 compared to the recursive version //Note the index shift by 1 compared to the recursive version
tarjanNodes[currentFrame.parent].lowlink = std::min(tarjanNodes[currentFrame.parent].lowlink, tarjanNodes[v].lowlink); tarjanNodes[currentFrame.parent].lowlink = std::min(tarjanNodes[currentFrame.parent].lowlink, tarjanNodes[v].lowlink);
// INFO("Setting tarjanNodes[" << currentFrame.parent <<"].lowlink=" << tarjanNodes[currentFrame.parent].lowlink); // SimpleLogger().Write() << "Setting tarjanNodes[" << currentFrame.parent <<"].lowlink=" << tarjanNodes[currentFrame.parent].lowlink;
} }
// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << v << "].index=" << tarjanNodes[v].index); // SimpleLogger().Write() << "tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << v << "].index=" << tarjanNodes[v].index;
//after recursion, lets do cycle checking //after recursion, lets do cycle checking
//Check if we found a cycle. This is the bottom part of the recursion //Check if we found a cycle. This is the bottom part of the recursion
if(tarjanNodes[v].lowlink == tarjanNodes[v].index) { if(tarjanNodes[v].lowlink == tarjanNodes[v].index) {
NodeID vprime; NodeID vprime;
do { do {
// INFO("identified component " << currentComponent << ": " << tarjanStack.top()); // SimpleLogger().Write() << "identified component " << currentComponent << ": " << tarjanStack.top();
vprime = tarjanStack.top(); tarjanStack.pop(); vprime = tarjanStack.top(); tarjanStack.pop();
tarjanNodes[vprime].onStack = false; tarjanNodes[vprime].onStack = false;
componentsIndex[vprime] = currentComponent; componentsIndex[vprime] = currentComponent;
@ -302,7 +318,7 @@ public:
} while( v != vprime); } while( v != vprime);
vectorOfComponentSizes.push_back(sizeOfCurrentComponent); vectorOfComponentSizes.push_back(sizeOfCurrentComponent);
if(sizeOfCurrentComponent > 1000) if(sizeOfCurrentComponent > 1000)
INFO("large component [" << currentComponent << "]=" << sizeOfCurrentComponent); SimpleLogger().Write() << "large component [" << currentComponent << "]=" << sizeOfCurrentComponent;
++currentComponent; ++currentComponent;
sizeOfCurrentComponent = 0; sizeOfCurrentComponent = 0;
} }
@ -310,14 +326,14 @@ public:
} }
} }
INFO("identified: " << vectorOfComponentSizes.size() << " many components, marking small components"); SimpleLogger().Write() << "identified: " << vectorOfComponentSizes.size() << " many components, marking small components";
int singleCounter = 0; int singleCounter = 0;
for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){ for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){
if(1 == vectorOfComponentSizes[i]) if(1 == vectorOfComponentSizes[i])
++singleCounter; ++singleCounter;
} }
INFO("identified " << singleCounter << " SCCs of size 1"); SimpleLogger().Write() << "identified " << singleCounter << " SCCs of size 1";
uint64_t total_network_distance = 0; uint64_t total_network_distance = 0;
p.reinit(_nodeBasedGraph->GetNumberOfNodes()); p.reinit(_nodeBasedGraph->GetNumberOfNodes());
for(TarjanDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { for(TarjanDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
@ -343,16 +359,17 @@ public:
//edges that end on bollard nodes may actually be in two distinct components //edges that end on bollard nodes may actually be in two distinct components
if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) { if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) {
//INFO("(" << inputNodeInfoList[u].lat/100000. << ";" << inputNodeInfoList[u].lon/100000. << ") -> (" << inputNodeInfoList[v].lat/100000. << ";" << inputNodeInfoList[v].lon/100000. << ")"); //INFO("(" << inputNodeInfoList[u].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[u].lon/COORDINATE_PRECISION << ") -> (" << inputNodeInfoList[v].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[v].lon/COORDINATE_PRECISION << ")");
OGRLineString lineString; OGRLineString lineString;
lineString.addPoint(inputNodeInfoList[u].lon/100000., inputNodeInfoList[u].lat/100000.); lineString.addPoint(inputNodeInfoList[u].lon/COORDINATE_PRECISION, inputNodeInfoList[u].lat/COORDINATE_PRECISION);
lineString.addPoint(inputNodeInfoList[v].lon/100000., inputNodeInfoList[v].lat/100000.); lineString.addPoint(inputNodeInfoList[v].lon/COORDINATE_PRECISION, inputNodeInfoList[v].lat/COORDINATE_PRECISION);
OGRFeature *poFeature; OGRFeature *poFeature;
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() ); poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
poFeature->SetGeometry( &lineString ); poFeature->SetGeometry( &lineString );
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) {
{ throw OSRMException(
ERR( "Failed to create feature in shapefile.\n" ); "Failed to create feature in shapefile."
);
} }
OGRFeature::DestroyFeature( poFeature ); OGRFeature::DestroyFeature( poFeature );
} }
@ -362,7 +379,7 @@ public:
OGRDataSource::DestroyDataSource( poDS ); OGRDataSource::DestroyDataSource( poDS );
std::vector<NodeID>().swap(vectorOfComponentSizes); std::vector<NodeID>().swap(vectorOfComponentSizes);
std::vector<NodeID>().swap(componentsIndex); std::vector<NodeID>().swap(componentsIndex);
INFO("total network distance: " << total_network_distance/100/1000. << " km"); SimpleLogger().Write() << "total network distance: " << (uint64_t)total_network_distance/100/1000. << " km";
} }
private: private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const { unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const {

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(OSRM) project(OSRM)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)

View File

@ -1,261 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef CONTRACTIONCLEANUP_H_INCLUDED
#define CONTRACTIONCLEANUP_H_INCLUDED
#include <algorithm>
#ifndef _WIN32
#include <sys/time.h>
#endif
#include "Contractor.h"
class ContractionCleanup {
private:
struct _CleanupHeapData {
NodeID parent;
_CleanupHeapData( NodeID p ) {
parent = p;
}
};
typedef BinaryHeap< NodeID, NodeID, int, _CleanupHeapData > _Heap;
struct _ThreadData {
_Heap* _heapForward;
_Heap* _heapBackward;
_ThreadData( NodeID nodes ) {
_heapBackward = new _Heap(nodes);
_heapForward = new _Heap(nodes);
}
~_ThreadData() {
delete _heapBackward;
delete _heapForward;
}
};
public:
struct Edge {
NodeID source;
NodeID target;
struct EdgeData {
NodeID via;
unsigned nameID;
int distance;
TurnInstruction turnInstruction;
bool shortcut:1;
bool forward:1;
bool backward:1;
} data;
bool operator<( const Edge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
//sorts by source and other attributes
static bool CompareBySource( const Edge& left, const Edge& right ) {
if ( left.source != right.source )
return left.source < right.source;
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 );
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
}
bool operator== ( const Edge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward
&& data.via == right.data.via && data.nameID == right.data.nameID
);
}
};
ContractionCleanup( int numNodes, const std::vector< Edge >& edges ) {
_graph = edges;
_numNodes = numNodes;
}
~ContractionCleanup() {
}
void Run() {
RemoveUselessShortcuts();
}
template< class EdgeT >
void GetData( std::vector< EdgeT >& edges ) {
for ( int edge = 0, endEdges = ( int ) _graph.size(); edge != endEdges; ++edge ) {
if(_graph[edge].data.forward || _graph[edge].data.backward) {
EdgeT newEdge;
newEdge.source = _graph[edge].source;
newEdge.target = _graph[edge].target;
newEdge.data = _graph[edge].data;
edges.push_back( newEdge );
}
}
sort( edges.begin(), edges.end() );
}
private:
double _Timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
void BuildOutgoingGraph() {
//sort edges by source
sort( _graph.begin(), _graph.end(), Edge::CompareBySource );
try {
_firstEdge.resize( _numNodes + 1 );
} catch(...) {
ERR("Not enough RAM on machine");
return;
}
_firstEdge[0] = 0;
for ( NodeID i = 0, node = 0; i < ( NodeID ) _graph.size(); i++ ) {
while ( _graph[i].source != node )
_firstEdge[++node] = i;
if ( i == ( NodeID ) _graph.size() - 1 )
while ( node < _numNodes )
_firstEdge[++node] = ( int ) _graph.size();
}
}
void RemoveUselessShortcuts() {
int maxThreads = omp_get_max_threads();
std::vector < _ThreadData* > threadData;
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
threadData.push_back( new _ThreadData( _numNodes ) );
}
INFO("Scanning for useless shortcuts");
BuildOutgoingGraph();
/*
#pragma omp parallel for
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
//only remove shortcuts
if ( !_graph[i].data.shortcut )
continue;
if ( _graph[i].data.forward ) {
int result = _ComputeDistance( _graph[i].source, _graph[i].target, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.forward = false;
}
}
if ( _graph[i].data.backward ) {
int result = _ComputeDistance( _graph[i].target, _graph[i].source, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.backward = false;
}
}
}
*/
INFO("Removing edges");
int useful = 0;
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
if ( !_graph[i].data.forward && !_graph[i].data.backward && _graph[i].data.shortcut ) {
continue;
}
_graph[useful] = _graph[i];
useful++;
}
INFO("Removed " << _graph.size() - useful << " useless shortcuts");
_graph.resize( useful );
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
delete threadData[threadNum];
}
}
void _ComputeStep( _Heap* heapForward, _Heap* heapBackward, bool forwardDirection, NodeID* middle, int* targetDistance ) {
const NodeID node = heapForward->DeleteMin();
const int distance = heapForward->GetKey( node );
if ( distance > *targetDistance ) {
heapForward->DeleteAll();
return;
}
if ( heapBackward->WasInserted( node ) ) {
const int newDistance = heapBackward->GetKey( node ) + distance;
if ( newDistance < *targetDistance ) {
*middle = node;
*targetDistance = newDistance;
}
}
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
const NodeID to = _graph[edge].target;
const int edgeWeight = _graph[edge].data.distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
if ( (forwardDirection ? _graph[edge].data.forward : _graph[edge].data.backward ) ) {
//New Node discovered -> Add to Heap + Node Info Storage
if ( !heapForward->WasInserted( to ) )
heapForward->Insert( to, toDistance, node );
//Found a shorter Path -> Update distance
else if ( toDistance < heapForward->GetKey( to ) ) {
heapForward->DecreaseKey( to, toDistance );
//new parent
heapForward->GetData( to ) = node;
}
}
}
}
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data ) {
data->_heapForward->Clear();
data->_heapBackward->Clear();
//insert source into heap
data->_heapForward->Insert( source, 0, source );
data->_heapBackward->Insert( target, 0, target );
int targetDistance = std::numeric_limits< int >::max();
NodeID middle = std::numeric_limits<NodeID>::max();
while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) {
if ( data->_heapForward->Size() > 0 ) {
_ComputeStep( data->_heapForward, data->_heapBackward, true, &middle, &targetDistance );
}
if ( data->_heapBackward->Size() > 0 ) {
_ComputeStep( data->_heapBackward, data->_heapForward, false, &middle, &targetDistance );
}
}
return targetDistance;
}
NodeID _numNodes;
std::vector< Edge > _graph;
std::vector< unsigned > _firstEdge;
};
#endif // CONTRACTIONCLEANUP_H_INCLUDED

View File

@ -29,6 +29,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/XORFastHash.h" #include "../DataStructures/XORFastHash.h"
#include "../DataStructures/XORFastHashStorage.h" #include "../DataStructures/XORFastHashStorage.h"
#include "../Util/OpenMPWrapper.h" #include "../Util/OpenMPWrapper.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -124,7 +125,8 @@ public:
BOOST_ASSERT_MSG( newEdge.data.distance > 0, "edge distance < 1" ); BOOST_ASSERT_MSG( newEdge.data.distance > 0, "edge distance < 1" );
#ifndef NDEBUG #ifndef NDEBUG
if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) { if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) {
WARN("Edge weight large -> " << newEdge.data.distance); SimpleLogger().Write(logWARNING) <<
"Edge weight large -> " << newEdge.data.distance;
} }
#endif #endif
edges.push_back( newEdge ); edges.push_back( newEdge );
@ -198,9 +200,9 @@ public:
// } // }
// } // }
// //
// INFO("edges at node with id " << highestNode << " has degree " << maxdegree); // SimpleLogger().Write() << "edges at node with id " << highestNode << " has degree " << maxdegree;
// for(unsigned i = _graph->BeginEdges(highestNode); i < _graph->EndEdges(highestNode); ++i) { // for(unsigned i = _graph->BeginEdges(highestNode); i < _graph->EndEdges(highestNode); ++i) {
// INFO(" ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via); // SimpleLogger().Write() << " ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via;
// } // }
//Create temporary file //Create temporary file
@ -430,19 +432,20 @@ public:
// avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() ); // avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
// quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() ); // quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
// //
// INFO("rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree); // SimpleLogger().Write() << "rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree;
p.printStatus(numberOfContractedNodes); p.printStatus(numberOfContractedNodes);
} }
BOOST_FOREACH(_ThreadData * data, threadData) BOOST_FOREACH(_ThreadData * data, threadData) {
delete data; delete data;
}
threadData.clear(); threadData.clear();
} }
template< class Edge > template< class Edge >
inline void GetEdges( DeallocatingVector< Edge >& edges ) { inline void GetEdges( DeallocatingVector< Edge >& edges ) {
Percent p (_graph->GetNumberOfNodes()); Percent p (_graph->GetNumberOfNodes());
INFO("Getting edges of minimized graph"); SimpleLogger().Write() << "Getting edges of minimized graph";
NodeID numberOfNodes = _graph->GetNumberOfNodes(); NodeID numberOfNodes = _graph->GetNumberOfNodes();
if(_graph->GetNumberOfNodes()) { if(_graph->GetNumberOfNodes()) {
for ( NodeID node = 0; node < numberOfNodes; ++node ) { for ( NodeID node = 0; node < numberOfNodes; ++node ) {

View File

@ -20,188 +20,262 @@
#include "EdgeBasedGraphFactory.h" #include "EdgeBasedGraphFactory.h"
template<> EdgeBasedGraphFactory::EdgeBasedGraphFactory(
EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI, SpeedProfileProperties sp) : speedProfile(sp), inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) { int number_of_nodes,
BOOST_FOREACH(const _Restriction & restriction, irs) { std::vector<ImportEdge> & input_edge_list,
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speed_profile
) : speed_profile(speed_profile),
m_turn_restrictions_count(0),
m_node_info_list(m_node_info_list)
{
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
std::pair<NodeID, NodeID> restriction_source =
std::make_pair(restriction.fromNode, restriction.viaNode);
unsigned index; unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::iterator restriction_iter = m_restriction_map.find(restriction_source);
if(restrIter == _restrictionMap.end()) { if(restriction_iter == m_restriction_map.end()) {
index = _restrictionBucketVector.size(); index = m_restriction_bucket_list.size();
_restrictionBucketVector.resize(index+1); m_restriction_bucket_list.resize(index+1);
_restrictionMap[restrictionSource] = index; m_restriction_map[restriction_source] = index;
} else { } else {
index = restrIter->second; index = restriction_iter->second;
//Map already contains an is_only_*-restriction //Map already contains an is_only_*-restriction
if(_restrictionBucketVector.at(index).begin()->second) if(m_restriction_bucket_list.at(index).begin()->second) {
continue; continue;
else if(restriction.flags.isOnly){ } else if(restriction.flags.isOnly) {
//We are going to insert an is_only_*-restriction. There can be only one. //We are going to insert an is_only_*-restriction. There can be only one.
_restrictionBucketVector.at(index).clear(); m_turn_restrictions_count -= m_restriction_bucket_list.at(index).size();
m_restriction_bucket_list.at(index).clear();
} }
} }
++m_turn_restrictions_count;
_restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly)); m_restriction_bucket_list.at(index).push_back(
std::make_pair( restriction.toNode, restriction.flags.isOnly)
);
} }
_barrierNodes.insert(bn.begin(), bn.end()); m_barrier_nodes.insert(
_trafficLights.insert(tl.begin(), tl.end()); barrier_node_list.begin(),
barrier_node_list.end()
);
DeallocatingVector< _NodeBasedEdge > edges; m_traffic_lights.insert(
_NodeBasedEdge edge; traffic_light_node_list.begin(),
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) { traffic_light_node_list.end()
if(!i->isForward()) { );
edge.source = i->target();
edge.target = i->source(); DeallocatingVector< NodeBasedEdge > edges_list;
edge.data.backward = i->isForward(); NodeBasedEdge edge;
edge.data.forward = i->isBackward(); BOOST_FOREACH(const ImportEdge & import_edge, input_edge_list) {
if(!import_edge.isForward()) {
edge.source = import_edge.target();
edge.target = import_edge.source();
edge.data.backward = import_edge.isForward();
edge.data.forward = import_edge.isBackward();
} else { } else {
edge.source = i->source(); edge.source = import_edge.source();
edge.target = i->target(); edge.target = import_edge.target();
edge.data.forward = i->isForward(); edge.data.forward = import_edge.isForward();
edge.data.backward = i->isBackward(); edge.data.backward = import_edge.isBackward();
} }
if(edge.source == edge.target) { if(edge.source == edge.target) {
continue; continue;
} }
edge.data.distance = (std::max)((int)i->weight(), 1 ); edge.data.distance = (std::max)((int)import_edge.weight(), 1 );
assert( edge.data.distance > 0 ); assert( edge.data.distance > 0 );
edge.data.shortcut = false; edge.data.shortcut = false;
edge.data.roundabout = i->isRoundabout(); edge.data.roundabout = import_edge.isRoundabout();
edge.data.ignoreInGrid = i->ignoreInGrid(); edge.data.ignoreInGrid = import_edge.ignoreInGrid();
edge.data.nameID = i->name(); edge.data.nameID = import_edge.name();
edge.data.type = i->type(); edge.data.type = import_edge.type();
edge.data.isAccessRestricted = i->isAccessRestricted(); edge.data.isAccessRestricted = import_edge.isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges_list.size();
edge.data.contraFlow = i->isContraFlow(); edge.data.contraFlow = import_edge.isContraFlow();
edges.push_back( edge ); edges_list.push_back( edge );
if( edge.data.backward ) { if( edge.data.backward ) {
std::swap( edge.source, edge.target ); std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward(); edge.data.forward = import_edge.isBackward();
edge.data.backward = i->isForward(); edge.data.backward = import_edge.isForward();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges_list.size();
edges.push_back( edge ); edges_list.push_back( edge );
} }
} }
std::vector<NodeBasedEdge>().swap(inputEdges); std::vector<ImportEdge>().swap(input_edge_list);
std::sort( edges.begin(), edges.end() ); std::sort( edges_list.begin(), edges_list.end() );
_nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges ); m_node_based_graph = boost::make_shared<NodeBasedDynamicGraph>(
number_of_nodes, edges_list
);
} }
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) { void EdgeBasedGraphFactory::GetEdgeBasedEdges(
DeallocatingVector< EdgeBasedEdge >& output_edge_list
) {
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(
0 == outputEdgeList.size(), 0 == output_edge_list.size(),
"Vector is not empty" "Vector is not empty"
); );
edgeBasedEdges.swap(outputEdgeList); m_edge_based_edge_list.swap(output_edge_list);
} }
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) { void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) {
#ifndef NDEBUG #ifndef NDEBUG
BOOST_FOREACH(EdgeBasedNode & node, edgeBasedNodes){ BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){
assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX); assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX);
assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX); assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX);
} }
#endif #endif
nodes.swap(edgeBasedNodes); nodes.swap(m_edge_based_node_list);
} }
NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const { NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); const NodeID u,
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); const NodeID v
if (restrIter != _restrictionMap.end()) { ) const {
unsigned index = restrIter->second; const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
BOOST_FOREACH(const RestrictionSource & restrictionTarget, _restrictionBucketVector.at(index)) { RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source);
if(restrictionTarget.second) { if (restriction_iter != m_restriction_map.end()) {
return restrictionTarget.first; const unsigned index = restriction_iter->second;
BOOST_FOREACH(
const RestrictionSource & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(restriction_target.second) {
return restriction_target.first;
} }
} }
} }
return UINT_MAX; return UINT_MAX;
} }
bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const { bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const {
//only add an edge if turn is not a U-turn except it is the end of dead-end street. //only add an edge if turn is not a U-turn except it is the end of dead-end street.
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source);
if (restrIter != _restrictionMap.end()) { if (restriction_iter != m_restriction_map.end()) {
unsigned index = restrIter->second; const unsigned index = restriction_iter->second;
BOOST_FOREACH(RestrictionTarget restrictionTarget, _restrictionBucketVector.at(index)) { BOOST_FOREACH(
if(w == restrictionTarget.first) const RestrictionTarget & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(w == restriction_target.first) {
return true; return true;
}
} }
} }
return false; return false;
} }
void EdgeBasedGraphFactory::InsertEdgeBasedNode( void EdgeBasedGraphFactory::InsertEdgeBasedNode(
_NodeBasedDynamicGraph::EdgeIterator e1, EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u, NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v, NodeIterator v,
bool belongsToTinyComponent) { bool belongsToTinyComponent) {
_NodeBasedDynamicGraph::EdgeData & data = _nodeBasedGraph->GetEdgeData(e1); EdgeData & data = m_node_based_graph->GetEdgeData(e1);
EdgeBasedNode currentNode; EdgeBasedNode currentNode;
currentNode.nameID = data.nameID; currentNode.nameID = data.nameID;
currentNode.lat1 = inputNodeInfoList[u].lat; currentNode.lat1 = m_node_info_list[u].lat;
currentNode.lon1 = inputNodeInfoList[u].lon; currentNode.lon1 = m_node_info_list[u].lon;
currentNode.lat2 = inputNodeInfoList[v].lat; currentNode.lat2 = m_node_info_list[v].lat;
currentNode.lon2 = inputNodeInfoList[v].lon; currentNode.lon2 = m_node_info_list[v].lon;
currentNode.belongsToTinyComponent = belongsToTinyComponent; currentNode.belongsToTinyComponent = belongsToTinyComponent;
currentNode.id = data.edgeBasedNodeID; currentNode.id = data.edgeBasedNodeID;
currentNode.ignoreInGrid = data.ignoreInGrid; currentNode.ignoreInGrid = data.ignoreInGrid;
currentNode.weight = data.distance; currentNode.weight = data.distance;
edgeBasedNodes.push_back(currentNode); m_edge_based_node_list.push_back(currentNode);
} }
void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State *myLuaState) { void EdgeBasedGraphFactory::Run(
Percent p(_nodeBasedGraph->GetNumberOfNodes()); const char * original_edge_data_filename,
int numberOfSkippedTurns(0); lua_State *lua_state
int nodeBasedEdgeCounter(0); ) {
unsigned numberOfOriginalEdges(0); SimpleLogger().Write() << "Identifying components of the road network";
std::ofstream originalEdgeDataOutFile(originalEdgeDataFilename, std::ios::binary);
originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned));
Percent p(m_node_based_graph->GetNumberOfNodes());
unsigned skipped_turns_counter = 0;
unsigned node_based_edge_counter = 0;
unsigned original_edges_counter = 0;
INFO("Identifying small components"); std::ofstream edge_data_file(
original_edge_data_filename,
std::ios::binary
);
//writes a dummy value that is updated later
edge_data_file.write(
(char*)&original_edges_counter,
sizeof(unsigned)
);
unsigned current_component = 0, current_component_size = 0;
//Run a BFS on the undirected graph and identify small components //Run a BFS on the undirected graph and identify small components
std::queue<std::pair<NodeID, NodeID> > bfsQueue; std::queue<std::pair<NodeID, NodeID> > bfs_queue;
std::vector<unsigned> componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX); std::vector<unsigned> component_index_list(
std::vector<NodeID> vectorOfComponentSizes; m_node_based_graph->GetNumberOfNodes(),
unsigned currentComponent = 0, sizeOfCurrentComponent = 0; UINT_MAX
);
std::vector<NodeID> component_size_list;
//put unexplorered node with parent pointer into queue //put unexplorered node with parent pointer into queue
for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) { for(
if(UINT_MAX == componentsIndex[node]) { NodeID node = 0,
bfsQueue.push(std::make_pair(node, node)); last_node = m_node_based_graph->GetNumberOfNodes();
node < last_node;
++node
) {
if(UINT_MAX == component_index_list[node]) {
bfs_queue.push(std::make_pair(node, node));
//mark node as read //mark node as read
componentsIndex[node] = currentComponent; component_index_list[node] = current_component;
p.printIncrement(); p.printIncrement();
while(!bfsQueue.empty()) { while(!bfs_queue.empty()) {
//fetch element from BFS queue //fetch element from BFS queue
std::pair<NodeID, NodeID> currentQueueItem = bfsQueue.front(); std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
bfsQueue.pop(); bfs_queue.pop();
// INFO("sizeof queue: " << bfsQueue.size() << ", sizeOfCurrentComponents: " << sizeOfCurrentComponent << ", settled nodes: " << settledNodes++ << ", max: " << endNodes); // SimpleLogger().Write() << "sizeof queue: " << bfs_queue.size() <<
const NodeID v = currentQueueItem.first; //current node // ", current_component_sizes: " << current_component_size <<
const NodeID u = currentQueueItem.second; //parent //", settled nodes: " << settledNodes++ << ", max: " << endNodes;
const NodeID v = current_queue_item.first; //current node
const NodeID u = current_queue_item.second; //parent
//increment size counter of current component //increment size counter of current component
++sizeOfCurrentComponent; ++current_component_size;
const bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
if(!isBollardNode) { if(!is_barrier_node) {
const NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
//relaxieren edge outgoing edge like below where edge-expanded graph //relaxieren edge outgoing edge like below where edge-expanded graph
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { for(
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); EdgeIterator e2 = m_node_based_graph->BeginEdges(v);
e2 < m_node_based_graph->EndEdges(v);
++e2
) {
NodeIterator w = m_node_based_graph->GetTarget(e2);
if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. if(
to_node_of_only_restriction != UINT_MAX &&
w != to_node_of_only_restriction
) {
//We are at an only_-restriction but not at the right turn.
continue; continue;
} }
if( u != w ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. if( u != w ) {
if (!CheckIfTurnIsRestricted(u, v, w) ) { //only add an edge if turn is not prohibited //only add an edge if turn is not a U-turn except
//insert next (node, parent) only if w has not yet been explored //when it is at the end of a dead-end street.
if(UINT_MAX == componentsIndex[w]) { if (!CheckIfTurnIsRestricted(u, v, w) ) {
//only add an edge if turn is not prohibited
if(UINT_MAX == component_index_list[w]) {
//insert next (node, parent) only if w has
//not yet been explored
//mark node as read //mark node as read
componentsIndex[w] = currentComponent; component_index_list[w] = current_component;
bfsQueue.push(std::make_pair(w,v)); bfs_queue.push(std::make_pair(w,v));
p.printIncrement(); p.printIncrement();
} }
} }
@ -210,149 +284,228 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
} }
} }
//push size into vector //push size into vector
vectorOfComponentSizes.push_back(sizeOfCurrentComponent); component_size_list.push_back(current_component_size);
//reset counters; //reset counters;
sizeOfCurrentComponent = 0; current_component_size = 0;
++currentComponent; ++current_component;
} }
} }
INFO("identified: " << vectorOfComponentSizes.size() << " many components"); SimpleLogger().Write() <<
"identified: " << component_size_list.size() << " many components";
p.reinit(_nodeBasedGraph->GetNumberOfNodes()); p.reinit(m_node_based_graph->GetNumberOfNodes());
//loop over all edges and generate new set of nodes. //loop over all edges and generate new set of nodes.
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { for(
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { NodeIterator u = 0,
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); number_of_nodes = m_node_based_graph->GetNumberOfNodes();
u < number_of_nodes;
++u
) {
for(
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
last_edge = m_node_based_graph->EndEdges(u);
e1 < last_edge;
++e1
) {
NodeIterator v = m_node_based_graph->GetTarget(e1);
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) { if(m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX) {
assert(e1 != UINT_MAX); BOOST_ASSERT_MSG(e1 != UINT_MAX, "edge id invalid");
assert(u != UINT_MAX); BOOST_ASSERT_MSG(u != UINT_MAX, "souce node invalid");
assert(v != UINT_MAX); BOOST_ASSERT_MSG(v != UINT_MAX, "target node invalid");
//edges that end on bollard nodes may actually be in two distinct components //Note: edges that end on barrier nodes or on a turn restriction
InsertEdgeBasedNode(e1, u, v, (std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 1000) ); //may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min(
component_size_list[component_index_list[u]],
component_size_list[component_index_list[v]]
);
InsertEdgeBasedNode( e1, u, v, size_of_component < 1000 );
} }
} }
} }
std::vector<NodeID>().swap(vectorOfComponentSizes); std::vector<NodeID>().swap(component_size_list);
std::vector<NodeID>().swap(componentsIndex); BOOST_ASSERT_MSG(
0 == component_size_list.capacity(),
"component size vector not deallocated"
);
std::vector<NodeID>().swap(component_index_list);
BOOST_ASSERT_MSG(
0 == component_index_list.capacity(),
"component index vector not deallocated"
);
std::vector<OriginalEdgeData> original_edge_data_vector; std::vector<OriginalEdgeData> original_edge_data_vector;
original_edge_data_vector.reserve(10000); original_edge_data_vector.reserve(10000);
//Loop over all turns and generate new set of edges. //Loop over all turns and generate new set of edges.
//Three nested loop look super-linear, but we are dealing with a linear number of turns only. //Three nested loop look super-linear, but we are dealing with a (kind of)
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { //linear number of turns only.
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { for(
++nodeBasedEdgeCounter; NodeIterator u = 0,
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); last_node = m_node_based_graph->GetNumberOfNodes();
bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); u < last_node;
//EdgeWeight heightPenalty = ComputeHeightPenalty(u, v); ++u
NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); ) {
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { for(
const _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
last_edge_u = m_node_based_graph->EndEdges(u);
if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. e1 < last_edge_u;
++numberOfSkippedTurns; ++e1
) {
++node_based_edge_counter;
NodeIterator v = m_node_based_graph->GetTarget(e1);
bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
for(
EdgeIterator e2 = m_node_based_graph->BeginEdges(v),
last_edge_v = m_node_based_graph->EndEdges(v);
e2 < last_edge_v;
++e2
) {
const NodeIterator w = m_node_based_graph->GetTarget(e2);
if(
to_node_of_only_restriction != UINT_MAX &&
w != to_node_of_only_restriction
) {
//We are at an only_-restriction but not at the right turn.
++skipped_turns_counter;
continue; continue;
} }
if(u == w && 1 != _nodeBasedGraph->GetOutDegree(v) ) { if(u == w && 1 != m_node_based_graph->GetOutDegree(v) ) {
continue; continue;
} }
if( !isBollardNode ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. if( !is_barrier_node ) {
if (!CheckIfTurnIsRestricted(u, v, w) || (onlyToNode != UINT_MAX && w == onlyToNode)) { //only add an edge if turn is not prohibited //only add an edge if turn is not a U-turn except when it is
const _NodeBasedDynamicGraph::EdgeData edgeData1 = _nodeBasedGraph->GetEdgeData(e1); //at the end of a dead-end street
const _NodeBasedDynamicGraph::EdgeData edgeData2 = _nodeBasedGraph->GetEdgeData(e2); if (
assert(edgeData1.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); !CheckIfTurnIsRestricted(u, v, w) ||
assert(edgeData2.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); (to_node_of_only_restriction != UINT_MAX && w == to_node_of_only_restriction)
) { //only add an edge if turn is not prohibited
const EdgeData edge_data1 = m_node_based_graph->GetEdgeData(e1);
const EdgeData edge_data2 = m_node_based_graph->GetEdgeData(e2);
assert(edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges());
assert(edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges());
if(!edgeData1.forward || !edgeData2.forward) { if(!edge_data1.forward || !edge_data2.forward) {
continue; continue;
} }
unsigned distance = edgeData1.distance; unsigned distance = edge_data1.distance;
if(_trafficLights.find(v) != _trafficLights.end()) { if(m_traffic_lights.find(v) != m_traffic_lights.end()) {
distance += speedProfile.trafficSignalPenalty; distance += speed_profile.trafficSignalPenalty;
}
const unsigned penalty =
GetTurnPenalty(u, v, w, lua_state);
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w);
if(turnInstruction == TurnInstructions.UTurn){
distance += speed_profile.uTurnPenalty;
} }
unsigned penalty = 0;
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w, penalty, myLuaState);
if(turnInstruction == TurnInstructions.UTurn)
distance += speedProfile.uTurnPenalty;
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
// distance += TurnInstructions.AccessRestrictionPenalty;
// turnInstruction |= TurnInstructions.AccessRestrictionFlag;
// }
distance += penalty; distance += penalty;
assert(edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID);
//distance += heightPenalty; original_edge_data_vector.push_back(
//distance += ComputeTurnPenalty(u, v, w); OriginalEdgeData(
assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID); v,
OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction); edge_data2.nameID,
original_edge_data_vector.push_back(oed); turnInstruction
++numberOfOriginalEdges; )
);
++original_edges_counter;
if(original_edge_data_vector.size() > 100000) { if(original_edge_data_vector.size() > 100000) {
originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); edge_data_file.write(
(char*)&(original_edge_data_vector[0]),
original_edge_data_vector.size()*sizeof(OriginalEdgeData)
);
original_edge_data_vector.clear(); original_edge_data_vector.clear();
} }
EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false ); m_edge_based_edge_list.push_back(
edgeBasedEdges.push_back(newEdge); EdgeBasedEdge(
edge_data1.edgeBasedNodeID,
edge_data2.edgeBasedNodeID,
m_edge_based_edge_list.size(),
distance,
true,
false
)
);
} else { } else {
++numberOfSkippedTurns; ++skipped_turns_counter;
} }
} }
} }
} }
p.printIncrement(); p.printIncrement();
} }
originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); edge_data_file.write(
originalEdgeDataOutFile.seekp(std::ios::beg); (char*)&(original_edge_data_vector[0]),
originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned)); original_edge_data_vector.size()*sizeof(OriginalEdgeData)
originalEdgeDataOutFile.close(); );
edge_data_file.seekp(std::ios::beg);
edge_data_file.write(
(char*)&original_edges_counter,
sizeof(unsigned)
);
edge_data_file.close();
// INFO("Sorting edge-based Nodes"); SimpleLogger().Write() <<
// std::sort(edgeBasedNodes.begin(), edgeBasedNodes.end()); "Generated " << m_edge_based_node_list.size() << " edge based nodes";
// INFO("Removing duplicate nodes (if any)"); SimpleLogger().Write() <<
// edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() ); "Node-based graph contains " << node_based_edge_counter << " edges";
// INFO("Applying vector self-swap trick to free up memory"); SimpleLogger().Write() <<
// INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity()); "Edge-expanded graph ...";
// std::vector<EdgeBasedNode>(edgeBasedNodes).swap(edgeBasedNodes); SimpleLogger().Write() <<
// INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity()); " contains " << m_edge_based_edge_list.size() << " edges";
INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges"); SimpleLogger().Write() <<
INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges"); " skips " << skipped_turns_counter << " turns, "
// INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << 2*((double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter)); "defined by " << m_turn_restrictions_count << " restrictions";
INFO("Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions.");
INFO("Generated " << edgeBasedNodes.size() << " edge based nodes");
} }
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, unsigned& penalty, lua_State *myLuaState) const { int EdgeBasedGraphFactory::GetTurnPenalty(
const double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]); const NodeID u,
const NodeID v,
const NodeID w,
lua_State *lua_state
) const {
const double angle = GetAngleBetweenThreeFixedPointCoordinates (
m_node_info_list[u],
m_node_info_list[v],
m_node_info_list[w]
);
if( speedProfile.has_turn_penalty_function ) { if( speed_profile.has_turn_penalty_function ) {
try { try {
//call lua profile to compute turn penalty //call lua profile to compute turn penalty
penalty = luabind::call_function<int>( myLuaState, "turn_function", 180-angle ); return luabind::call_function<int>(
lua_state,
"turn_function",
180.-angle
);
} catch (const luabind::error &er) { } catch (const luabind::error &er) {
std::cerr << er.what() << std::endl; SimpleLogger().Write(logWARNING) << er.what();
//TODO handle lua errors
} }
} else {
penalty = 0;
} }
return 0;
}
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const NodeID u,
const NodeID v,
const NodeID w
) const {
if(u == w) { if(u == w) {
return TurnInstructions.UTurn; return TurnInstructions.UTurn;
} }
_NodeBasedDynamicGraph::EdgeIterator edge1 = _nodeBasedGraph->FindEdge(u, v); EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v);
_NodeBasedDynamicGraph::EdgeIterator edge2 = _nodeBasedGraph->FindEdge(v, w); EdgeIterator edge2 = m_node_based_graph->FindEdge(v, w);
_NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1); EdgeData & data1 = m_node_based_graph->GetEdgeData(edge1);
_NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2); EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2);
if(!data1.contraFlow && data2.contraFlow) { if(!data1.contraFlow && data2.contraFlow) {
return TurnInstructions.EnterAgainstAllowedDirection; return TurnInstructions.EnterAgainstAllowedDirection;
@ -364,7 +517,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
//roundabouts need to be handled explicitely //roundabouts need to be handled explicitely
if(data1.roundabout && data2.roundabout) { if(data1.roundabout && data2.roundabout) {
//Is a turn possible? If yes, we stay on the roundabout! //Is a turn possible? If yes, we stay on the roundabout!
if( 1 == (_nodeBasedGraph->EndEdges(v) - _nodeBasedGraph->BeginEdges(v)) ) { if( 1 == m_node_based_graph->GetOutDegree(v) ) {
//No turn possible. //No turn possible.
return TurnInstructions.NoTurn; return TurnInstructions.NoTurn;
} }
@ -382,31 +535,27 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
} }
} }
//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
if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) { //a segment of a roundabout, we skip it.
return TurnInstructions.NoTurn; if( data1.nameID == data2.nameID ) {
} //TODO: Here we should also do a small graph exploration to check for
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) { // more complex situations
return TurnInstructions.NoTurn; if( 0 != data1.nameID ) {
return TurnInstructions.NoTurn;
} else if (m_node_based_graph->GetOutDegree(v) <= 2) {
return TurnInstructions.NoTurn;
}
} }
const double angle = GetAngleBetweenThreeFixedPointCoordinates (
m_node_info_list[u],
m_node_info_list[v],
m_node_info_list[w]
);
return TurnInstructions.GetTurnDirectionOfInstruction(angle); return TurnInstructions.GetTurnDirectionOfInstruction(angle);
} }
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const { unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const {
return _nodeBasedGraph->GetNumberOfEdges(); return m_node_based_graph->GetNumberOfEdges();
}
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
template<class CoordinateT>
double EdgeBasedGraphFactory::GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const {
const double v1x = (A.lon - C.lon)/100000.;
const double v1y = lat2y(A.lat/100000.) - lat2y(C.lat/100000.);
const double v2x = (B.lon - C.lon)/100000.;
const double v2y = lat2y(B.lat/100000.) - lat2y(C.lat/100000.);
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
} }

View File

@ -18,9 +18,7 @@
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
/* // This class constructs the edge-expanded routing graph
* This class constructs the edge base representation of a graph from a given node based edge list
*/
#ifndef EDGEBASEDGRAPHFACTORY_H_ #ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_ #define EDGEBASEDGRAPHFACTORY_H_
@ -31,14 +29,11 @@
#include "../Extractor/ExtractorStructs.h" #include "../Extractor/ExtractorStructs.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
#include "../DataStructures/MercatorUtil.h"
#include "../DataStructures/QueryEdge.h" #include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Percent.h" #include "../DataStructures/Percent.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/BaseConfiguration.h"
#include "../Util/LuaUtil.h" #include "../Util/LuaUtil.h"
#include "../Util/SimpleLogger.h"
#include <stxxl.h>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
@ -47,9 +42,8 @@
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <cstdlib>
#include <algorithm> #include <algorithm>
#include <fstream>
#include <queue> #include <queue>
#include <vector> #include <vector>
@ -67,6 +61,7 @@ public:
weight(UINT_MAX >> 1), weight(UINT_MAX >> 1),
ignoreInGrid(false) ignoreInGrid(false)
{ } { }
bool operator<(const EdgeBasedNode & other) const { bool operator<(const EdgeBasedNode & other) const {
return other.id < id; return other.id < id;
} }
@ -75,8 +70,8 @@ public:
return id == other.id; return id == other.id;
} }
inline _Coordinate Centroid() const { inline FixedPointCoordinate Centroid() const {
_Coordinate centroid; FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by: //The coordinates of the midpoint are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2. //x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (std::min(lon1, lon2) + std::max(lon1, lon2))/2; centroid.lon = (std::min(lon1, lon2) + std::max(lon1, lon2))/2;
@ -87,6 +82,7 @@ public:
inline bool isIgnored() const { inline bool isIgnored() const {
return ignoreInGrid; return ignoreInGrid;
} }
NodeID id; NodeID id;
int lat1; int lat1;
int lat2; int lat2;
@ -99,14 +95,47 @@ public:
}; };
struct SpeedProfileProperties{ struct SpeedProfileProperties{
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false) {} SpeedProfileProperties() :
trafficSignalPenalty(0),
uTurnPenalty(0),
has_turn_penalty_function(false)
{ }
int trafficSignalPenalty; int trafficSignalPenalty;
int uTurnPenalty; int uTurnPenalty;
bool has_turn_penalty_function; bool has_turn_penalty_function;
} speedProfile; } speed_profile;
explicit EdgeBasedGraphFactory(
int number_of_nodes,
std::vector<ImportEdge> & input_edge_list,
std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speed_profile
);
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector<OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(
const NodeID u,
const NodeID v,
const NodeID w
) const;
int GetTurnPenalty(
const NodeID u,
const NodeID v,
const NodeID w,
lua_State *myLuaState
) const;
unsigned GetNumberOfNodes() const;
private: private:
struct _NodeBasedEdgeData { struct NodeBasedEdgeData {
int distance; int distance;
unsigned edgeBasedNodeID; unsigned edgeBasedNodeID;
unsigned nameID; unsigned nameID;
@ -129,45 +158,46 @@ private:
TurnInstruction turnInstruction; TurnInstruction turnInstruction;
}; };
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; unsigned m_turn_restrictions_count;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph; typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
boost::unordered_set<NodeID> _barrierNodes; typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
boost::unordered_set<NodeID> _trafficLights; typedef NodeBasedDynamicGraph::NodeIterator NodeIterator;
typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator;
typedef std::pair<NodeID, NodeID> RestrictionSource; typedef NodeBasedDynamicGraph::EdgeData EdgeData;
typedef std::pair<NodeID, bool> RestrictionTarget; typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector; typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap; typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges; std::vector<NodeInfo> m_node_info_list;
std::vector<EdgeBasedNode> edgeBasedNodes; std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
std::vector<EdgeBasedNode> m_edge_based_node_list;
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
boost::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
boost::unordered_set<NodeID> m_barrier_nodes;
boost::unordered_set<NodeID> m_traffic_lights;
RestrictionMap m_restriction_map;
NodeID CheckForEmanatingIsOnlyTurn(
const NodeID u,
const NodeID v
) const;
bool CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const;
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
void InsertEdgeBasedNode( void InsertEdgeBasedNode(
_NodeBasedDynamicGraph::EdgeIterator e1, NodeBasedDynamicGraph::EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u, NodeBasedDynamicGraph::NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v, NodeBasedDynamicGraph::NodeIterator v,
bool belongsToTinyComponent); bool belongsToTinyComponent);
template<class CoordinateT>
double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const;
public:
template< class InputEdgeT >
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, SpeedProfileProperties speedProfile);
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, unsigned& penalty, lua_State *myLuaState) const;
unsigned GetNumberOfNodes() const;
}; };
#endif /* EDGEBASEDGRAPHFACTORY_H_ */ #endif /* EDGEBASEDGRAPHFACTORY_H_ */

View File

@ -21,11 +21,7 @@
#include "TemporaryStorage.h" #include "TemporaryStorage.h"
TemporaryStorage::TemporaryStorage() { TemporaryStorage::TemporaryStorage() {
try { tempDirectory = boost::filesystem::temp_directory_path();
tempDirectory = boost::filesystem::temp_directory_path();
} catch(boost::filesystem::filesystem_error & e) {
ERR("could not retrieve location of temporary path: " << e.what());
}
} }
TemporaryStorage & TemporaryStorage::GetInstance(){ TemporaryStorage & TemporaryStorage::GetInstance(){
@ -39,12 +35,8 @@ TemporaryStorage::~TemporaryStorage() {
void TemporaryStorage::removeAll() { void TemporaryStorage::removeAll() {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
try { for(unsigned slot_id = 0; slot_id < vectorOfStreamDatas.size(); ++slot_id) {
for(unsigned slotID = 0; slotID < vectorOfStreamDatas.size(); ++slotID) deallocateSlot(slot_id);
deallocateSlot(slotID);
} catch(boost::filesystem::filesystem_error & e) {
ERR("could not retrieve location of temporary path: " << e.what());
} }
vectorOfStreamDatas.clear(); vectorOfStreamDatas.clear();
} }
@ -53,7 +45,7 @@ int TemporaryStorage::allocateSlot() {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
try { try {
vectorOfStreamDatas.push_back(StreamData()); vectorOfStreamDatas.push_back(StreamData());
//INFO("created new temporary file: " << vectorOfStreamDatas.back().pathToTemporaryFile); //SimpleLogger().Write() << "created new temporary file: " << vectorOfStreamDatas.back().pathToTemporaryFile;
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
} }
@ -64,13 +56,13 @@ void TemporaryStorage::deallocateSlot(int slotID) {
try { try {
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!boost::filesystem::exists(data.pathToTemporaryFile)) { if(!boost::filesystem::exists(data.pathToTemporaryFile)) {
return; return;
} }
if(data.streamToTemporaryFile->is_open()) if(data.streamToTemporaryFile->is_open()) {
data.streamToTemporaryFile->close(); data.streamToTemporaryFile->close();
}
//INFO("deallocating slot " << slotID << " and its file: " << data.pathToTemporaryFile);
boost::filesystem::remove(data.pathToTemporaryFile); boost::filesystem::remove(data.pathToTemporaryFile);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
@ -81,8 +73,10 @@ void TemporaryStorage::writeToSlot(int slotID, char * pointer, std::streamsize s
try { try {
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!data.writeMode) BOOST_ASSERT_MSG(
ERR("Writing after first read is not allowed"); data.writeMode,
"Writing after first read is not allowed"
);
data.streamToTemporaryFile->write(pointer, size); data.streamToTemporaryFile->write(pointer, size);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
@ -121,13 +115,11 @@ boost::filesystem::fstream::pos_type TemporaryStorage::tell(int slotID) {
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
} }
// INFO("telling position: " << position);
return position; return position;
} }
void TemporaryStorage::abort(boost::filesystem::filesystem_error& ) { void TemporaryStorage::abort(boost::filesystem::filesystem_error& ) {
removeAll(); removeAll();
// ERR("I/O Error occured: " << e.what());
} }
void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type position) { void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type position) {
@ -135,7 +127,6 @@ void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type pos
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
data.streamToTemporaryFile->seekg(position); data.streamToTemporaryFile->seekg(position);
// INFO("seeking to position: " << position);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
} }

View File

@ -24,12 +24,15 @@
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#include <boost/assert.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
//This is one big workaround for latest boost renaming woes. //This is one big workaround for latest boost renaming woes.
@ -102,8 +105,9 @@ private:
streamToTemporaryFile(new boost::filesystem::fstream(pathToTemporaryFile, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)), streamToTemporaryFile(new boost::filesystem::fstream(pathToTemporaryFile, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
readWriteMutex(new boost::mutex) readWriteMutex(new boost::mutex)
{ {
if(streamToTemporaryFile->fail()) if(streamToTemporaryFile->fail()) {
ERR("Aborting, because temporary file at " << pathToTemporaryFile << " could not be created"); throw OSRMException("temporary file could not be created");
}
} }
}; };
//vector of file streams that is used to store temporary data //vector of file streams that is used to store temporary data

View File

@ -147,13 +147,13 @@ public:
return insertedNodes[index].weight; return insertedNodes[index].weight;
} }
bool WasRemoved( NodeID node ) { bool WasRemoved( const NodeID node ) {
assert( WasInserted( node ) ); assert( WasInserted( node ) );
const Key index = nodeIndex[node]; const Key index = nodeIndex[node];
return insertedNodes[index].key == 0; return insertedNodes[index].key == 0;
} }
bool WasInserted( NodeID node ) { bool WasInserted( const NodeID node ) {
const Key index = nodeIndex[node]; const Key index = nodeIndex[node];
if ( index >= static_cast<Key> (insertedNodes.size()) ) if ( index >= static_cast<Key> (insertedNodes.size()) )
return false; return false;

View File

@ -18,9 +18,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef COORDINATE_H_ #ifndef FIXED_POINT_COORDINATE_H_
#define COORDINATE_H_ #define FIXED_POINT_COORDINATE_H_
#include "../DataStructures/MercatorUtil.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <cassert> #include <cassert>
@ -29,11 +30,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <iostream> #include <iostream>
struct _Coordinate { static const double COORDINATE_PRECISION = 1000000.;
struct FixedPointCoordinate {
int lat; int lat;
int lon; int lon;
_Coordinate () : lat(INT_MIN), lon(INT_MIN) {} FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {}
explicit _Coordinate (int t, int n) : lat(t) , lon(n) {} explicit FixedPointCoordinate (int lat, int lon) : lat(lat) , lon(lon) {}
void Reset() { void Reset() {
lat = INT_MIN; lat = INT_MIN;
@ -43,17 +46,22 @@ struct _Coordinate {
return (INT_MIN != lat) && (INT_MIN != lon); return (INT_MIN != lat) && (INT_MIN != lon);
} }
inline bool isValid() const { inline bool isValid() const {
if(lat > 90*100000 || lat < -90*100000 || lon > 180*100000 || lon <-180*100000) { if(
lat > 90*COORDINATE_PRECISION ||
lat < -90*COORDINATE_PRECISION ||
lon > 180*COORDINATE_PRECISION ||
lon < -180*COORDINATE_PRECISION
) {
return false; return false;
} }
return true; return true;
} }
bool operator==(const _Coordinate & other) const { bool operator==(const FixedPointCoordinate & other) const {
return lat == other.lat && lon == other.lon; return lat == other.lat && lon == other.lon;
} }
}; };
inline std::ostream & operator<<(std::ostream & out, const _Coordinate & c){ inline std::ostream & operator<<(std::ostream & out, const FixedPointCoordinate & c){
out << "(" << c.lat << "," << c.lon << ")"; out << "(" << c.lat << "," << c.lon << ")";
return out; return out;
} }
@ -64,10 +72,10 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat
assert(lat2 != INT_MIN); assert(lat2 != INT_MIN);
assert(lon2 != INT_MIN); assert(lon2 != INT_MIN);
double RAD = 0.017453292519943295769236907684886; double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1/100000.; double lt1 = lat1/COORDINATE_PRECISION;
double ln1 = lon1/100000.; double ln1 = lon1/COORDINATE_PRECISION;
double lt2 = lat2/100000.; double lt2 = lat2/COORDINATE_PRECISION;
double ln2 = lon2/100000.; double ln2 = lon2/COORDINATE_PRECISION;
double dlat1=lt1*(RAD); double dlat1=lt1*(RAD);
double dlong1=ln1*(RAD); double dlong1=ln1*(RAD);
@ -86,20 +94,20 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat
return distance; return distance;
} }
inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) { inline double ApproximateDistance(const FixedPointCoordinate &c1, const FixedPointCoordinate &c2) {
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon ); return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
} }
inline double ApproximateEuclideanDistance(const _Coordinate &c1, const _Coordinate &c2) { inline double ApproximateEuclideanDistance(const FixedPointCoordinate &c1, const FixedPointCoordinate &c2) {
assert(c1.lat != INT_MIN); assert(c1.lat != INT_MIN);
assert(c1.lon != INT_MIN); assert(c1.lon != INT_MIN);
assert(c2.lat != INT_MIN); assert(c2.lat != INT_MIN);
assert(c2.lon != INT_MIN); assert(c2.lon != INT_MIN);
const double RAD = 0.017453292519943295769236907684886; const double RAD = 0.017453292519943295769236907684886;
const double lat1 = (c1.lat/100000.)*RAD; const double lat1 = (c1.lat/COORDINATE_PRECISION)*RAD;
const double lon1 = (c1.lon/100000.)*RAD; const double lon1 = (c1.lon/COORDINATE_PRECISION)*RAD;
const double lat2 = (c2.lat/100000.)*RAD; const double lat2 = (c2.lat/COORDINATE_PRECISION)*RAD;
const double lon2 = (c2.lon/100000.)*RAD; const double lon2 = (c2.lon/COORDINATE_PRECISION)*RAD;
const double x = (lon2-lon1) * cos((lat1+lat2)/2.); const double x = (lon2-lon1) * cos((lat1+lat2)/2.);
const double y = (lat2-lat1); const double y = (lat2-lat1);
@ -111,11 +119,11 @@ inline double ApproximateEuclideanDistance(const _Coordinate &c1, const _Coordin
static inline void convertInternalLatLonToString(const int value, std::string & output) { static inline void convertInternalLatLonToString(const int value, std::string & output) {
char buffer[100]; char buffer[100];
buffer[10] = 0; // Nullterminierung buffer[10] = 0; // Nullterminierung
char* string = printInt< 10, 5 >( buffer, value ); char* string = printInt< 10, 6 >( buffer, value );
output = string; output = string;
} }
static inline void convertInternalCoordinateToString(const _Coordinate & coord, std::string & output) { static inline void convertInternalCoordinateToString(const FixedPointCoordinate & coord, std::string & output) {
std::string tmp; std::string tmp;
convertInternalLatLonToString(coord.lon, tmp); convertInternalLatLonToString(coord.lon, tmp);
output = tmp; output = tmp;
@ -124,7 +132,7 @@ static inline void convertInternalCoordinateToString(const _Coordinate & coord,
output += tmp; output += tmp;
output += " "; output += " ";
} }
static inline void convertInternalReversedCoordinateToString(const _Coordinate & coord, std::string & output) { static inline void convertInternalReversedCoordinateToString(const FixedPointCoordinate & coord, std::string & output) {
std::string tmp; std::string tmp;
convertInternalLatLonToString(coord.lat, tmp); convertInternalLatLonToString(coord.lat, tmp);
output = tmp; output = tmp;
@ -134,4 +142,22 @@ static inline void convertInternalReversedCoordinateToString(const _Coordinate &
output += " "; output += " ";
} }
#endif /* COORDINATE_H_ */
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
template<class CoordinateT>
static inline double GetAngleBetweenThreeFixedPointCoordinates (
const CoordinateT & A,
const CoordinateT & C,
const CoordinateT & B
) {
const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION;
const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION;
const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
}
#endif /* FIXED_POINT_COORDINATE_H_ */

View File

@ -194,7 +194,7 @@ class DynamicGraph {
//searches for a specific edge //searches for a specific edge
EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const { EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const {
for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) { for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) {
if ( m_edges[i].target == to ) { if ( to == m_edges[i].target ) {
return i; return i;
} }
} }

View File

@ -24,56 +24,35 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef HASHTABLE_H_ #ifndef HASHTABLE_H_
#define HASHTABLE_H_ #define HASHTABLE_H_
#include <boost/ref.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
template<typename keyT, typename valueT> template<typename keyT, typename valueT>
class HashTable { class HashTable : public boost::unordered_map<keyT, valueT> {
typedef boost::unordered_map<keyT, valueT> MyHashTable; private:
typedef boost::unordered_map<keyT, valueT> super;
public: public:
typedef typename boost::unordered_map<keyT, valueT>::const_iterator MyIterator; HashTable() : super() { }
typedef MyIterator iterator;
HashTable() { } HashTable(const unsigned size) : super(size) { }
HashTable(const unsigned size) {
table.resize(size);
}
inline void Add(const keyT& key, const valueT& value){ inline void Add(const keyT& key, const valueT& value){
table[key] = value; super::insert(std::make_pair(key, value));
}
inline void Set(const keyT& key, const valueT& value){
table[key] = value;
} }
inline valueT Find(const keyT& key) const { inline valueT Find(const keyT& key) const {
if(table.find(key) == table.end()) if(super::find(key) == super::end()) {
return valueT(); return valueT();
return table.find(key)->second; }
return boost::ref(super::find(key)->second);
} }
inline bool Holds(const keyT& key) const { inline bool Holds(const keyT& key) const {
if(table.find(key) == table.end()) if(super::find(key) == super::end()) {
return false; return false;
}
return true; return true;
} }
void EraseAll() {
if(table.size() > 0)
table.clear();
}
inline valueT operator[] (keyT key) const {
if(table.find(key) == table.end())
return valueT();
return table.find(key)->second;
}
inline unsigned Size() const {
return table.size();
}
MyIterator begin() const {
return table.begin();
}
MyIterator end() const {
return table.end();
}
private:
MyHashTable table;
}; };
#endif /* HASHTABLE_H_ */ #endif /* HASHTABLE_H_ */

View File

@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef HILBERTVALUE_H_ #ifndef HILBERTVALUE_H_
#define HILBERTVALUE_H_ #define HILBERTVALUE_H_
#include "Coordinate.h"
#include <boost/integer.hpp> #include <boost/integer.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@ -29,10 +31,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
class HilbertCode : boost::noncopyable { class HilbertCode : boost::noncopyable {
public: public:
static uint64_t GetHilbertNumberForCoordinate( static uint64_t GetHilbertNumberForCoordinate(
const _Coordinate & current_coordinate) { const FixedPointCoordinate & current_coordinate
) {
unsigned location[2]; unsigned location[2];
location[0] = current_coordinate.lat+( 90*100000); location[0] = current_coordinate.lat+( 90*COORDINATE_PRECISION);
location[1] = current_coordinate.lon+(180*100000); location[1] = current_coordinate.lon+(180*COORDINATE_PRECISION);
TransposeCoordinate(location); TransposeCoordinate(location);
const uint64_t result = BitInterleaving(location[0], location[1]); const uint64_t result = BitInterleaving(location[0], location[1]);

View File

@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef EDGE_H #ifndef EDGE_H
#define EDGE_H #define EDGE_H
#include "../Util/OSRMException.h"
#include <cassert> #include <cassert>
class NodeBasedEdge { class NodeBasedEdge {
@ -40,8 +42,34 @@ public:
return (source() < e.source()); return (source() < e.source());
} }
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar, bool cf) : explicit NodeBasedEdge(
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar), _contraFlow(cf) { if(ty < 0) {ERR("Type: " << ty);}; } NodeID s,
NodeID t,
NodeID n,
EdgeWeight w,
bool f,
bool b,
short ty,
bool ra,
bool ig,
bool ar,
bool cf
) : _source(s),
_target(t),
_name(n),
_weight(w),
forward(f),
backward(b),
_type(ty),
_roundabout(ra),
_ignoreInGrid(ig),
_accessRestricted(ar),
_contraFlow(cf)
{
if(ty < 0) {
throw OSRMException("negative edge type");
}
}
NodeID target() const {return _target; } NodeID target() const {return _target; }
NodeID source() const {return _source; } NodeID source() const {return _source; }

View File

@ -21,7 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef IMPORTNODE_H_ #ifndef IMPORTNODE_H_
#define IMPORTNODE_H_ #define IMPORTNODE_H_
#include "NodeCoords.h" #include "QueryNode.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
@ -44,9 +44,9 @@ struct _Node : NodeInfo{
struct ImportNode : public _Node { struct ImportNode : public _Node {
HashTable<std::string, std::string> keyVals; HashTable<std::string, std::string> keyVals;
inline void Clear() { inline void Clear() {
keyVals.EraseAll(); keyVals.clear();
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false; lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false;
} }
}; };

View File

@ -21,23 +21,25 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef NODEINFORMATIONHELPDESK_H_ #ifndef NODEINFORMATIONHELPDESK_H_
#define NODEINFORMATIONHELPDESK_H_ #define NODEINFORMATIONHELPDESK_H_
#include "NodeCoords.h" #include "QueryNode.h"
#include "PhantomNodes.h" #include "PhantomNodes.h"
#include "StaticRTree.h" #include "StaticRTree.h"
#include "../Contractor/EdgeBasedGraphFactory.h" #include "../Contractor/EdgeBasedGraphFactory.h"
#include "../Util/OSRMException.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <iostream> #include <iostream>
#include <fstream>
#include <string> #include <string>
#include <vector> #include <vector>
typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf; typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf;
class NodeInformationHelpDesk : boost::noncopyable{ class NodeInformationHelpDesk : boost::noncopyable {
public: public:
NodeInformationHelpDesk( NodeInformationHelpDesk(
const std::string & ramIndexInput, const std::string & ramIndexInput,
@ -46,8 +48,21 @@ public:
const std::string & edges_filename, const std::string & edges_filename,
const unsigned number_of_nodes, const unsigned number_of_nodes,
const unsigned check_sum const unsigned check_sum
) : number_of_nodes(number_of_nodes), check_sum(check_sum) ) : number_of_nodes(number_of_nodes), check_sum(check_sum)
{ {
if ( ramIndexInput.empty() ) {
throw OSRMException("no ram index file name in server ini");
}
if ( fileIndexInput.empty() ) {
throw OSRMException("no mem index file name in server ini");
}
if ( nodes_filename.empty() ) {
throw OSRMException("no nodes file name in server ini");
}
if ( edges_filename.empty() ) {
throw OSRMException("no edges file name in server ini");
}
read_only_rtree = new StaticRTree<RTreeLeaf>( read_only_rtree = new StaticRTree<RTreeLeaf>(
ramIndexInput, ramIndexInput,
fileIndexInput fileIndexInput
@ -92,8 +107,8 @@ public:
} }
inline bool FindNearestNodeCoordForLatLon( inline bool FindNearestNodeCoordForLatLon(
const _Coordinate& input_coordinate, const FixedPointCoordinate& input_coordinate,
_Coordinate& result, FixedPointCoordinate& result,
const unsigned zoom_level = 18 const unsigned zoom_level = 18
) const { ) const {
PhantomNode resulting_phantom_node; PhantomNode resulting_phantom_node;
@ -106,7 +121,7 @@ public:
} }
inline bool FindPhantomNodeForCoordinate( inline bool FindPhantomNodeForCoordinate(
const _Coordinate & input_coordinate, const FixedPointCoordinate & input_coordinate,
PhantomNode & resulting_phantom_node, PhantomNode & resulting_phantom_node,
const unsigned zoom_level const unsigned zoom_level
) const { ) const {
@ -123,24 +138,38 @@ public:
private: private:
void LoadNodesAndEdges( void LoadNodesAndEdges(
const std::string & nodes_file, const std::string & nodes_filename,
const std::string & edges_file const std::string & edges_filename
) { ) {
std::ifstream nodes_input_stream(nodes_file.c_str(), std::ios::binary); boost::filesystem::path nodes_file(nodes_filename);
if(!nodes_input_stream) { ERR(nodes_file << " not found"); } if ( !boost::filesystem::exists( nodes_file ) ) {
std::ifstream edges_input_stream(edges_file.c_str(), std::ios::binary); throw OSRMException("nodes file does not exist");
if(!edges_input_stream) { ERR(edges_file << " not found"); } }
if ( 0 == boost::filesystem::file_size( nodes_file ) ) {
throw OSRMException("nodes file is empty");
}
DEBUG("Loading node data"); boost::filesystem::path edges_file(edges_filename);
if ( !boost::filesystem::exists( edges_file ) ) {
throw OSRMException("edges file does not exist");
}
if ( 0 == boost::filesystem::file_size( edges_file ) ) {
throw OSRMException("edges file is empty");
}
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary);
SimpleLogger().Write(logDEBUG) << "Loading node data";
NodeInfo b; NodeInfo b;
while(!nodes_input_stream.eof()) { while(!nodes_input_stream.eof()) {
nodes_input_stream.read((char *)&b, sizeof(NodeInfo)); nodes_input_stream.read((char *)&b, sizeof(NodeInfo));
coordinateVector.push_back(_Coordinate(b.lat, b.lon)); coordinateVector.push_back(FixedPointCoordinate(b.lat, b.lon));
} }
std::vector<_Coordinate>(coordinateVector).swap(coordinateVector); std::vector<FixedPointCoordinate>(coordinateVector).swap(coordinateVector);
nodes_input_stream.close(); nodes_input_stream.close();
DEBUG("Loading edge data"); SimpleLogger().Write(logDEBUG) << "Loading edge data";
unsigned numberOfOrigEdges(0); unsigned numberOfOrigEdges(0);
edges_input_stream.read((char*)&numberOfOrigEdges, sizeof(unsigned)); edges_input_stream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
origEdgeData_viaNode.resize(numberOfOrigEdges); origEdgeData_viaNode.resize(numberOfOrigEdges);
@ -158,11 +187,11 @@ private:
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction; origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
} }
edges_input_stream.close(); edges_input_stream.close();
DEBUG("Loaded " << numberOfOrigEdges << " orig edges"); SimpleLogger().Write(logDEBUG) << "Loaded " << numberOfOrigEdges << " orig edges";
DEBUG("Opening NN indices"); SimpleLogger().Write(logDEBUG) << "Opening NN indices";
} }
std::vector<_Coordinate> coordinateVector; std::vector<FixedPointCoordinate> coordinateVector;
std::vector<NodeID> origEdgeData_viaNode; std::vector<NodeID> origEdgeData_viaNode;
std::vector<unsigned> origEdgeData_nameID; std::vector<unsigned> origEdgeData_nameID;
std::vector<TurnInstruction> origEdgeData_turnInstruction; std::vector<TurnInstruction> origEdgeData_turnInstruction;

View File

@ -24,13 +24,20 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "Coordinate.h" #include "Coordinate.h"
struct PhantomNode { struct PhantomNode {
PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX), ratio(0.) {} PhantomNode() :
edgeBasedNode(UINT_MAX),
nodeBasedEdgeNameID(UINT_MAX),
weight1(INT_MAX),
weight2(INT_MAX),
ratio(0.)
{ }
NodeID edgeBasedNode; NodeID edgeBasedNode;
unsigned nodeBasedEdgeNameID; unsigned nodeBasedEdgeNameID;
int weight1; int weight1;
int weight2; int weight2;
double ratio; double ratio;
_Coordinate location; FixedPointCoordinate location;
void Reset() { void Reset() {
edgeBasedNode = UINT_MAX; edgeBasedNode = UINT_MAX;
nodeBasedEdgeNameID = UINT_MAX; nodeBasedEdgeNameID = UINT_MAX;
@ -88,7 +95,7 @@ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){
struct NodesOfEdge { struct NodesOfEdge {
NodeID edgeBasedNode; NodeID edgeBasedNode;
double ratio; double ratio;
_Coordinate projectedPoint; FixedPointCoordinate projectedPoint;
}; };
#endif /* PHANTOMNODES_H_ */ #endif /* PHANTOMNODES_H_ */

View File

@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef QUERYEDGE_H_ #ifndef QUERYEDGE_H_
#define QUERYEDGE_H_ #define QUERYEDGE_H_
@ -29,7 +27,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <climits> #include <climits>
struct OriginalEdgeData{ struct OriginalEdgeData{
explicit OriginalEdgeData(NodeID v, unsigned n, TurnInstruction t) : viaNode(v), nameID(n), turnInstruction(t) {} explicit OriginalEdgeData(
NodeID viaNode,
unsigned nameID,
TurnInstruction turnInstruction
) : viaNode(viaNode), nameID(nameID), turnInstruction(turnInstruction) {}
OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {} OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {}
NodeID viaNode; NodeID viaNode;
unsigned nameID; unsigned nameID;
@ -46,23 +48,12 @@ struct QueryEdge {
bool forward:1; bool forward:1;
bool backward:1; bool backward:1;
} data; } data;
bool operator<( const QueryEdge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
//sorts by source and other attributes bool operator<( const QueryEdge& right ) const {
static bool CompareBySource( const QueryEdge& left, const QueryEdge& right ) { if ( source != right.source ) {
if ( left.source != right.source ) return source < right.source;
return left.source < right.source; }
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 ); return target < right.target;
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
} }
bool operator== ( const QueryEdge& right ) const { bool operator== ( const QueryEdge& right ) const {

View File

@ -21,33 +21,43 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef _NODE_COORDS_H #ifndef _NODE_COORDS_H
#define _NODE_COORDS_H #define _NODE_COORDS_H
#include "Coordinate.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <cassert> #include <boost/assert.hpp>
#include <cstddef> #include <cstddef>
#include <climits> #include <climits>
#include <limits> #include <limits>
template<typename NodeT> struct NodeInfo {
struct NodeCoords { typedef NodeID key_type; //type of NodeID
typedef unsigned key_type; //type of NodeID
typedef int value_type; //type of lat,lons typedef int value_type; //type of lat,lons
NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {} NodeInfo(int _lat, int _lon, NodeID _id) : lat(_lat), lon(_lon), id(_id) {}
NodeCoords() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {} NodeInfo() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {}
int lat; int lat;
int lon; int lon;
NodeT id; NodeID id;
static NodeCoords<NodeT> min_value() { static NodeInfo min_value() {
return NodeCoords<NodeT>(-90*100000,-180*100000,std::numeric_limits<NodeT>::min()); return NodeInfo(
} -90*COORDINATE_PRECISION,
static NodeCoords<NodeT> max_value() { -180*COORDINATE_PRECISION,
return NodeCoords<NodeT>(90*100000, 180*100000, std::numeric_limits<NodeT>::max()); std::numeric_limits<NodeID>::min()
);
} }
value_type operator[](std::size_t n) const { static NodeInfo max_value() {
return NodeInfo(
90*COORDINATE_PRECISION,
180*COORDINATE_PRECISION,
std::numeric_limits<NodeID>::max()
);
}
value_type operator[](const std::size_t n) const {
switch(n) { switch(n) {
case 1: case 1:
return lat; return lat;
@ -56,15 +66,13 @@ struct NodeCoords {
return lon; return lon;
break; break;
default: default:
assert(false); BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX; return UINT_MAX;
break; break;
} }
assert(false); BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX; return UINT_MAX;
} }
}; };
typedef NodeCoords<NodeID> NodeInfo;
#endif //_NODE_COORDS_H #endif //_NODE_COORDS_H

View File

@ -21,8 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef RAWROUTEDATA_H_ #ifndef RAWROUTEDATA_H_
#define RAWROUTEDATA_H_ #define RAWROUTEDATA_H_
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/PhantomNodes.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <vector>
struct _PathData { struct _PathData {
_PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { } _PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { }
NodeID node; NodeID node;
@ -35,7 +39,7 @@ struct RawRouteData {
std::vector< _PathData > computedShortestPath; std::vector< _PathData > computedShortestPath;
std::vector< _PathData > computedAlternativePath; std::vector< _PathData > computedAlternativePath;
std::vector< PhantomNodes > segmentEndCoordinates; std::vector< PhantomNodes > segmentEndCoordinates;
std::vector< _Coordinate > rawViaNodeCoordinates; std::vector< FixedPointCoordinate > rawViaNodeCoordinates;
unsigned checkSum; unsigned checkSum;
int lengthOfShortestPath; int lengthOfShortestPath;
int lengthOfAlternativePath; int lengthOfAlternativePath;

View File

@ -23,14 +23,16 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef RESTRICTION_H_ #ifndef RESTRICTION_H_
#define RESTRICTION_H_ #define RESTRICTION_H_
#include "../typedefs.h"
#include <climits> #include <climits>
struct _Restriction { struct TurnRestriction {
NodeID viaNode; NodeID viaNode;
NodeID fromNode; NodeID fromNode;
NodeID toNode; NodeID toNode;
struct Bits { //mostly unused struct Bits { //mostly unused
Bits() : Bits()
:
isOnly(false), isOnly(false),
unused1(false), unused1(false),
unused2(false), unused2(false),
@ -38,9 +40,8 @@ struct _Restriction {
unused4(false), unused4(false),
unused5(false), unused5(false),
unused6(false), unused6(false),
unused7(false) { unused7(false)
{ }
}
bool isOnly:1; bool isOnly:1;
bool unused1:1; bool unused1:1;
@ -52,14 +53,14 @@ struct _Restriction {
bool unused7:1; bool unused7:1;
} flags; } flags;
_Restriction(NodeID vn) : TurnRestriction(NodeID viaNode) :
viaNode(vn), viaNode(viaNode),
fromNode(UINT_MAX), fromNode(UINT_MAX),
toNode(UINT_MAX) { toNode(UINT_MAX) {
} }
_Restriction(const bool isOnly = false) : TurnRestriction(const bool isOnly = false) :
viaNode(UINT_MAX), viaNode(UINT_MAX),
fromNode(UINT_MAX), fromNode(UINT_MAX),
toNode(UINT_MAX) { toNode(UINT_MAX) {
@ -68,13 +69,32 @@ struct _Restriction {
}; };
struct _RawRestrictionContainer { struct _RawRestrictionContainer {
_Restriction restriction; TurnRestriction restriction;
EdgeID fromWay; EdgeID fromWay;
EdgeID toWay; EdgeID toWay;
unsigned viaNode; unsigned viaNode;
_RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaNode(vw) { restriction.viaNode = vn;} _RawRestrictionContainer(
_RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaNode(UINT_MAX) { restriction.flags.isOnly = isOnly;} EdgeID fromWay,
EdgeID toWay,
NodeID vn,
unsigned vw
) :
fromWay(fromWay),
toWay(toWay),
viaNode(vw)
{
restriction.viaNode = vn;
}
_RawRestrictionContainer(
bool isOnly = false
) :
fromWay(UINT_MAX),
toWay(UINT_MAX),
viaNode(UINT_MAX)
{
restriction.flags.isOnly = isOnly;
}
static _RawRestrictionContainer min_value() { static _RawRestrictionContainer min_value() {
return _RawRestrictionContainer(0, 0, 0, 0); return _RawRestrictionContainer(0, 0, 0, 0);

View File

@ -33,14 +33,14 @@ SearchEngine::SearchEngine(
void SearchEngine::GetCoordinatesForNodeID( void SearchEngine::GetCoordinatesForNodeID(
NodeID id, NodeID id,
_Coordinate& result FixedPointCoordinate& result
) const { ) const {
result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id); result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id);
result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id); result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id);
} }
void SearchEngine::FindPhantomNodeForCoordinate( void SearchEngine::FindPhantomNodeForCoordinate(
const _Coordinate & location, const FixedPointCoordinate & location,
PhantomNode & result, PhantomNode & result,
const unsigned zoomLevel const unsigned zoomLevel
) const { ) const {

View File

@ -45,17 +45,17 @@ public:
AlternativeRouting<SearchEngineData> alternativePaths; AlternativeRouting<SearchEngineData> alternativePaths;
SearchEngine( SearchEngine(
QueryGraph * g, QueryGraph * g,
NodeInformationHelpDesk * nh, NodeInformationHelpDesk * nh,
std::vector<std::string> & n std::vector<std::string> & n
); );
~SearchEngine(); ~SearchEngine();
void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const; void GetCoordinatesForNodeID(NodeID id, FixedPointCoordinate& result) const;
void FindPhantomNodeForCoordinate( void FindPhantomNodeForCoordinate(
const _Coordinate & location, const FixedPointCoordinate & location,
PhantomNode & result, PhantomNode & result,
unsigned zoomLevel unsigned zoomLevel
) const; ) const;

View File

@ -27,16 +27,16 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <climits> #include <climits>
struct SegmentInformation { struct SegmentInformation {
_Coordinate location; FixedPointCoordinate location;
NodeID nameID; NodeID nameID;
double length; double length;
unsigned duration; unsigned duration;
double bearing; double bearing;
TurnInstruction turnInstruction; TurnInstruction turnInstruction;
bool necessary; bool necessary;
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) : SegmentInformation(const FixedPointCoordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec) {} location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec) {}
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr) : SegmentInformation(const FixedPointCoordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {} location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {}
}; };

View File

@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef STATICGRAPH_H_INCLUDED #ifndef STATICGRAPH_H_INCLUDED
#define STATICGRAPH_H_INCLUDED #define STATICGRAPH_H_INCLUDED
#include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <algorithm> #include <algorithm>
@ -99,12 +100,17 @@ public:
if(data.shortcut) { if(data.shortcut) {
unsigned eid2 = FindEdgeInEitherDirection(u, data.id); unsigned eid2 = FindEdgeInEitherDirection(u, data.id);
if(eid2 == UINT_MAX) { if(eid2 == UINT_MAX) {
DEBUG("cannot find first segment of edge (" << u << "," << data.id << "," << v << ")"); SimpleLogger().Write(logWARNING) <<
"cannot find first segment of edge (" <<
u << "," << data.id << "," << v << ")";
data.shortcut = false; data.shortcut = false;
} }
eid2 = FindEdgeInEitherDirection(data.id, v); eid2 = FindEdgeInEitherDirection(data.id, v);
if(eid2 == UINT_MAX) { if(eid2 == UINT_MAX) {
DEBUG("cannot find second segment of edge (" << u << "," << data.id << "," << v << ")"); SimpleLogger().Write(logWARNING) <<
"cannot find second segment of edge (" <<
u << "," << data.id << "," << v << ")";
data.shortcut = false; data.shortcut = false;
} }
} }

View File

@ -22,16 +22,20 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define STATICRTREE_H_ #define STATICRTREE_H_
#include "MercatorUtil.h" #include "MercatorUtil.h"
#include "TimingUtil.h"
#include "Coordinate.h" #include "Coordinate.h"
#include "PhantomNodes.h" #include "PhantomNodes.h"
#include "DeallocatingVector.h" #include "DeallocatingVector.h"
#include "HilbertValue.h" #include "HilbertValue.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/minmax.hpp> #include <boost/algorithm/minmax.hpp>
#include <boost/algorithm/minmax_element.hpp> #include <boost/algorithm/minmax_element.hpp>
#include <boost/range/algorithm_ext/erase.hpp> #include <boost/range/algorithm_ext/erase.hpp>
@ -43,7 +47,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <climits> #include <climits>
#include <algorithm> #include <algorithm>
#include <fstream>
#include <queue> #include <queue>
#include <string> #include <string>
#include <vector> #include <vector>
@ -54,7 +57,7 @@ const static uint32_t RTREE_LEAF_NODE_SIZE = 1170;
// Implements a static, i.e. packed, R-tree // Implements a static, i.e. packed, R-tree
static boost::thread_specific_ptr<std::ifstream> thread_local_rtree_stream; static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream;
template<class DataT> template<class DataT>
class StaticRTree : boost::noncopyable { class StaticRTree : boost::noncopyable {
@ -97,8 +100,8 @@ private:
max_lat = std::max(max_lat, other.max_lat); max_lat = std::max(max_lat, other.max_lat);
} }
inline _Coordinate Centroid() const { inline FixedPointCoordinate Centroid() const {
_Coordinate centroid; FixedPointCoordinate centroid;
//The coordinates of the midpoints are given by: //The coordinates of the midpoints are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2. //x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (min_lon + max_lon)/2; centroid.lon = (min_lon + max_lon)/2;
@ -107,10 +110,10 @@ private:
} }
inline bool Intersects(const RectangleInt2D & other) const { inline bool Intersects(const RectangleInt2D & other) const {
_Coordinate upper_left (other.max_lat, other.min_lon); FixedPointCoordinate upper_left (other.max_lat, other.min_lon);
_Coordinate upper_right(other.max_lat, other.max_lon); FixedPointCoordinate upper_right(other.max_lat, other.max_lon);
_Coordinate lower_right(other.min_lat, other.max_lon); FixedPointCoordinate lower_right(other.min_lat, other.max_lon);
_Coordinate lower_left (other.min_lat, other.min_lon); FixedPointCoordinate lower_left (other.min_lat, other.min_lon);
return ( return (
Contains(upper_left) Contains(upper_left)
@ -120,7 +123,7 @@ private:
); );
} }
inline double GetMinDist(const _Coordinate & location) const { inline double GetMinDist(const FixedPointCoordinate & location) const {
bool is_contained = Contains(location); bool is_contained = Contains(location);
if (is_contained) { if (is_contained) {
return 0.0; return 0.0;
@ -166,13 +169,13 @@ private:
return min_dist; return min_dist;
} }
inline double GetMinMaxDist(const _Coordinate & location) const { inline double GetMinMaxDist(const FixedPointCoordinate & location) const {
double min_max_dist = DBL_MAX; double min_max_dist = DBL_MAX;
//Get minmax distance to each of the four sides //Get minmax distance to each of the four sides
_Coordinate upper_left (max_lat, min_lon); FixedPointCoordinate upper_left (max_lat, min_lon);
_Coordinate upper_right(max_lat, max_lon); FixedPointCoordinate upper_right(max_lat, max_lon);
_Coordinate lower_right(min_lat, max_lon); FixedPointCoordinate lower_right(min_lat, max_lon);
_Coordinate lower_left (min_lat, min_lon); FixedPointCoordinate lower_left (min_lat, min_lon);
min_max_dist = std::min( min_max_dist = std::min(
min_max_dist, min_max_dist,
@ -208,7 +211,7 @@ private:
return min_max_dist; return min_max_dist;
} }
inline bool Contains(const _Coordinate & location) const { inline bool Contains(const FixedPointCoordinate & location) const {
bool lats_contained = bool lats_contained =
(location.lat > min_lat) && (location.lat < max_lat); (location.lat > min_lat) && (location.lat < max_lat);
bool lons_contained = bool lons_contained =
@ -220,10 +223,10 @@ private:
std::ostream & out, std::ostream & out,
const RectangleInt2D & rect const RectangleInt2D & rect
) { ) {
out << rect.min_lat/100000. << "," out << rect.min_lat/COORDINATE_PRECISION << ","
<< rect.min_lon/100000. << " " << rect.min_lon/COORDINATE_PRECISION << " "
<< rect.max_lat/100000. << "," << rect.max_lat/COORDINATE_PRECISION << ","
<< rect.max_lon/100000.; << rect.max_lon/COORDINATE_PRECISION;
return out; return out;
} }
}; };
@ -287,7 +290,10 @@ public:
: m_element_count(input_data_vector.size()), : m_element_count(input_data_vector.size()),
m_leaf_node_filename(leaf_node_filename) m_leaf_node_filename(leaf_node_filename)
{ {
INFO("constructing r-tree of " << m_element_count << " elements"); SimpleLogger().Write() <<
"constructing r-tree of " << m_element_count <<
" elements";
double time1 = get_timestamp(); double time1 = get_timestamp();
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count); std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
@ -297,15 +303,15 @@ public:
input_wrapper_vector[element_counter].m_array_index = element_counter; input_wrapper_vector[element_counter].m_array_index = element_counter;
//Get Hilbert-Value for centroid in mercartor projection //Get Hilbert-Value for centroid in mercartor projection
DataT & current_element = input_data_vector[element_counter]; DataT & current_element = input_data_vector[element_counter];
_Coordinate current_centroid = current_element.Centroid(); FixedPointCoordinate current_centroid = current_element.Centroid();
current_centroid.lat = 100000*lat2y(current_centroid.lat/100000.); current_centroid.lat = COORDINATE_PRECISION*lat2y(current_centroid.lat/COORDINATE_PRECISION);
uint64_t current_hilbert_value = HilbertCode::GetHilbertNumberForCoordinate(current_centroid); uint64_t current_hilbert_value = HilbertCode::GetHilbertNumberForCoordinate(current_centroid);
input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value; input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value;
} }
//open leaf file //open leaf file
std::ofstream leaf_node_file(leaf_node_filename.c_str(), std::ios::binary); boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t)); leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t));
//sort the hilbert-value representatives //sort the hilbert-value representatives
@ -386,7 +392,11 @@ public:
} }
//open tree file //open tree file
std::ofstream tree_node_file(tree_node_filename.c_str(), std::ios::binary); boost::filesystem::ofstream tree_node_file(
tree_node_filename,
std::ios::binary
);
uint32_t size_of_tree = m_search_tree.size(); uint32_t size_of_tree = m_search_tree.size();
BOOST_ASSERT_MSG(0 < size_of_tree, "tree empty"); BOOST_ASSERT_MSG(0 < size_of_tree, "tree empty");
tree_node_file.write((char *)&size_of_tree, sizeof(uint32_t)); tree_node_file.write((char *)&size_of_tree, sizeof(uint32_t));
@ -394,7 +404,8 @@ public:
//close tree node file. //close tree node file.
tree_node_file.close(); tree_node_file.close();
double time2 = get_timestamp(); double time2 = get_timestamp();
INFO("finished r-tree construction in " << (time2-time1) << " seconds"); SimpleLogger().Write() <<
"finished r-tree construction in " << (time2-time1) << " seconds";
} }
//Read-only operation for queries //Read-only operation for queries
@ -403,25 +414,42 @@ public:
const std::string & leaf_filename const std::string & leaf_filename
) : m_leaf_node_filename(leaf_filename) { ) : m_leaf_node_filename(leaf_filename) {
//open tree node file and load into RAM. //open tree node file and load into RAM.
std::ifstream tree_node_file(node_filename.c_str(), std::ios::binary); boost::filesystem::path node_file(node_filename);
if ( !boost::filesystem::exists( node_file ) ) {
throw OSRMException("ram index file does not exist");
}
if ( 0 == boost::filesystem::file_size( node_file ) ) {
throw OSRMException("ram index file is empty");
}
boost::filesystem::ifstream tree_node_file( node_file, std::ios::binary );
uint32_t tree_size = 0; uint32_t tree_size = 0;
tree_node_file.read((char*)&tree_size, sizeof(uint32_t)); tree_node_file.read((char*)&tree_size, sizeof(uint32_t));
//INFO("reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes"); //SimpleLogger().Write() << "reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes";
m_search_tree.resize(tree_size); m_search_tree.resize(tree_size);
tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size); tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size);
tree_node_file.close(); tree_node_file.close();
//open leaf node file and store thread specific pointer //open leaf node file and store thread specific pointer
std::ifstream leaf_node_file(leaf_filename.c_str(), std::ios::binary); boost::filesystem::path leaf_file(leaf_filename);
if ( !boost::filesystem::exists( leaf_file ) ) {
throw OSRMException("mem index file does not exist");
}
if ( 0 == boost::filesystem::file_size( leaf_file ) ) {
throw OSRMException("mem index file is empty");
}
boost::filesystem::ifstream leaf_node_file( leaf_file, std::ios::binary );
leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t)); leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t));
leaf_node_file.close(); leaf_node_file.close();
//INFO( tree_size << " nodes in search tree"); //SimpleLogger().Write() << tree_size << " nodes in search tree";
//INFO( m_element_count << " elements in leafs"); //SimpleLogger().Write() << m_element_count << " elements in leafs";
} }
/* /*
inline void FindKNearestPhantomNodesForCoordinate( inline void FindKNearestPhantomNodesForCoordinate(
const _Coordinate & location, const FixedPointCoordinate & location,
const unsigned zoom_level, const unsigned zoom_level,
const unsigned candidate_count, const unsigned candidate_count,
std::vector<std::pair<PhantomNode, double> > & result_vector std::vector<std::pair<PhantomNode, double> > & result_vector
@ -432,12 +460,12 @@ public:
uint32_t io_count = 0; uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0; uint32_t explored_tree_nodes_count = 0;
INFO("searching for coordinate " << input_coordinate); SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
double min_dist = DBL_MAX; double min_dist = DBL_MAX;
double min_max_dist = DBL_MAX; double min_max_dist = DBL_MAX;
bool found_a_nearest_edge = false; bool found_a_nearest_edge = false;
_Coordinate nearest, current_start_coordinate, current_end_coordinate; FixedPointCoordinate nearest, current_start_coordinate, current_end_coordinate;
//initialize queue with root element //initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue; std::priority_queue<QueryCandidate> traversal_queue;
@ -465,8 +493,8 @@ public:
double current_ratio = 0.; double current_ratio = 0.;
double current_perpendicular_distance = ComputePerpendicularDistance( double current_perpendicular_distance = ComputePerpendicularDistance(
input_coordinate, input_coordinate,
_Coordinate(current_edge.lat1, current_edge.lon1), FixedPointCoordinate(current_edge.lat1, current_edge.lon1),
_Coordinate(current_edge.lat2, current_edge.lon2), FixedPointCoordinate(current_edge.lat2, current_edge.lon2),
nearest, nearest,
&current_ratio &current_ratio
); );
@ -495,11 +523,11 @@ public:
1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode )
&& CoordinatesAreEquivalent( && CoordinatesAreEquivalent(
current_start_coordinate, current_start_coordinate,
_Coordinate( FixedPointCoordinate(
current_edge.lat1, current_edge.lat1,
current_edge.lon1 current_edge.lon1
), ),
_Coordinate( FixedPointCoordinate(
current_edge.lat2, current_edge.lat2,
current_edge.lon2 current_edge.lon2
), ),
@ -535,14 +563,14 @@ public:
const double distance_to_edge = const double distance_to_edge =
ApproximateDistance ( ApproximateDistance (
_Coordinate(nearest_edge.lat1, nearest_edge.lon1), FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
result_phantom_node.location result_phantom_node.location
); );
const double length_of_edge = const double length_of_edge =
ApproximateDistance( ApproximateDistance(
_Coordinate(nearest_edge.lat1, nearest_edge.lon1), FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
_Coordinate(nearest_edge.lat2, nearest_edge.lon2) FixedPointCoordinate(nearest_edge.lat2, nearest_edge.lon2)
); );
const double ratio = (found_a_nearest_edge ? const double ratio = (found_a_nearest_edge ?
@ -561,14 +589,14 @@ public:
result_phantom_node.location.lat = input_coordinate.lat; result_phantom_node.location.lat = input_coordinate.lat;
} }
INFO("mindist: " << min_distphantom_node.isBidirected() ? "yes" : "no") ); SimpleLogger().Write() << "mindist: " << min_distphantom_node.isBidirected() ? "yes" : "no");
return found_a_nearest_edge; return found_a_nearest_edge;
} }
*/ */
bool FindPhantomNodeForCoordinate( bool FindPhantomNodeForCoordinate(
const _Coordinate & input_coordinate, const FixedPointCoordinate & input_coordinate,
PhantomNode & result_phantom_node, PhantomNode & result_phantom_node,
const unsigned zoom_level const unsigned zoom_level
) { ) {
@ -578,12 +606,12 @@ public:
uint32_t io_count = 0; uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0; uint32_t explored_tree_nodes_count = 0;
//INFO("searching for coordinate " << input_coordinate); //SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
double min_dist = DBL_MAX; double min_dist = DBL_MAX;
double min_max_dist = DBL_MAX; double min_max_dist = DBL_MAX;
bool found_a_nearest_edge = false; bool found_a_nearest_edge = false;
_Coordinate nearest, current_start_coordinate, current_end_coordinate; FixedPointCoordinate nearest, current_start_coordinate, current_end_coordinate;
//initialize queue with root element //initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue; std::priority_queue<QueryCandidate> traversal_queue;
@ -609,7 +637,7 @@ public:
LeafNode current_leaf_node; LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node); LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
++io_count; ++io_count;
//INFO("checking " << current_leaf_node.object_count << " elements"); //SimpleLogger().Write() << "checking " << current_leaf_node.object_count << " elements";
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) { for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT & current_edge = current_leaf_node.objects[i]; DataT & current_edge = current_leaf_node.objects[i];
if(ignore_tiny_components && current_edge.belongsToTinyComponent) { if(ignore_tiny_components && current_edge.belongsToTinyComponent) {
@ -622,8 +650,8 @@ public:
double current_ratio = 0.; double current_ratio = 0.;
double current_perpendicular_distance = ComputePerpendicularDistance( double current_perpendicular_distance = ComputePerpendicularDistance(
input_coordinate, input_coordinate,
_Coordinate(current_edge.lat1, current_edge.lon1), FixedPointCoordinate(current_edge.lat1, current_edge.lon1),
_Coordinate(current_edge.lat2, current_edge.lon2), FixedPointCoordinate(current_edge.lat2, current_edge.lon2),
nearest, nearest,
&current_ratio &current_ratio
); );
@ -652,11 +680,11 @@ public:
1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode )
&& CoordinatesAreEquivalent( && CoordinatesAreEquivalent(
current_start_coordinate, current_start_coordinate,
_Coordinate( FixedPointCoordinate(
current_edge.lat1, current_edge.lat1,
current_edge.lon1 current_edge.lon1
), ),
_Coordinate( FixedPointCoordinate(
current_edge.lat2, current_edge.lat2,
current_edge.lon2 current_edge.lon2
), ),
@ -664,15 +692,15 @@ public:
) )
) { ) {
BOOST_ASSERT_MSG(current_edge.id != result_phantom_node.edgeBasedNode, "IDs not different"); BOOST_ASSERT_MSG(current_edge.id != result_phantom_node.edgeBasedNode, "IDs not different");
//INFO("found bidirected edge on nodes " << current_edge.id << " and " << result_phantom_node.edgeBasedNode); //SimpleLogger().Write() << "found bidirected edge on nodes " << current_edge.id << " and " << result_phantom_node.edgeBasedNode;
result_phantom_node.weight2 = current_edge.weight; result_phantom_node.weight2 = current_edge.weight;
if(current_edge.id < result_phantom_node.edgeBasedNode) { if(current_edge.id < result_phantom_node.edgeBasedNode) {
result_phantom_node.edgeBasedNode = current_edge.id; result_phantom_node.edgeBasedNode = current_edge.id;
std::swap(result_phantom_node.weight1, result_phantom_node.weight2); std::swap(result_phantom_node.weight1, result_phantom_node.weight2);
std::swap(current_end_coordinate, current_start_coordinate); std::swap(current_end_coordinate, current_start_coordinate);
// INFO("case 2"); // SimpleLogger().Write() <<"case 2";
} }
//INFO("w1: " << result_phantom_node.weight1 << ", w2: " << result_phantom_node.weight2); //SimpleLogger().Write() << "w1: " << result_phantom_node.weight1 << ", w2: " << result_phantom_node.weight2;
} }
} }
} else { } else {
@ -724,15 +752,15 @@ private:
inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode& result_node) { inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode& result_node) {
if(!thread_local_rtree_stream.get() || !thread_local_rtree_stream->is_open()) { if(!thread_local_rtree_stream.get() || !thread_local_rtree_stream->is_open()) {
thread_local_rtree_stream.reset( thread_local_rtree_stream.reset(
new std::ifstream( new boost::filesystem::ifstream(
m_leaf_node_filename.c_str(), m_leaf_node_filename,
std::ios::in | std::ios::binary std::ios::in | std::ios::binary
) )
); );
} }
if(!thread_local_rtree_stream->good()) { if(!thread_local_rtree_stream->good()) {
thread_local_rtree_stream->clear(std::ios::goodbit); thread_local_rtree_stream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream"); SimpleLogger().Write(logDEBUG) << "Resetting stale filestream";
} }
uint64_t seek_pos = sizeof(uint64_t) + leaf_id*sizeof(LeafNode); uint64_t seek_pos = sizeof(uint64_t) + leaf_id*sizeof(LeafNode);
thread_local_rtree_stream->seekg(seek_pos); thread_local_rtree_stream->seekg(seek_pos);
@ -740,10 +768,10 @@ private:
} }
inline double ComputePerpendicularDistance( inline double ComputePerpendicularDistance(
const _Coordinate& inputPoint, const FixedPointCoordinate& inputPoint,
const _Coordinate& source, const FixedPointCoordinate& source,
const _Coordinate& target, const FixedPointCoordinate& target,
_Coordinate& nearest, double *r) const { FixedPointCoordinate& nearest, double *r) const {
const double x = static_cast<double>(inputPoint.lat); const double x = static_cast<double>(inputPoint.lat);
const double y = static_cast<double>(inputPoint.lon); const double y = static_cast<double>(inputPoint.lon);
const double a = static_cast<double>(source.lat); const double a = static_cast<double>(source.lat);
@ -787,7 +815,7 @@ private:
return (p-x)*(p-x) + (q-y)*(q-y); return (p-x)*(p-x) + (q-y)*(q-y);
} }
inline bool CoordinatesAreEquivalent(const _Coordinate & a, const _Coordinate & b, const _Coordinate & c, const _Coordinate & d) const { inline bool CoordinatesAreEquivalent(const FixedPointCoordinate & a, const FixedPointCoordinate & b, const FixedPointCoordinate & c, const FixedPointCoordinate & d) const {
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c); return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
} }

View File

@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/PhantomNodes.h" #include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngine.h" #include "../DataStructures/SearchEngine.h"
#include "../Plugins/RawRouteData.h" #include "../Server/BasicDatastructures.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h" #include "../typedefs.h"

View File

@ -32,11 +32,14 @@ inline double DescriptionFactory::RadianToDegree(const double radian) const {
return radian * (180/M_PI); return radian * (180/M_PI);
} }
double DescriptionFactory::GetBearing(const _Coordinate& A, const _Coordinate& B) const { double DescriptionFactory::GetBearing(
double deltaLong = DegreeToRadian(B.lon/100000. - A.lon/100000.); const FixedPointCoordinate & A,
const FixedPointCoordinate & B
) const {
double deltaLong = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
double lat1 = DegreeToRadian(A.lat/100000.); double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION);
double lat2 = DegreeToRadian(B.lat/100000.); double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION);
double y = sin(deltaLong) * cos(lat2); double y = sin(deltaLong) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong); double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong);
@ -59,7 +62,7 @@ void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) {
pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) ); pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) );
} }
void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) { void DescriptionFactory::AppendSegment(const FixedPointCoordinate & coordinate, const _PathData & data ) {
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) { if(1 == pathDescription.size() && pathDescription.back().location == coordinate) {
pathDescription.back().nameID = data.nameID; pathDescription.back().nameID = data.nameID;
} else { } else {
@ -123,7 +126,7 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
// || std::string::npos != string0.find(string1+" ;") // || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1) // || std::string::npos != string0.find("; "+string1)
// ){ // ){
// INFO("->next correct: " << string0 << " contains " << string1); // SimpleLogger().Write() << "->next correct: " << string0 << " contains " << string1;
// for(; lastTurn != i; ++lastTurn) // for(; lastTurn != i; ++lastTurn)
// pathDescription[lastTurn].nameID = pathDescription[i].nameID; // pathDescription[lastTurn].nameID = pathDescription[i].nameID;
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; // pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
@ -132,7 +135,7 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
// || std::string::npos != string1.find(string0+" ;") // || std::string::npos != string1.find(string0+" ;")
// || std::string::npos != string1.find("; "+string0) // || std::string::npos != string1.find("; "+string0)
// ){ // ){
// INFO("->prev correct: " << string1 << " contains " << string0); // SimpleLogger().Write() << "->prev correct: " << string1 << " contains " << string0;
// pathDescription[i].nameID = pathDescription[i-1].nameID; // pathDescription[i].nameID = pathDescription[i-1].nameID;
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; // pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
// } // }
@ -153,24 +156,24 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
if(TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) { if(TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
//INFO("Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID); //SimpleLogger().Write() << "Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID;
assert(pathDescription[i].necessary); assert(pathDescription[i].necessary);
lengthOfSegment = 0; lengthOfSegment = 0;
durationOfSegment = 0; durationOfSegment = 0;
indexOfSegmentBegin = i; indexOfSegmentBegin = i;
} }
} }
// INFO("#segs: " << pathDescription.size()); // SimpleLogger().Write() << "#segs: " << pathDescription.size();
//Post-processing to remove empty or nearly empty path segments //Post-processing to remove empty or nearly empty path segments
if(FLT_EPSILON > pathDescription.back().length) { if(FLT_EPSILON > pathDescription.back().length) {
// INFO("#segs: " << pathDescription.size() << ", last ratio: " << targetPhantom.ratio << ", length: " << pathDescription.back().length); // SimpleLogger().Write() << "#segs: " << pathDescription.size() << ", last ratio: " << targetPhantom.ratio << ", length: " << pathDescription.back().length;
if(pathDescription.size() > 2){ if(pathDescription.size() > 2){
pathDescription.pop_back(); pathDescription.pop_back();
pathDescription.back().necessary = true; pathDescription.back().necessary = true;
pathDescription.back().turnInstruction = TurnInstructions.NoTurn; pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID; targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
// INFO("Deleting last turn instruction"); // SimpleLogger().Write() << "Deleting last turn instruction";
} }
} else { } else {
pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio); pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio);
@ -182,7 +185,7 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
pathDescription[0].turnInstruction = TurnInstructions.HeadOn; pathDescription[0].turnInstruction = TurnInstructions.HeadOn;
pathDescription[0].necessary = true; pathDescription[0].necessary = true;
startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID; startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
// INFO("Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length); // SimpleLogger().Write() << "Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length;
} }
} else { } else {
pathDescription[0].duration *= startPhantom.ratio; pathDescription[0].duration *= startPhantom.ratio;

View File

@ -27,6 +27,7 @@
#include "../DataStructures/SearchEngine.h" #include "../DataStructures/SearchEngine.h"
#include "../DataStructures/SegmentInformation.h" #include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <vector> #include <vector>
@ -62,10 +63,10 @@ public:
std::vector <SegmentInformation> pathDescription; std::vector <SegmentInformation> pathDescription;
DescriptionFactory(); DescriptionFactory();
virtual ~DescriptionFactory(); virtual ~DescriptionFactory();
double GetBearing(const _Coordinate& C, const _Coordinate& B) const; double GetBearing(const FixedPointCoordinate& C, const FixedPointCoordinate& B) const;
void AppendEncodedPolylineString(std::string &output); void AppendEncodedPolylineString(std::string &output);
void AppendUnencodedPolylineString(std::string &output); void AppendUnencodedPolylineString(std::string &output);
void AppendSegment(const _Coordinate & coordinate, const _PathData & data); void AppendSegment(const FixedPointCoordinate & coordinate, const _PathData & data);
void BuildRouteSummary(const double distance, const unsigned time); void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode & startPhantom); void SetStartSegment(const PhantomNode & startPhantom);
void SetEndSegment(const PhantomNode & startPhantom); void SetEndSegment(const PhantomNode & startPhantom);

View File

@ -28,7 +28,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
class GPXDescriptor : public BaseDescriptor{ class GPXDescriptor : public BaseDescriptor{
private: private:
_DescriptorConfig config; _DescriptorConfig config;
_Coordinate current; FixedPointCoordinate current;
std::string tmp; std::string tmp;
public: public:

View File

@ -39,7 +39,7 @@ private:
_DescriptorConfig config; _DescriptorConfig config;
DescriptionFactory descriptionFactory; DescriptionFactory descriptionFactory;
DescriptionFactory alternateDescriptionFactory; DescriptionFactory alternateDescriptionFactory;
_Coordinate current; FixedPointCoordinate current;
unsigned numberOfEnteredRestrictedAreas; unsigned numberOfEnteredRestrictedAreas;
struct RoundAbout{ struct RoundAbout{
RoundAbout() : RoundAbout() :

View File

@ -29,38 +29,34 @@ extractor_callbacks(ec), scriptingEnvironment(se), luaState(NULL), use_turn_rest
void BaseParser::ReadUseRestrictionsSetting() { void BaseParser::ReadUseRestrictionsSetting() {
if( 0 != luaL_dostring( luaState, "return use_turn_restrictions\n") ) { if( 0 != luaL_dostring( luaState, "return use_turn_restrictions\n") ) {
ERR(lua_tostring( luaState,-1)<< " occured in scripting block"); throw OSRMException(
/*lua_tostring( luaState, -1 ) + */"ERROR occured in scripting block"
);
} }
if( lua_isboolean( luaState, -1) ) { if( lua_isboolean( luaState, -1) ) {
use_turn_restrictions = lua_toboolean(luaState, -1); use_turn_restrictions = lua_toboolean(luaState, -1);
} }
if( use_turn_restrictions ) { if( use_turn_restrictions ) {
INFO("Using turn restrictions" ); SimpleLogger().Write() << "Using turn restrictions";
} else { } else {
INFO("Ignoring turn restrictions" ); SimpleLogger().Write() << "Ignoring turn restrictions";
} }
} }
void BaseParser::ReadRestrictionExceptions() { void BaseParser::ReadRestrictionExceptions() {
if(lua_function_exists(luaState, "get_exceptions" )) { if(lua_function_exists(luaState, "get_exceptions" )) {
//get list of turn restriction exceptions //get list of turn restriction exceptions
try { luabind::call_function<void>(
luabind::call_function<void>( luaState,
luaState, "get_exceptions",
"get_exceptions", boost::ref(restriction_exceptions)
boost::ref(restriction_exceptions) );
); SimpleLogger().Write() << "Found " << restriction_exceptions.size() << " exceptions to turn restriction";
INFO("Found " << restriction_exceptions.size() << " exceptions to turn restriction"); BOOST_FOREACH(const std::string & str, restriction_exceptions) {
BOOST_FOREACH(std::string & str, restriction_exceptions) { SimpleLogger().Write() << " " << str;
INFO(" " << str);
}
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
} }
} else { } else {
INFO("Found no exceptions to turn restrictions"); SimpleLogger().Write() << "Found no exceptions to turn restrictions";
} }
} }
@ -72,37 +68,25 @@ void BaseParser::report_errors(lua_State *L, const int status) const {
} }
void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* localLuaState) { void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* localLuaState) {
try { luabind::call_function<void>( localLuaState, "node_function", boost::ref(n) );
luabind::call_function<void>( localLuaState, "node_function", boost::ref(n) );
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
} }
void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) { void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) {
if(2 > w.path.size()) { if(2 > w.path.size()) {
return; return;
} }
try { luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) );
luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) );
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
} }
bool BaseParser::ShouldIgnoreRestriction(const std::string& except_tag_string) const { bool BaseParser::ShouldIgnoreRestriction(const std::string& except_tag_string) const {
//should this restriction be ignored? yes if there's an overlap between: //should this restriction be ignored? yes if there's an overlap between:
//a) the list of modes in the except tag of the restriction (except_tag_string), ex: except=bus;bicycle //a) the list of modes in the except tag of the restriction (except_tag_string), ex: except=bus;bicycle
//b) the lua profile defines a hierachy of modes, ex: [access, vehicle, bicycle] //b) the lua profile defines a hierachy of modes, ex: [access, vehicle, bicycle]
if( "" == except_tag_string ) { if( "" == except_tag_string ) {
return false; return false;
} }
//Be warned, this is quadratic work here, but we assume that //Be warned, this is quadratic work here, but we assume that
//only a few exceptions are actually defined. //only a few exceptions are actually defined.
std::vector<std::string> exceptions; std::vector<std::string> exceptions;

View File

@ -23,6 +23,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "ExtractorCallbacks.h" #include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h" #include "ScriptingEnvironment.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
extern "C" { extern "C" {
#include <lua.h> #include <lua.h>

View File

@ -117,7 +117,7 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
++restrictionsIT; ++restrictionsIT;
} }
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
INFO("usable restrictions: " << usableRestrictionsCounter ); SimpleLogger().Write() << "usable restrictions: " << usableRestrictionsCounter;
//serialize restrictions //serialize restrictions
std::ofstream restrictionsOutstream; std::ofstream restrictionsOutstream;
restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary); restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary);
@ -125,7 +125,7 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned)); restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) { for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) {
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) { if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(_Restriction)); restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(TurnRestriction));
} }
} }
restrictionsOutstream.close(); restrictionsOutstream.close();
@ -298,7 +298,7 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
// addressOutFile.close(); // addressOutFile.close();
// cout << "ok, after " << get_timestamp() - time << "s" << endl; // cout << "ok, after " << get_timestamp() - time << "s" << endl;
INFO("Processed " << usedNodeCounter << " nodes and " << usedEdgeCounter << " edges"); SimpleLogger().Write() << "Processed " << usedNodeCounter << " nodes and " << usedEdgeCounter << " edges";
} catch ( const std::exception& e ) { } catch ( const std::exception& e ) {

View File

@ -22,7 +22,8 @@
#define EXTRACTIONCONTAINERS_H_ #define EXTRACTIONCONTAINERS_H_
#include "ExtractorStructs.h" #include "ExtractorStructs.h"
#include "../DataStructures/TimingUtil.h" #include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include "../Util/UUID.h" #include "../Util/UUID.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@ -39,14 +40,10 @@ public:
ExtractionContainers() { ExtractionContainers() {
//Check if another instance of stxxl is already running or if there is a general problem //Check if another instance of stxxl is already running or if there is a general problem
try { stxxl::vector<unsigned> testForRunningInstance;
stxxl::vector<unsigned> testForRunningInstance;
} catch(std::exception & e) {
ERR("Could not instantiate STXXL layer." << std::endl << e.what());
}
nameVector.push_back(""); nameVector.push_back("");
} }
virtual ~ExtractionContainers() { virtual ~ExtractionContainers() {
usedNodeIDs.clear(); usedNodeIDs.clear();
allNodes.clear(); allNodes.clear();

View File

@ -31,7 +31,7 @@ ExtractorCallbacks::~ExtractorCallbacks() { }
/** warning: caller needs to take care of synchronization! */ /** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::nodeFunction(const _Node &n) { void ExtractorCallbacks::nodeFunction(const _Node &n) {
if(n.lat <= 85*100000 && n.lat >= -85*100000) { if(n.lat <= 85*COORDINATE_PRECISION && n.lat >= -85*COORDINATE_PRECISION) {
externalMemory->allNodes.push_back(n); externalMemory->allNodes.push_back(n);
} }
} }
@ -45,7 +45,9 @@ bool ExtractorCallbacks::restrictionFunction(const _RawRestrictionContainer &r)
void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) { void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
if((0 < parsed_way.speed) || (0 < parsed_way.duration)) { //Only true if the way is specified by the speed profile if((0 < parsed_way.speed) || (0 < parsed_way.duration)) { //Only true if the way is specified by the speed profile
if(UINT_MAX == parsed_way.id){ if(UINT_MAX == parsed_way.id){
DEBUG("found bogus way with id: " << parsed_way.id << " of size " << parsed_way.path.size()); SimpleLogger().Write(logDEBUG) <<
"found bogus way with id: " << parsed_way.id <<
" of size " << parsed_way.path.size();
return; return;
} }
@ -55,7 +57,8 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
} }
if(FLT_EPSILON >= fabs(-1. - parsed_way.speed)){ if(FLT_EPSILON >= fabs(-1. - parsed_way.speed)){
DEBUG("found way with bogus speed, id: " << parsed_way.id); SimpleLogger().Write(logDEBUG) <<
"found way with bogus speed, id: " << parsed_way.id;
return; return;
} }

View File

@ -21,8 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef EXTRACTORCALLBACKS_H_ #ifndef EXTRACTORCALLBACKS_H_
#define EXTRACTORCALLBACKS_H_ #define EXTRACTORCALLBACKS_H_
#include <string> #include "ExtractionContainers.h"
#include <vector> #include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h"
#include "../DataStructures/Coordinate.h"
#include <cfloat> #include <cfloat>
@ -30,9 +33,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <boost/algorithm/string/regex.hpp> #include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include "ExtractionContainers.h" #include <string>
#include "ExtractionHelperFunctions.h" #include <vector>
#include "ExtractorStructs.h"
class ExtractorCallbacks{ class ExtractorCallbacks{
private: private:

View File

@ -21,13 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef EXTRACTORSTRUCTS_H_ #ifndef EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_ #define EXTRACTORSTRUCTS_H_
#include "../DataStructures/Coordinate.h" #include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h" #include "../DataStructures/ImportNode.h"
#include "../DataStructures/NodeCoords.h" #include "../DataStructures/QueryNode.h"
#include "../DataStructures/Restriction.h" #include "../DataStructures/Restriction.h"
#include "../DataStructures/TimingUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@ -50,7 +48,7 @@ struct ExtractionWay {
id = UINT_MAX; id = UINT_MAX;
nameID = UINT_MAX; nameID = UINT_MAX;
path.clear(); path.clear();
keyVals.EraseAll(); keyVals.clear();
direction = ExtractionWay::notSure; direction = ExtractionWay::notSure;
speed = -1; speed = -1;
backward_speed = -1; backward_speed = -1;
@ -111,8 +109,8 @@ struct InternalExtractorEdge {
bool isAccessRestricted; bool isAccessRestricted;
bool isContraFlow; bool isContraFlow;
_Coordinate startCoord; FixedPointCoordinate startCoord;
_Coordinate targetCoord; FixedPointCoordinate targetCoord;
static InternalExtractorEdge min_value() { static InternalExtractorEdge min_value() {
return InternalExtractorEdge(0,0); return InternalExtractorEdge(0,0);

View File

@ -28,7 +28,7 @@ PBFParser::PBFParser(const char * fileName, ExtractorCallbacks* ec, ScriptingEnv
input.open(fileName, std::ios::in | std::ios::binary); input.open(fileName, std::ios::in | std::ios::binary);
if (!input) { if (!input) {
std::cerr << fileName << ": File not found." << std::endl; throw OSRMException("pbf file not found.");
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -50,7 +50,10 @@ PBFParser::~PBFParser() {
google::protobuf::ShutdownProtobufLibrary(); google::protobuf::ShutdownProtobufLibrary();
#ifndef NDEBUG #ifndef NDEBUG
DEBUG("parsed " << blockCount << " blocks from pbf with " << groupCount << " groups"); SimpleLogger().Write(logDEBUG) <<
"parsed " << blockCount <<
" blocks from pbf with " << groupCount <<
" groups";
#endif #endif
} }
@ -108,7 +111,7 @@ inline void PBFParser::ParseData() {
_ThreadData *threadData; _ThreadData *threadData;
threadDataQueue->wait_and_pop(threadData); threadDataQueue->wait_and_pop(threadData);
if( NULL==threadData ) { if( NULL==threadData ) {
INFO("Parse Data Thread Finished"); SimpleLogger().Write() << "Parse Data Thread Finished";
threadDataQueue->push(NULL); // Signal end of data for other threads threadDataQueue->push(NULL); // Signal end of data for other threads
break; break;
} }
@ -166,8 +169,8 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
m_lastDenseLatitude += dense.lat( i ); m_lastDenseLatitude += dense.lat( i );
m_lastDenseLongitude += dense.lon( i ); m_lastDenseLongitude += dense.lon( i );
extracted_nodes_vector[i].id = m_lastDenseID; extracted_nodes_vector[i].id = m_lastDenseID;
extracted_nodes_vector[i].lat = 100000*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lat_offset() ) / NANO; extracted_nodes_vector[i].lat = COORDINATE_PRECISION*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lat_offset() ) / NANO;
extracted_nodes_vector[i].lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO; extracted_nodes_vector[i].lon = COORDINATE_PRECISION*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
while (denseTagIndex < dense.keys_vals_size()) { while (denseTagIndex < dense.keys_vals_size()) {
const int tagValue = dense.keys_vals( denseTagIndex ); const int tagValue = dense.keys_vals( denseTagIndex );
if( 0==tagValue ) { if( 0==tagValue ) {
@ -177,7 +180,7 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
const int keyValue = dense.keys_vals ( denseTagIndex+1 ); const int keyValue = dense.keys_vals ( denseTagIndex+1 );
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data(); const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data(); const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
extracted_nodes_vector[i].keyVals.Add(key, value); extracted_nodes_vector[i].keyVals.insert(std::make_pair(key, value));
denseTagIndex += 2; denseTagIndex += 2;
} }
} }
@ -194,7 +197,9 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
} }
inline void PBFParser::parseNode(_ThreadData * ) { inline void PBFParser::parseNode(_ThreadData * ) {
ERR("Parsing of simple nodes not supported. PBF should use dense nodes"); throw OSRMException(
"Parsing of simple nodes not supported. PBF should use dense nodes"
);
} }
inline void PBFParser::parseRelation(_ThreadData * threadData) { inline void PBFParser::parseRelation(_ThreadData * threadData) {
@ -304,7 +309,7 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
for(int j = 0; j < number_of_keys; ++j) { for(int j = 0; j < number_of_keys; ++j) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j)); const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j)); const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j));
parsed_way_vector[i].keyVals.Add(key, val); parsed_way_vector[i].keyVals.insert(std::make_pair(key, val));
} }
} }
@ -475,7 +480,7 @@ bool PBFParser::readNextBlock(std::fstream& stream, _ThreadData * threadData) {
} }
if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) { if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) {
ERR("failed to parse PrimitiveBlock"); std::cerr << "failed to parse PrimitiveBlock" << std::endl;
return false; return false;
} }
return true; return true;

View File

@ -23,10 +23,13 @@
#include "BaseParser.h" #include "BaseParser.h"
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ConcurrentQueue.h" #include "../DataStructures/ConcurrentQueue.h"
#include "../Util/MachineInfo.h" #include "../Util/MachineInfo.h"
#include "../Util/OpenMPWrapper.h" #include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>

View File

@ -22,11 +22,12 @@
ScriptingEnvironment::ScriptingEnvironment() {} ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
INFO("Using script " << fileName); SimpleLogger().Write() << "Using script " << fileName;
// Create a new lua state // Create a new lua state
for(int i = 0; i < omp_get_max_threads(); ++i) for(int i = 0; i < omp_get_max_threads(); ++i) {
luaStateVector.push_back(luaL_newstate()); luaStateVector.push_back(luaL_newstate());
}
// Connect LuaBind to this lua state for all threads // Connect LuaBind to this lua state for all threads
#pragma omp parallel #pragma omp parallel
@ -40,59 +41,59 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
// Add our function to the state's global scope // Add our function to the state's global scope
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::def("print", LUA_print<std::string>), luabind::def("print", LUA_print<std::string>),
luabind::def("parseMaxspeed", parseMaxspeed), luabind::def("parseMaxspeed", parseMaxspeed),
luabind::def("durationIsValid", durationIsValid), luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration) luabind::def("parseDuration", parseDuration)
]; ];
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<HashTable<std::string, std::string> >("keyVals") luabind::class_<HashTable<std::string, std::string> >("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add) .def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find) .def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds) .def("Holds", &HashTable<std::string, std::string>::Holds)
]; ];
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<ImportNode>("Node") luabind::class_<ImportNode>("Node")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat) .def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon) .def_readwrite("lon", &ImportNode::lon)
.def_readwrite("id", &ImportNode::id) .def_readwrite("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard) .def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight) .def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals) .def_readwrite("tags", &ImportNode::keyVals)
]; ];
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<ExtractionWay>("Way") luabind::class_<ExtractionWay>("Way")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
.def_readwrite("name", &ExtractionWay::name) .def_readwrite("name", &ExtractionWay::name)
.def_readwrite("speed", &ExtractionWay::speed) .def_readwrite("speed", &ExtractionWay::speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed) .def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration) .def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("type", &ExtractionWay::type) .def_readwrite("type", &ExtractionWay::type)
.def_readwrite("access", &ExtractionWay::access) .def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout) .def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted) .def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid) .def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals) .def_readwrite("tags", &ExtractionWay::keyVals)
.def_readwrite("direction", &ExtractionWay::direction) .def_readwrite("direction", &ExtractionWay::direction)
.enum_("constants") .enum_("constants") [
[ luabind::value("notSure", 0),
luabind::value("notSure", 0), luabind::value("oneway", 1),
luabind::value("oneway", 1), luabind::value("bidirectional", 2),
luabind::value("bidirectional", 2), luabind::value("opposite", 3)
luabind::value("opposite", 3) ]
] ];
];
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<std::vector<std::string> >("vector") luabind::class_<std::vector<std::string> >("vector")
.def("Add", &std::vector<std::string>::push_back) .def("Add", &std::vector<std::string>::push_back)
]; ];
if(0 != luaL_dofile(myLuaState, fileName) ) { if(0 != luaL_dofile(myLuaState, fileName) ) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block"); throw OSRMException("ERROR occured in scripting block");
} }
} }
} }

View File

@ -26,6 +26,8 @@
#include "../DataStructures/ImportNode.h" #include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h" #include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h" #include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <vector> #include <vector>

View File

@ -27,7 +27,9 @@
#include <boost/ref.hpp> #include <boost/ref.hpp>
XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) { XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) {
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf"); SimpleLogger().Write(logWARNING) <<
"Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf";
inputReader = inputReaderFactory(filename); inputReader = inputReaderFactory(filename);
} }
@ -217,12 +219,12 @@ ImportNode XMLParser::_ReadXMLNode() {
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" ); xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
if ( attribute != NULL ) { if ( attribute != NULL ) {
node.lat = static_cast<NodeID>(100000.*atof(( const char* ) attribute ) ); node.lat = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ) );
xmlFree( attribute ); xmlFree( attribute );
} }
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" ); attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
if ( attribute != NULL ) { if ( attribute != NULL ) {
node.lon = static_cast<NodeID>(100000.*atof(( const char* ) attribute )); node.lon = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ));
xmlFree( attribute ); xmlFree( attribute );
} }
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );

View File

@ -22,6 +22,8 @@
#define XMLPARSER_H_ #define XMLPARSER_H_
#include "BaseParser.h" #include "BaseParser.h"
#include "../DataStructures/Coordinate.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h" #include "../typedefs.h"

View File

@ -22,18 +22,71 @@ or see http://www.gnu.org/licenses/agpl.txt.
OSRM::OSRM(const char * server_ini_path) { OSRM::OSRM(const char * server_ini_path) {
if( !testDataFile(server_ini_path) ){ if( !testDataFile(server_ini_path) ){
throw OSRMException("server.ini not found"); std::string error_message = std::string(server_ini_path) + " not found";
throw OSRMException(error_message.c_str());
} }
BaseConfiguration serverConfig(server_ini_path); IniFile serverConfig(server_ini_path);
boost::filesystem::path base_path =
boost::filesystem::absolute(server_ini_path).parent_path();
if ( !serverConfig.Holds("hsgrData")) {
throw OSRMException("no ram index file name in server ini");
}
if ( !serverConfig.Holds("ramIndex") ) {
throw OSRMException("no mem index file name in server ini");
}
if ( !serverConfig.Holds("fileIndex") ) {
throw OSRMException("no nodes file name in server ini");
}
if ( !serverConfig.Holds("nodesData") ) {
throw OSRMException("no nodes file name in server ini");
}
if ( !serverConfig.Holds("edgesData") ) {
throw OSRMException("no edges file name in server ini");
}
boost::filesystem::path hsgr_path = boost::filesystem::absolute(
serverConfig.GetParameter("hsgrData"),
base_path
);
boost::filesystem::path ram_index_path = boost::filesystem::absolute(
serverConfig.GetParameter("ramIndex"),
base_path
);
boost::filesystem::path file_index_path = boost::filesystem::absolute(
serverConfig.GetParameter("fileIndex"),
base_path
);
boost::filesystem::path node_data_path = boost::filesystem::absolute(
serverConfig.GetParameter("nodesData"),
base_path
);
boost::filesystem::path edge_data_path = boost::filesystem::absolute(
serverConfig.GetParameter("edgesData"),
base_path
);
boost::filesystem::path name_data_path = boost::filesystem::absolute(
serverConfig.GetParameter("namesData"),
base_path
);
boost::filesystem::path timestamp_path = boost::filesystem::absolute(
serverConfig.GetParameter("timestamp"),
base_path
);
objects = new QueryObjectsStorage( objects = new QueryObjectsStorage(
serverConfig.GetParameter("hsgrData"), hsgr_path.string(),
serverConfig.GetParameter("ramIndex"), ram_index_path.string(),
serverConfig.GetParameter("fileIndex"), file_index_path.string(),
serverConfig.GetParameter("nodesData"), node_data_path.string(),
serverConfig.GetParameter("edgesData"), edge_data_path.string(),
serverConfig.GetParameter("namesData"), name_data_path.string(),
serverConfig.GetParameter("timestamp") timestamp_path.string()
); );
RegisterPlugin(new HelloWorldPlugin()); RegisterPlugin(new HelloWorldPlugin());
@ -51,8 +104,11 @@ OSRM::~OSRM() {
} }
void OSRM::RegisterPlugin(BasePlugin * plugin) { void OSRM::RegisterPlugin(BasePlugin * plugin) {
std::cout << "[plugin] " << plugin->GetDescriptor() << std::endl; SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor();
pluginMap[plugin->GetDescriptor()] = plugin; if( pluginMap.find(plugin->GetDescriptor()) != pluginMap.end() ) {
delete pluginMap[plugin->GetDescriptor()];
}
pluginMap.insert(std::make_pair(plugin->GetDescriptor(), plugin));
} }
void OSRM::RunQuery(RouteParameters & route_parameters, http::Reply & reply) { void OSRM::RunQuery(RouteParameters & route_parameters, http::Reply & reply) {

View File

@ -29,28 +29,20 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Plugins/NearestPlugin.h" #include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h" #include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.h" #include "../Plugins/ViaRoutePlugin.h"
#include "../Plugins/RouteParameters.h" #include "../Server/DataStructures/RouteParameters.h"
#include "../Util/BaseConfiguration.h" #include "../Util/IniFile.h"
#include "../Util/InputFileUtil.h" #include "../Util/InputFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Server/BasicDatastructures.h" #include "../Server/BasicDatastructures.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <exception>
#include <vector> #include <vector>
class OSRMException: public std::exception {
public:
OSRMException(const char * message) : message(message) {}
private:
virtual const char* what() const throw() {
return message;
}
const char * message;
};
class OSRM : boost::noncopyable { class OSRM : boost::noncopyable {
typedef boost::unordered_map<std::string, BasePlugin *> PluginMap; typedef boost::unordered_map<std::string, BasePlugin *> PluginMap;
QueryObjectsStorage * objects; QueryObjectsStorage * objects;
@ -63,4 +55,4 @@ private:
PluginMap pluginMap; PluginMap pluginMap;
}; };
#endif //OSRM_H #endif //OSRM_H

View File

@ -21,8 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASEPLUGIN_H_ #ifndef BASEPLUGIN_H_
#define BASEPLUGIN_H_ #define BASEPLUGIN_H_
#include "RouteParameters.h" #include "../DataStructures/Coordinate.h"
#include "../Server/BasicDatastructures.h" #include "../Server/BasicDatastructures.h"
#include "../Server/DataStructures/RouteParameters.h"
#include <string> #include <string>
#include <vector> #include <vector>
@ -32,9 +33,20 @@ public:
BasePlugin() { } BasePlugin() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis) //Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BasePlugin() { } virtual ~BasePlugin() { }
virtual std::string GetDescriptor() const = 0; virtual const std::string & GetDescriptor() const = 0;
virtual std::string GetVersionString() const = 0 ;
virtual void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) = 0; virtual void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) = 0;
inline bool checkCoord(const FixedPointCoordinate & c) {
if(
c.lat > 90*COORDINATE_PRECISION ||
c.lat < -90*COORDINATE_PRECISION ||
c.lon > 180*COORDINATE_PRECISION ||
c.lon < -180*COORDINATE_PRECISION
) {
return false;
}
return true;
}
}; };
#endif /* BASEPLUGIN_H_ */ #endif /* BASEPLUGIN_H_ */

View File

@ -1,24 +1,35 @@
/* /*
* LocatePlugin.h open source routing machine
* Copyright (C) Dennis Luxen, 2010
* Created on: 01.01.2011
* Author: dennis This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef HELLOWORLDPLUGIN_H_ #ifndef HELLOWORLDPLUGIN_H_
#define HELLOWORLDPLUGIN_H_ #define HELLOWORLDPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include <sstream> #include <sstream>
class HelloWorldPlugin : public BasePlugin { class HelloWorldPlugin : public BasePlugin {
public: public:
HelloWorldPlugin() {} HelloWorldPlugin() : descriptor_string("hello"){}
virtual ~HelloWorldPlugin() { } virtual ~HelloWorldPlugin() { }
std::string GetDescriptor() const { return std::string("hello"); } const std::string & GetDescriptor() const { return descriptor_string; }
std::string GetVersionString() const { return std::string("0.1a"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
@ -35,7 +46,7 @@ public:
content << "language: " << routeParameters.language << "<br>"; content << "language: " << routeParameters.language << "<br>";
content << "Number of locations: " << routeParameters.coordinates.size() << "\n"; content << "Number of locations: " << routeParameters.coordinates.size() << "\n";
for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) { for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) {
content << " [" << i << "] " << routeParameters.coordinates[i].lat/100000. << "," << routeParameters.coordinates[i].lon/100000. << "\n"; content << " [" << i << "] " << routeParameters.coordinates[i].lat/COORDINATE_PRECISION << "," << routeParameters.coordinates[i].lon/COORDINATE_PRECISION << "\n";
} }
content << "Number of hints: " << routeParameters.hints.size() << "\n"; content << "Number of hints: " << routeParameters.hints.size() << "\n";
for(unsigned i = 0; i < routeParameters.hints.size(); ++i) { for(unsigned i = 0; i < routeParameters.hints.size(); ++i) {
@ -45,6 +56,8 @@ public:
reply.content.append(content.str()); reply.content.append(content.str());
reply.content.append("</body></html>"); reply.content.append("</body></html>");
} }
private:
std::string descriptor_string;
}; };
#endif /* HELLOWORLDPLUGIN_H_ */ #endif /* HELLOWORLDPLUGIN_H_ */

View File

@ -22,23 +22,19 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define LOCATEPLUGIN_H_ #define LOCATEPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../DataStructures/NodeInformationHelpDesk.h" #include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h" #include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <fstream>
/* /*
* This Plugin locates the nearest node in the road network for a given coordinate. * This Plugin locates the nearest node in the road network for a given coordinate.
*/ */
class LocatePlugin : public BasePlugin { class LocatePlugin : public BasePlugin {
public: public:
LocatePlugin(QueryObjectsStorage * objects) { LocatePlugin(QueryObjectsStorage * objects) : descriptor_string("locate") {
nodeHelpDesk = objects->nodeHelpDesk; nodeHelpDesk = objects->nodeHelpDesk;
} }
std::string GetDescriptor() const { return std::string("locate"); } const std::string & GetDescriptor() const { return descriptor_string; }
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if(!routeParameters.coordinates.size()) { if(!routeParameters.coordinates.size()) {
@ -51,7 +47,7 @@ public:
} }
//query to helpdesk //query to helpdesk
_Coordinate result; FixedPointCoordinate result;
std::string tmp; std::string tmp;
//json //json
@ -99,15 +95,10 @@ public:
reply.headers[0].value = tmp; reply.headers[0].value = tmp;
return; return;
} }
private:
inline bool checkCoord(const _Coordinate & c) {
if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) {
return false;
}
return true;
}
private:
NodeInformationHelpDesk * nodeHelpDesk; NodeInformationHelpDesk * nodeHelpDesk;
std::string descriptor_string;
}; };
#endif /* LOCATEPLUGIN_H_ */ #endif /* LOCATEPLUGIN_H_ */

View File

@ -22,27 +22,27 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define NearestPlugin_H_ #define NearestPlugin_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../DataStructures/NodeInformationHelpDesk.h" #include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h" #include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <fstream>
/* /*
* This Plugin locates the nearest point on a street in the road network for a given coordinate. * This Plugin locates the nearest point on a street in the road network for a given coordinate.
*/ */
class NearestPlugin : public BasePlugin { class NearestPlugin : public BasePlugin {
public: public:
NearestPlugin(QueryObjectsStorage * objects) : names(objects->names) { NearestPlugin(QueryObjectsStorage * objects )
:
names(objects->names),
descriptor_string("nearest")
{
nodeHelpDesk = objects->nodeHelpDesk; nodeHelpDesk = objects->nodeHelpDesk;
descriptorTable.Set("", 0); //default descriptor descriptorTable.insert(std::make_pair("" , 0)); //default descriptor
descriptorTable.Set("json", 1); descriptorTable.insert(std::make_pair("json", 1));
} }
std::string GetDescriptor() const { return std::string("nearest"); } const std::string & GetDescriptor() const { return descriptor_string; }
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if(!routeParameters.coordinates.size()) { if(!routeParameters.coordinates.size()) {
@ -107,17 +107,12 @@ public:
intToString(reply.content.size(), tmp); intToString(reply.content.size(), tmp);
reply.headers[0].value = tmp; reply.headers[0].value = tmp;
} }
private:
inline bool checkCoord(const _Coordinate & c) {
if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) {
return false;
}
return true;
}
private:
NodeInformationHelpDesk * nodeHelpDesk; NodeInformationHelpDesk * nodeHelpDesk;
HashTable<std::string, unsigned> descriptorTable; HashTable<std::string, unsigned> descriptorTable;
std::vector<std::string> & names; std::vector<std::string> & names;
std::string descriptor_string;
}; };
#endif /* NearestPlugin_H_ */ #endif /* NearestPlugin_H_ */

View File

@ -22,16 +22,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define TIMESTAMPPLUGIN_H_ #define TIMESTAMPPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include <cassert>
class TimestampPlugin : public BasePlugin { class TimestampPlugin : public BasePlugin {
public: public:
TimestampPlugin(QueryObjectsStorage * o) : objects(o) { TimestampPlugin(QueryObjectsStorage * o)
} : objects(o), descriptor_string("timestamp")
std::string GetDescriptor() const { return std::string("timestamp"); } { }
std::string GetVersionString() const { return std::string("0.3 (DL)"); } const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
std::string tmp; std::string tmp;
@ -70,6 +67,7 @@ public:
} }
private: private:
QueryObjectsStorage * objects; QueryObjectsStorage * objects;
std::string descriptor_string;
}; };
#endif /* TIMESTAMPPLUGIN_H_ */ #endif /* TIMESTAMPPLUGIN_H_ */

View File

@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define VIAROUTEPLUGIN_H_ #define VIAROUTEPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../Algorithms/ObjectToBase64.h" #include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
@ -33,12 +32,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Descriptors/GPXDescriptor.h" #include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h" #include "../Descriptors/JSONDescriptor.h"
#include "../Server/DataStructures/QueryObjectsStorage.h" #include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <cstdlib> #include <cstdlib>
#include <fstream>
#include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
@ -48,27 +46,30 @@ private:
std::vector<std::string> & names; std::vector<std::string> & names;
StaticGraph<QueryEdge::EdgeData> * graph; StaticGraph<QueryEdge::EdgeData> * graph;
HashTable<std::string, unsigned> descriptorTable; HashTable<std::string, unsigned> descriptorTable;
std::string pluginDescriptorString;
SearchEngine * searchEnginePtr; SearchEngine * searchEnginePtr;
public: public:
ViaRoutePlugin(QueryObjectsStorage * objects, std::string psd = "viaroute") : names(objects->names), pluginDescriptorString(psd) { ViaRoutePlugin(QueryObjectsStorage * objects)
:
names(objects->names),
descriptor_string("viaroute")
{
nodeHelpDesk = objects->nodeHelpDesk; nodeHelpDesk = objects->nodeHelpDesk;
graph = objects->graph; graph = objects->graph;
searchEnginePtr = new SearchEngine(graph, nodeHelpDesk, names); searchEnginePtr = new SearchEngine(graph, nodeHelpDesk, names);
descriptorTable.Set("", 0); //default descriptor descriptorTable.insert(std::make_pair("" , 0));
descriptorTable.Set("json", 0); descriptorTable.insert(std::make_pair("json", 0));
descriptorTable.Set("gpx", 1); descriptorTable.insert(std::make_pair("gpx" , 1));
} }
virtual ~ViaRoutePlugin() { virtual ~ViaRoutePlugin() {
delete searchEnginePtr; delete searchEnginePtr;
} }
std::string GetDescriptor() const { return pluginDescriptorString; } const std::string & GetDescriptor() const { return descriptor_string; }
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if( 2 > routeParameters.coordinates.size() ) { if( 2 > routeParameters.coordinates.size() ) {
@ -90,14 +91,14 @@ public:
std::vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size()); std::vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size());
for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) { for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) {
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) { if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) {
// INFO("Decoding hint: " << routeParameters.hints[i] << " for location index " << i); // SimpleLogger().Write() <<"Decoding hint: " << routeParameters.hints[i] << " for location index " << i;
DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]); DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]);
if(phantomNodeVector[i].isValid(nodeHelpDesk->getNumberOfNodes())) { if(phantomNodeVector[i].isValid(nodeHelpDesk->getNumberOfNodes())) {
// INFO("Decoded hint " << i << " successfully"); // SimpleLogger().Write() << "Decoded hint " << i << " successfully";
continue; continue;
} }
} }
// INFO("Brute force lookup of coordinate " << i); // SimpleLogger().Write() << "Brute force lookup of coordinate " << i;
searchEnginePtr->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i], routeParameters.zoomLevel); searchEnginePtr->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i], routeParameters.zoomLevel);
} }
@ -108,7 +109,7 @@ public:
rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes); rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes);
} }
if( ( routeParameters.alternateRoute ) && (1 == rawRoute.segmentEndCoordinates.size()) ) { if( ( routeParameters.alternateRoute ) && (1 == rawRoute.segmentEndCoordinates.size()) ) {
// INFO("Checking for alternative paths"); // SimpleLogger().Write() << "Checking for alternative paths";
searchEnginePtr->alternativePaths(rawRoute.segmentEndCoordinates[0], rawRoute); searchEnginePtr->alternativePaths(rawRoute.segmentEndCoordinates[0], rawRoute);
} else { } else {
@ -117,7 +118,7 @@ public:
if(INT_MAX == rawRoute.lengthOfShortestPath ) { if(INT_MAX == rawRoute.lengthOfShortestPath ) {
DEBUG( "Error occurred, single path not found" ); SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
} }
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
@ -152,10 +153,10 @@ public:
PhantomNodes phantomNodes; PhantomNodes phantomNodes;
phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom; phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom;
// INFO("Start location: " << phantomNodes.startPhantom.location) // SimpleLogger().Write() << "Start location: " << phantomNodes.startPhantom.location;
phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom; phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom;
// INFO("TargetLocation: " << phantomNodes.targetPhantom.location); // SimpleLogger().Write() << "TargetLocation: " << phantomNodes.targetPhantom.location;
// INFO("Number of segments: " << rawRoute.segmentEndCoordinates.size()); // SimpleLogger().Write() << "Number of segments: " << rawRoute.segmentEndCoordinates.size();
desc->SetConfig(descriptorConfig); desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, *searchEnginePtr); desc->Run(reply, rawRoute, phantomNodes, *searchEnginePtr);
@ -201,7 +202,6 @@ public:
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.json\""; reply.headers[2].value = "attachment; filename=\"route.json\"";
} }
break; break;
} }
@ -209,12 +209,7 @@ public:
return; return;
} }
private: private:
inline bool checkCoord(const _Coordinate & c) { std::string descriptor_string;
if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) {
return false;
}
return true;
}
}; };

40
README.md Normal file
View File

@ -0,0 +1,40 @@
# Readme
For instructions on how to compile and run OSRM, please consult the Wiki at
https://github.com/DennisOSRM/Project-OSRM/wiki
or use our free and daily updated online service at
http://map.project-osrm.org
## References in publications
When using the code in a (scientific) publication, please cite
```
@inproceedings{luxen-vetter-2011,
author = {Luxen, Dennis and Vetter, Christian},
title = {Real-time routing with OpenStreetMap data},
booktitle = {Proceedings of the 19th ACM SIGSPATIAL International Conference on Advances in Geographic Information Systems},
series = {GIS '11},
year = {2011},
isbn = {978-1-4503-1031-4},
location = {Chicago, Illinois},
pages = {513--516},
numpages = {4},
url = {http://doi.acm.org/10.1145/2093973.2094062},
doi = {10.1145/2093973.2094062},
acmid = {2094062},
publisher = {ACM},
address = {New York, NY, USA},
}
```
## Current build status
| build config | branch | status |
|:-------------|:--------|:------------|
| Project OSRM | master | [![Build Status](https://travis-ci.org/DennisOSRM/Project-OSRM.png?branch=master)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Project OSRM | develop | [![Build Status](https://travis-ci.org/DennisOSRM/Project-OSRM.png?branch=develop)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| LUAbind fork | master | [![Build Status](https://travis-ci.org/DennisOSRM/luabind.png?branch=master)](https://travis-ci.org/DennisOSRM/luabind) |

View File

@ -307,7 +307,7 @@ private:
int aindex = 0; int aindex = 0;
//compute forward sharing //compute forward sharing
while( (packedAlternativePath[aindex] == packedShortestPath[aindex]) && (packedAlternativePath[aindex+1] == packedShortestPath[aindex+1]) ) { while( (packedAlternativePath[aindex] == packedShortestPath[aindex]) && (packedAlternativePath[aindex+1] == packedShortestPath[aindex+1]) ) {
// INFO("retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")"); // SimpleLogger().Write() << "retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")";
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]); typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]);
sharing += search_graph->GetEdgeData(edgeID).distance; sharing += search_graph->GetEdgeData(edgeID).distance;
++aindex; ++aindex;

View File

@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASICROUTINGINTERFACE_H_ #ifndef BASICROUTINGINTERFACE_H_
#define BASICROUTINGINTERFACE_H_ #define BASICROUTINGINTERFACE_H_
#include "../Plugins/RawRouteData.h" #include "../DataStructures/RawRouteData.h"
#include "../Util/ContainerUtils.h" #include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h"
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@ -44,7 +45,7 @@ public:
inline void RoutingStep(typename QueryDataT::QueryHeap & _forwardHeap, typename QueryDataT::QueryHeap & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection) const { inline void RoutingStep(typename QueryDataT::QueryHeap & _forwardHeap, typename QueryDataT::QueryHeap & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection) const {
const NodeID node = _forwardHeap.DeleteMin(); const NodeID node = _forwardHeap.DeleteMin();
const int distance = _forwardHeap.GetKey(node); const int distance = _forwardHeap.GetKey(node);
//INFO("Settled (" << _forwardHeap.GetData( node ).parent << "," << node << ")=" << distance); //SimpleLogger().Write() << "Settled (" << _forwardHeap.GetData( node ).parent << "," << node << ")=" << distance;
if(_backwardHeap.WasInserted(node) ){ if(_backwardHeap.WasInserted(node) ){
const int newDistance = _backwardHeap.GetKey(node) + distance; const int newDistance = _backwardHeap.GetKey(node) + distance;
if(newDistance < *_upperbound ){ if(newDistance < *_upperbound ){

View File

@ -20,7 +20,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "QueryObjectsStorage.h" #include "QueryObjectsStorage.h"
#include "../../Util/GraphLoader.h"
QueryObjectsStorage::QueryObjectsStorage( QueryObjectsStorage::QueryObjectsStorage(
const std::string & hsgrPath, const std::string & hsgrPath,
@ -31,29 +30,47 @@ QueryObjectsStorage::QueryObjectsStorage(
const std::string & namesPath, const std::string & namesPath,
const std::string & timestampPath const std::string & timestampPath
) { ) {
INFO("loading graph data"); if( hsgrPath.empty() ) {
std::ifstream hsgrInStream(hsgrPath.c_str(), std::ios::binary); throw OSRMException("no hsgr file given in ini file");
if(!hsgrInStream) { ERR(hsgrPath << " not found"); } }
if( ramIndexPath.empty() ) {
throw OSRMException("no ram index file given in ini file");
}
if( fileIndexPath.empty() ) {
throw OSRMException("no mem index file given in ini file");
}
if( nodesPath.empty() ) {
throw OSRMException("no nodes file given in ini file");
}
if( edgesPath.empty() ) {
throw OSRMException("no edges file given in ini file");
}
if( namesPath.empty() ) {
throw OSRMException("no names file given in ini file");
}
SimpleLogger().Write() << "loading graph data";
//Deserialize road network graph //Deserialize road network graph
std::vector< QueryGraph::_StrNode> nodeList; std::vector< QueryGraph::_StrNode> nodeList;
std::vector< QueryGraph::_StrEdge> edgeList; std::vector< QueryGraph::_StrEdge> edgeList;
const int n = readHSGRFromStream( const int n = readHSGRFromStream(
hsgrInStream, hsgrPath,
nodeList, nodeList,
edgeList, edgeList,
&checkSum &checkSum
); );
hsgrInStream.close();
INFO("Data checksum is " << checkSum); SimpleLogger().Write() << "Data checksum is " << checkSum;
graph = new QueryGraph(nodeList, edgeList); graph = new QueryGraph(nodeList, edgeList);
assert(0 == nodeList.size()); assert(0 == nodeList.size());
assert(0 == edgeList.size()); assert(0 == edgeList.size());
if(timestampPath.length()) { if(timestampPath.length()) {
INFO("Loading Timestamp"); SimpleLogger().Write() << "Loading Timestamp";
std::ifstream timestampInStream(timestampPath.c_str()); std::ifstream timestampInStream(timestampPath.c_str());
if(!timestampInStream) { WARN(timestampPath << " not found"); } if(!timestampInStream) {
SimpleLogger().Write(logWARNING) << timestampPath << " not found";
}
getline(timestampInStream, timestamp); getline(timestampInStream, timestamp);
timestampInStream.close(); timestampInStream.close();
@ -65,7 +82,7 @@ QueryObjectsStorage::QueryObjectsStorage(
timestamp.resize(25); timestamp.resize(25);
} }
INFO("Loading auxiliary information"); SimpleLogger().Write() << "Loading auxiliary information";
//Init nearest neighbor data structure //Init nearest neighbor data structure
nodeHelpDesk = new NodeInformationHelpDesk( nodeHelpDesk = new NodeInformationHelpDesk(
ramIndexPath, ramIndexPath,
@ -77,23 +94,33 @@ QueryObjectsStorage::QueryObjectsStorage(
); );
//deserialize street name list //deserialize street name list
INFO("Loading names index"); SimpleLogger().Write() << "Loading names index";
std::ifstream namesInStream(namesPath.c_str(), std::ios::binary); boost::filesystem::path names_file(namesPath);
if(!namesInStream) { ERR(namesPath << " not found"); }
unsigned size(0); if ( !boost::filesystem::exists( names_file ) ) {
namesInStream.read((char *)&size, sizeof(unsigned)); throw OSRMException("names file does not exist");
}
if ( 0 == boost::filesystem::file_size( names_file ) ) {
throw OSRMException("names file is empty");
}
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
unsigned size = 0;
name_stream.read((char *)&size, sizeof(unsigned));
BOOST_ASSERT_MSG(0 != size, "name file empty");
char buf[1024]; char buf[1024];
for(unsigned i = 0; i < size; ++i) { for( unsigned i = 0; i < size; ++i ) {
unsigned sizeOfString = 0; unsigned size_of_string = 0;
namesInStream.read((char *)&sizeOfString, sizeof(unsigned)); name_stream.read((char *)&size_of_string, sizeof(unsigned));
buf[sizeOfString] = '\0'; // instead of memset buf[size_of_string] = '\0'; // instead of memset
namesInStream.read(buf, sizeOfString); name_stream.read(buf, size_of_string);
names.push_back(buf); names.push_back(buf);
} }
std::vector<std::string>(names).swap(names); std::vector<std::string>(names).swap(names);
namesInStream.close(); BOOST_ASSERT_MSG(0 != names.size(), "could not load any names");
INFO("All query data structures loaded"); name_stream.close();
SimpleLogger().Write() << "All query data structures loaded";
} }
QueryObjectsStorage::~QueryObjectsStorage() { QueryObjectsStorage::~QueryObjectsStorage() {

View File

@ -22,13 +22,21 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef QUERYOBJECTSSTORAGE_H_ #ifndef QUERYOBJECTSSTORAGE_H_
#define QUERYOBJECTSSTORAGE_H_ #define QUERYOBJECTSSTORAGE_H_
#include<vector> #include "../../Util/GraphLoader.h"
#include<string> #include "../../Util/OSRMException.h"
#include "../../Util/SimpleLogger.h"
#include "../../DataStructures/NodeInformationHelpDesk.h" #include "../../DataStructures/NodeInformationHelpDesk.h"
#include "../../DataStructures/QueryEdge.h" #include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/StaticGraph.h" #include "../../DataStructures/StaticGraph.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <vector>
#include <string>
struct QueryObjectsStorage { struct QueryObjectsStorage {
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph; typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
typedef QueryGraph::InputEdge InputEdge; typedef QueryGraph::InputEdge InputEdge;

View File

@ -21,8 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef ROUTE_PARAMETERS_H #ifndef ROUTE_PARAMETERS_H
#define ROUTE_PARAMETERS_H #define ROUTE_PARAMETERS_H
#include "../DataStructures/Coordinate.h" #include "../../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h" #include "../../DataStructures/HashTable.h"
#include <boost/fusion/container/vector.hpp> #include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp> #include <boost/fusion/sequence/intrinsic.hpp>
@ -52,12 +52,13 @@ struct RouteParameters {
std::string jsonpParameter; std::string jsonpParameter;
std::string language; std::string language;
std::vector<std::string> hints; std::vector<std::string> hints;
std::vector<_Coordinate> coordinates; std::vector<FixedPointCoordinate> coordinates;
typedef HashTable<std::string, std::string>::MyIterator OptionsIterator; typedef HashTable<std::string, std::string>::const_iterator OptionsIterator;
void setZoomLevel(const short i) { void setZoomLevel(const short i) {
if (18 > i && 0 < i) if (18 > i && 0 < i) {
zoomLevel = i; zoomLevel = i;
}
} }
void setAlternateRouteFlag(const bool b) { void setAlternateRouteFlag(const bool b) {
@ -105,13 +106,11 @@ struct RouteParameters {
compression = b; compression = b;
} }
void addCoordinate(boost::fusion::vector < double, double > arg_) { void addCoordinate(const boost::fusion::vector < double, double > & arg_) {
int lat = 100000.*boost::fusion::at_c < 0 > (arg_); int lat = COORDINATE_PRECISION*boost::fusion::at_c < 0 > (arg_);
int lon = 100000.*boost::fusion::at_c < 1 > (arg_); int lon = COORDINATE_PRECISION*boost::fusion::at_c < 1 > (arg_);
_Coordinate myCoordinate(lat, lon); coordinates.push_back(FixedPointCoordinate(lat, lon));
coordinates.push_back(_Coordinate(lat, lon));
} }
}; };
#endif /*ROUTE_PARAMETERS_H*/ #endif /*ROUTE_PARAMETERS_H*/

View File

@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "APIGrammar.h" #include "APIGrammar.h"
#include "BasicDatastructures.h" #include "BasicDatastructures.h"
#include "DataStructures/RouteParameters.h"
#include "../Library/OSRM.h" #include "../Library/OSRM.h"
#include "../Plugins/RouteParameters.h" #include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
@ -46,25 +47,35 @@ public:
try { try {
std::string request(req.uri); std::string request(req.uri);
{ //This block logs the current request to std out. should be moved to a logging component time_t ltime;
time_t ltime; struct tm *Tm;
struct tm *Tm;
ltime=time(NULL); ltime=time(NULL);
Tm=localtime(&ltime); Tm=localtime(&ltime);
INFO((Tm->tm_mday < 10 ? "0" : "" ) << Tm->tm_mday << "-" << (Tm->tm_mon+1 < 10 ? "0" : "" ) << (Tm->tm_mon+1) << "-" << 1900+Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "" ) << Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "" ) << Tm->tm_min << ":" << (Tm->tm_sec < 10 ? "0" : "" ) << Tm->tm_sec << " " << SimpleLogger().Write() <<
req.endpoint.to_string() << " " << req.referrer << ( 0 == req.referrer.length() ? "- " :" ") << req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri ); (Tm->tm_mday < 10 ? "0" : "" ) << Tm->tm_mday << "-" <<
} (Tm->tm_mon+1 < 10 ? "0" : "" ) << (Tm->tm_mon+1) << "-" <<
1900+Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "" ) <<
Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "" ) <<
Tm->tm_min << ":" << (Tm->tm_sec < 10 ? "0" : "" ) <<
Tm->tm_sec << " " << req.endpoint.to_string() << " " <<
req.referrer << ( 0 == req.referrer.length() ? "- " :" ") <<
req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri;
RouteParameters routeParameters; RouteParameters routeParameters;
APIGrammarParser apiParser(&routeParameters); APIGrammarParser apiParser(&routeParameters);
std::string::iterator it = request.begin(); std::string::iterator it = request.begin();
bool result = boost::spirit::qi::parse(it, request.end(), apiParser); const bool result = boost::spirit::qi::parse(
if (!result || (it != request.end()) ) { it,
request.end(),
apiParser
);
if ( !result || (it != request.end()) ) {
rep = http::Reply::stockReply(http::Reply::badRequest); rep = http::Reply::stockReply(http::Reply::badRequest);
int position = std::distance(request.begin(), it); const int position = std::distance(request.begin(), it);
std::string tmp_position_string; std::string tmp_position_string;
intToString(position, tmp_position_string); intToString(position, tmp_position_string);
rep.content += "Input seems to be malformed close to position "; rep.content += "Input seems to be malformed close to position ";
@ -72,7 +83,7 @@ public:
rep.content += request; rep.content += request;
rep.content += tmp_position_string; rep.content += tmp_position_string;
rep.content += "<br>"; rep.content += "<br>";
unsigned end = std::distance(request.begin(), it); const unsigned end = std::distance(request.begin(), it);
for(unsigned i = 0; i < end; ++i) { for(unsigned i = 0; i < end; ++i) {
rep.content += "&nbsp;"; rep.content += "&nbsp;";
} }
@ -84,7 +95,8 @@ public:
} }
} catch(std::exception& e) { } catch(std::exception& e) {
rep = http::Reply::stockReply(http::Reply::internalServerError); rep = http::Reply::stockReply(http::Reply::internalServerError);
WARN("[server error] code: " << e.what() << ", uri: " << req.uri); SimpleLogger().Write(logWARNING) <<
"[server error] code: " << e.what() << ", uri: " << req.uri;
return; return;
} }
}; };

View File

@ -21,9 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef REQUEST_PARSER_H #ifndef REQUEST_PARSER_H
#define REQUEST_PARSER_H #define REQUEST_PARSER_H
#include "BasicDatastructures.h"
#include <boost/logic/tribool.hpp> #include <boost/logic/tribool.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include "BasicDatastructures.h"
namespace http { namespace http {

View File

@ -16,65 +16,51 @@ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
Created on: 26.11.2010
Author: dennis
*/ */
#ifndef SERVERFACTORY_H_ #ifndef SERVERFACTORY_H_
#define SERVERFACTORY_H_ #define SERVERFACTORY_H_
#include "Server.h" #include "Server.h"
#include "../Util/IniFile.h"
#include "../Util/BaseConfiguration.h" #include "../Util/SimpleLogger.h"
#include "../Util/InputFileUtil.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <zlib.h> #include <zlib.h>
struct ServerFactory { #include <boost/noncopyable.hpp>
static Server * CreateServer(BaseConfiguration& serverConfig) {
if(!testDataFile(serverConfig.GetParameter("nodesData"))) {
ERR("nodes file not found");
}
if(!testDataFile(serverConfig.GetParameter("hsgrData"))) {
ERR("hsgr file not found");
}
if(!testDataFile(serverConfig.GetParameter("namesData"))) {
ERR("names file not found");
}
if(!testDataFile(serverConfig.GetParameter("ramIndex"))) {
ERR("ram index file not found");
}
if(!testDataFile(serverConfig.GetParameter("fileIndex"))) {
ERR("file index file not found");
}
struct ServerFactory : boost::noncopyable {
static Server * CreateServer( IniFile & serverConfig ) {
int threads = omp_get_num_procs(); int threads = omp_get_num_procs();
if(serverConfig.GetParameter("IP") == "") if( serverConfig.GetParameter("IP").empty() ) {
serverConfig.SetParameter("IP", "0.0.0.0"); serverConfig.SetParameter("IP", "0.0.0.0");
if(serverConfig.GetParameter("Port") == "") }
if( serverConfig.GetParameter("Port").empty() ) {
serverConfig.SetParameter("Port", "5000"); serverConfig.SetParameter("Port", "5000");
}
if(stringToInt(serverConfig.GetParameter("Threads")) != 0 && stringToInt(serverConfig.GetParameter("Threads")) <= threads) if(
stringToInt(serverConfig.GetParameter("Threads")) >= 1 &&
stringToInt(serverConfig.GetParameter("Threads")) <= threads
) {
threads = stringToInt( serverConfig.GetParameter("Threads") ); threads = stringToInt( serverConfig.GetParameter("Threads") );
}
std::cout << "[server] http 1.1 compression handled by zlib version " << zlibVersion() << std::endl; SimpleLogger().Write() <<
Server * server = new Server(serverConfig.GetParameter("IP"), serverConfig.GetParameter("Port"), threads); "http 1.1 compression handled by zlib version " << zlibVersion();
Server * server = new Server(
serverConfig.GetParameter("IP"),
serverConfig.GetParameter("Port"),
threads
);
return server; return server;
} }
static Server * CreateServer(const char * iniFile) { static Server * CreateServer(const char * iniFile) {
BaseConfiguration serverConfig(iniFile); IniFile serverConfig(iniFile);
return CreateServer(serverConfig); return CreateServer(serverConfig);
} }
}; };

View File

@ -25,9 +25,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/DynamicGraph.h" #include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/QueryEdge.h" #include "../DataStructures/QueryEdge.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/BaseConfiguration.h"
#include "../Util/InputFileUtil.h"
#include "../Util/GraphLoader.h" #include "../Util/GraphLoader.h"
#include "../Util/IniFile.h"
#include "../Util/InputFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <fstream> #include <fstream>
@ -39,22 +41,25 @@ or see http://www.gnu.org/licenses/agpl.txt.
typedef QueryEdge::EdgeData EdgeData; typedef QueryEdge::EdgeData EdgeData;
typedef DynamicGraph<EdgeData>::InputEdge InputEdge; typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
typedef BaseConfiguration ContractorConfiguration;
std::vector<NodeInfo> internal_to_external_node_map; std::vector<NodeInfo> internal_to_external_node_map;
std::vector<_Restriction> restrictions_vector; std::vector<TurnRestriction> restrictions_vector;
std::vector<NodeID> bollard_node_IDs_vector; std::vector<NodeID> bollard_node_IDs_vector;
std::vector<NodeID> traffic_light_node_IDs_vector; std::vector<NodeID> traffic_light_node_IDs_vector;
int main (int argument_count, char *argument_values[]) { int main (int argc, char * argv[]) {
if(argument_count < 3) { LogPolicy::GetInstance().Unmute();
ERR("usage:\n" << argument_values[0] << " <osrm> <osrm.restrictions>"); if(argc < 3) {
SimpleLogger().Write(logWARNING) <<
"usage:\n" << argv[0] << " <osrm> <osrm.restrictions>";
return -1;
} }
INFO("Using restrictions from file: " << argument_values[2]); SimpleLogger().Write() <<
std::ifstream restriction_ifstream(argument_values[2], std::ios::binary); "Using restrictions from file: " << argv[2];
std::ifstream restriction_ifstream(argv[2], std::ios::binary);
if(!restriction_ifstream.good()) { if(!restriction_ifstream.good()) {
ERR("Could not access <osrm-restrictions> files"); throw OSRMException("Could not access <osrm-restrictions> files");
} }
uint32_t usable_restriction_count = 0; uint32_t usable_restriction_count = 0;
restriction_ifstream.read( restriction_ifstream.read(
@ -65,18 +70,15 @@ int main (int argument_count, char *argument_values[]) {
restriction_ifstream.read( restriction_ifstream.read(
(char *)&(restrictions_vector[0]), (char *)&(restrictions_vector[0]),
usable_restriction_count*sizeof(_Restriction) usable_restriction_count*sizeof(TurnRestriction)
); );
restriction_ifstream.close(); restriction_ifstream.close();
std::ifstream input_stream; std::ifstream input_stream;
input_stream.open( input_stream.open( argv[1], std::ifstream::in | std::ifstream::binary );
argument_values[1],
std::ifstream::in | std::ifstream::binary
);
if (!input_stream.is_open()) { if (!input_stream.is_open()) {
ERR("Cannot open " << argument_values[1]); throw OSRMException("Cannot open osrm file");
} }
std::vector<ImportEdge> edge_list; std::vector<ImportEdge> edge_list;
@ -90,17 +92,16 @@ int main (int argument_count, char *argument_values[]) {
); );
input_stream.close(); input_stream.close();
INFO( SimpleLogger().Write() <<
restrictions_vector.size() << " restrictions, " << restrictions_vector.size() << " restrictions, " <<
bollard_node_IDs_vector.size() << " bollard nodes, " << bollard_node_IDs_vector.size() << " bollard nodes, " <<
traffic_light_node_IDs_vector.size() << " traffic lights" traffic_light_node_IDs_vector.size() << " traffic lights";
);
/*** /***
* Building an edge-expanded graph from node-based input an turn restrictions * Building an edge-expanded graph from node-based input an turn restrictions
*/ */
INFO("Starting SCC graph traversal"); SimpleLogger().Write() << "Starting SCC graph traversal";
TarjanSCC * tarjan = new TarjanSCC ( TarjanSCC * tarjan = new TarjanSCC (
node_based_node_count, node_based_node_count,
edge_list, edge_list,
@ -113,9 +114,9 @@ int main (int argument_count, char *argument_values[]) {
tarjan->Run(); tarjan->Run();
std::vector<_Restriction>().swap(restrictions_vector); std::vector<TurnRestriction>().swap(restrictions_vector);
std::vector<NodeID>().swap(bollard_node_IDs_vector); std::vector<NodeID>().swap(bollard_node_IDs_vector);
std::vector<NodeID>().swap(traffic_light_node_IDs_vector); std::vector<NodeID>().swap(traffic_light_node_IDs_vector);
INFO("finished component analysis"); SimpleLogger().Write() << "finished component analysis";
return 0; return 0;
} }

View File

@ -20,6 +20,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Library/OSRM.h" #include "../Library/OSRM.h"
#include "../Util/SimpleLogger.h"
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
@ -44,43 +45,49 @@ void print_tree(boost::property_tree::ptree const& pt, const unsigned recursion_
int main (int argc, char * argv[]) { int main (int argc, char * argv[]) {
std::cout << "\n starting up engines, compile at " LogPolicy::GetInstance().Unmute();
<< __DATE__ << ", " __TIME__ << std::endl; try {
BaseConfiguration serverConfig((argc > 1 ? argv[1] : "server.ini")); std::cout << "\n starting up engines, compile at "
OSRM routing_machine((argc > 1 ? argv[1] : "server.ini")); << __DATE__ << ", " __TIME__ << std::endl;
IniFile serverConfig((argc > 1 ? argv[1] : "server.ini"));
OSRM routing_machine((argc > 1 ? argv[1] : "server.ini"));
RouteParameters route_parameters; RouteParameters route_parameters;
route_parameters.zoomLevel = 18; //no generalization route_parameters.zoomLevel = 18; //no generalization
route_parameters.printInstructions = true; //turn by turn instructions route_parameters.printInstructions = true; //turn by turn instructions
route_parameters.alternateRoute = true; //get an alternate route, too route_parameters.alternateRoute = true; //get an alternate route, too
route_parameters.geometry = true; //retrieve geometry of route route_parameters.geometry = true; //retrieve geometry of route
route_parameters.compression = true; //polyline encoding route_parameters.compression = true; //polyline encoding
route_parameters.checkSum = UINT_MAX; //see wiki route_parameters.checkSum = UINT_MAX; //see wiki
route_parameters.service = "viaroute"; //that's routing route_parameters.service = "viaroute"; //that's routing
route_parameters.outputFormat = "json"; route_parameters.outputFormat = "json";
route_parameters.jsonpParameter = ""; //set for jsonp wrapping route_parameters.jsonpParameter = ""; //set for jsonp wrapping
route_parameters.language = ""; //unused atm route_parameters.language = ""; //unused atm
//route_parameters.hints.push_back(); // see wiki, saves I/O if done properly //route_parameters.hints.push_back(); // see wiki, saves I/O if done properly
_Coordinate start_coordinate(52.519930*100000,13.438640*100000); FixedPointCoordinate start_coordinate(52.519930*COORDINATE_PRECISION,13.438640*COORDINATE_PRECISION);
_Coordinate target_coordinate(52.513191*100000,13.415852*100000); FixedPointCoordinate target_coordinate(52.513191*COORDINATE_PRECISION,13.415852*COORDINATE_PRECISION);
route_parameters.coordinates.push_back(start_coordinate); route_parameters.coordinates.push_back(start_coordinate);
route_parameters.coordinates.push_back(target_coordinate); route_parameters.coordinates.push_back(target_coordinate);
http::Reply osrm_reply; http::Reply osrm_reply;
routing_machine.RunQuery(route_parameters, osrm_reply); routing_machine.RunQuery(route_parameters, osrm_reply);
std::cout << osrm_reply.content << std::endl; std::cout << osrm_reply.content << std::endl;
//attention: super-inefficient hack below: //attention: super-inefficient hack below:
std::stringstream ss; std::stringstream ss;
ss << osrm_reply.content; ss << osrm_reply.content;
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt); boost::property_tree::read_json(ss, pt);
print_tree(pt, 0); print_tree(pt, 0);
} catch (std::exception & e) {
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
return -1;
}
return 0; return 0;
} }

View File

@ -21,14 +21,18 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef GRAPHLOADER_H #ifndef GRAPHLOADER_H
#define GRAPHLOADER_H #define GRAPHLOADER_H
#include "OSRMException.h"
#include "../DataStructures/ImportNode.h" #include "../DataStructures/ImportNode.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
#include "../DataStructures/NodeCoords.h" #include "../DataStructures/QueryNode.h"
#include "../DataStructures/Restriction.h" #include "../DataStructures/Restriction.h"
#include "../Util/SimpleLogger.h"
#include "../Util/UUID.h" #include "../Util/UUID.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <cassert> #include <cassert>
@ -56,17 +60,16 @@ NodeID readBinaryOSRMGraphFromStream(
std::vector<NodeID> &bollardNodes, std::vector<NodeID> &bollardNodes,
std::vector<NodeID> &trafficLightNodes, std::vector<NodeID> &trafficLightNodes,
std::vector<NodeInfo> * int2ExtNodeMap, std::vector<NodeInfo> * int2ExtNodeMap,
std::vector<_Restriction> & inputRestrictions std::vector<TurnRestriction> & inputRestrictions
) { ) {
const UUID uuid_orig; const UUID uuid_orig;
UUID uuid_loaded; UUID uuid_loaded;
in.read((char *) &uuid_loaded, sizeof(UUID)); in.read((char *) &uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) { if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
WARN( SimpleLogger().Write(logWARNING) <<
".osrm was prepared with different build.\n" ".osrm was prepared with different build.\n"
"Reprocess to get rid of this warning." "Reprocess to get rid of this warning.";
)
} }
NodeID n, source, target; NodeID n, source, target;
@ -74,16 +77,18 @@ NodeID readBinaryOSRMGraphFromStream(
short dir;// direction (0 = open, 1 = forward, 2+ = open) short dir;// direction (0 = open, 1 = forward, 2+ = open)
ExternalNodeMap ext2IntNodeMap; ExternalNodeMap ext2IntNodeMap;
in.read((char*)&n, sizeof(NodeID)); in.read((char*)&n, sizeof(NodeID));
INFO("Importing n = " << n << " nodes "); SimpleLogger().Write() << "Importing n = " << n << " nodes ";
_Node node; _Node node;
for (NodeID i=0; i<n; ++i) { for (NodeID i=0; i<n; ++i) {
in.read((char*)&node, sizeof(_Node)); in.read((char*)&node, sizeof(_Node));
int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id)); int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id));
ext2IntNodeMap.insert(std::make_pair(node.id, i)); ext2IntNodeMap.insert(std::make_pair(node.id, i));
if(node.bollard) if(node.bollard) {
bollardNodes.push_back(i); bollardNodes.push_back(i);
if(node.trafficLight) }
if(node.trafficLight) {
trafficLightNodes.push_back(i); trafficLightNodes.push_back(i);
}
} }
//tighten vector sizes //tighten vector sizes
@ -91,11 +96,11 @@ NodeID readBinaryOSRMGraphFromStream(
std::vector<NodeID>(trafficLightNodes).swap(trafficLightNodes); std::vector<NodeID>(trafficLightNodes).swap(trafficLightNodes);
in.read((char*)&m, sizeof(unsigned)); in.read((char*)&m, sizeof(unsigned));
INFO(" and " << m << " edges "); SimpleLogger().Write() << " and " << m << " edges ";
for(unsigned i = 0; i < inputRestrictions.size(); ++i) { for(unsigned i = 0; i < inputRestrictions.size(); ++i) {
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode); ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped from Node of restriction"); SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
continue; continue;
} }
@ -103,14 +108,14 @@ NodeID readBinaryOSRMGraphFromStream(
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode); intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped via node of restriction"); SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
continue; continue;
} }
inputRestrictions[i].viaNode = intNodeID->second; inputRestrictions[i].viaNode = intNodeID->second;
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode); intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped to node of restriction"); SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
continue; continue;
} }
inputRestrictions[i].toNode = intNodeID->second; inputRestrictions[i].toNode = intNodeID->second;
@ -151,7 +156,8 @@ NodeID readBinaryOSRMGraphFromStream(
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source); ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source);
if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) { if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) {
#ifndef NDEBUG #ifndef NDEBUG
WARN(" unresolved source NodeID: " << source ); SimpleLogger().Write(logWARNING) <<
" unresolved source NodeID: " << source;
#endif #endif
continue; continue;
} }
@ -159,7 +165,8 @@ NodeID readBinaryOSRMGraphFromStream(
intNodeID = ext2IntNodeMap.find(target); intNodeID = ext2IntNodeMap.find(target);
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) { if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) {
#ifndef NDEBUG #ifndef NDEBUG
WARN("unresolved target NodeID : " << target ); SimpleLogger().Write(logWARNING) <<
"unresolved target NodeID : " << target;
#endif #endif
continue; continue;
} }
@ -210,7 +217,7 @@ NodeID readBinaryOSRMGraphFromStream(
typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>()); typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>());
ext2IntNodeMap.clear(); ext2IntNodeMap.clear();
std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates. std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates.
INFO("Graph loaded ok and has " << edgeList.size() << " edges"); SimpleLogger().Write() << "Graph loaded ok and has " << edgeList.size() << " edges";
return n; return n;
} }
template<typename EdgeT> template<typename EdgeT>
@ -220,14 +227,14 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open) int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open)
ExternalNodeMap ext2IntNodeMap; ExternalNodeMap ext2IntNodeMap;
in >> n; in >> n;
DEBUG("Importing n = " << n << " nodes "); SimpleLogger().Write(logDEBUG) << "Importing n = " << n << " nodes ";
for (NodeID i=0; i<n; ++i) { for (NodeID i=0; i<n; ++i) {
in >> id >> ycoord >> xcoord; in >> id >> ycoord >> xcoord;
int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id)); int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id));
ext2IntNodeMap.insert(std::make_pair(id, i)); ext2IntNodeMap.insert(std::make_pair(id, i));
} }
in >> m; in >> m;
DEBUG(" and " << m << " edges"); SimpleLogger().Write(logDEBUG) << " and " << m << " edges";
edgeList.reserve(m); edgeList.reserve(m);
for (EdgeID i=0; i<m; ++i) { for (EdgeID i=0; i<m; ++i) {
@ -295,8 +302,9 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
} }
assert(length > 0); assert(length > 0);
assert(weight > 0); assert(weight > 0);
if(dir <0 || dir > 2) if(dir <0 || dir > 2) {
WARN("direction bogus: " << dir); SimpleLogger().Write(logWARNING) << "direction bogus: " << dir;
}
assert(0<=dir && dir<=2); assert(0<=dir && dir<=2);
bool forward = true; bool forward = true;
@ -308,19 +316,25 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
forward = false; forward = false;
} }
if(length == 0) { ERR("loaded null length edge"); } if(length == 0) {
throw OSRMException("loaded null length edge");
}
// translate the external NodeIDs to internal IDs // translate the external NodeIDs to internal IDs
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source); ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source);
if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) { if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) {
ERR("after " << edgeList.size() << " edges" << "\n->" << source << "," << target << "," << length << "," << dir << "," << weight << "\n->unresolved source NodeID: " << source); throw OSRMException("unresolvable source Node ID");
} }
source = intNodeID->second; source = intNodeID->second;
intNodeID = ext2IntNodeMap.find(target); intNodeID = ext2IntNodeMap.find(target);
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) { ERR("unresolved target NodeID : " << target); } if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) {
throw OSRMException("unresolvable target Node ID");
}
target = intNodeID->second; target = intNodeID->second;
if(source == UINT_MAX || target == UINT_MAX) { ERR("nonexisting source or target" ); } if(source == UINT_MAX || target == UINT_MAX) {
throw OSRMException("nonexisting source or target" );
}
EdgeT inputEdge(source, target, 0, weight, forward, backward, type ); EdgeT inputEdge(source, target, 0, weight, forward, backward, type );
edgeList.push_back(inputEdge); edgeList.push_back(inputEdge);
@ -342,17 +356,19 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
in >> d; in >> d;
in >> n; in >> n;
in >> m; in >> m;
#ifndef DEBUG
std::cout << "expecting " << n << " nodes and " << m << " edges ..." << flush; SimpleLogger().Write(logDEBUG) <<
#endif "expecting " << n << " nodes and " << m << " edges ...";
edgeList.reserve(m); edgeList.reserve(m);
for (EdgeID i=0; i<m; i++) { for (EdgeID i=0; i<m; i++) {
EdgeWeight weight; EdgeWeight weight;
in >> source >> target >> weight >> dir; in >> source >> target >> weight >> dir;
assert(weight > 0); assert(weight > 0);
if(dir <0 || dir > 3) if(dir <0 || dir > 3) {
ERR( "[error] direction bogus: " << dir ); throw OSRMException( "[error] direction bogus");
}
assert(0<=dir && dir<=3); assert(0<=dir && dir<=3);
bool forward = true; bool forward = true;
@ -361,7 +377,9 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
if (dir == 2) forward = false; if (dir == 2) forward = false;
if (dir == 3) {backward = true; forward = true;} if (dir == 3) {backward = true; forward = true;}
if(weight == 0) { ERR("loaded null length edge"); } if(weight == 0) {
throw OSRMException("loaded null length edge");
}
if( nodeMap.find(source) == nodeMap.end()) { if( nodeMap.find(source) == nodeMap.end()) {
nodeMap.insert(std::make_pair(source, numberOfNodes )); nodeMap.insert(std::make_pair(source, numberOfNodes ));
@ -384,41 +402,51 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
template<typename NodeT, typename EdgeT> template<typename NodeT, typename EdgeT>
unsigned readHSGRFromStream( unsigned readHSGRFromStream(
std::istream &hsgr_input_stream, const std::string & hsgr_filename,
std::vector<NodeT> & node_list, std::vector<NodeT> & node_list,
std::vector<EdgeT> & edge_list, std::vector<EdgeT> & edge_list,
unsigned * check_sum unsigned * check_sum
) { ) {
boost::filesystem::path hsgr_file(hsgr_filename);
if ( !boost::filesystem::exists( hsgr_file ) ) {
throw OSRMException("hsgr file does not exist");
}
if ( 0 == boost::filesystem::file_size( hsgr_file ) ) {
throw OSRMException("hsgr file is empty");
}
boost::filesystem::ifstream hsgr_input_stream(hsgr_file, std::ios::binary);
UUID uuid_loaded, uuid_orig; UUID uuid_loaded, uuid_orig;
hsgr_input_stream.read((char *)&uuid_loaded, sizeof(UUID)); hsgr_input_stream.read((char *)&uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) { if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
WARN( SimpleLogger().Write(logWARNING) <<
".hsgr was prepared with different build.\n" ".hsgr was prepared with different build. "
"Reprocess to get rid of this warning." "Reprocess to get rid of this warning.";
)
} }
unsigned number_of_nodes = 0; unsigned number_of_nodes = 0;
hsgr_input_stream.read((char*) check_sum, sizeof(unsigned)); hsgr_input_stream.read((char*) check_sum, sizeof(unsigned));
hsgr_input_stream.read((char*) & number_of_nodes, sizeof(unsigned)); hsgr_input_stream.read((char*) & number_of_nodes, sizeof(unsigned));
BOOST_ASSERT_MSG( 0 != number_of_nodes, "number of nodes is zero");
node_list.resize(number_of_nodes + 1); node_list.resize(number_of_nodes + 1);
hsgr_input_stream.read( hsgr_input_stream.read(
(char*) &(node_list[0]), (char*) &(node_list[0]),
number_of_nodes*sizeof(NodeT) number_of_nodes*sizeof(NodeT)
); );
unsigned number_of_edges = 0; unsigned number_of_edges = 0;
hsgr_input_stream.read( hsgr_input_stream.read(
(char*) &number_of_edges, (char*) &number_of_edges,
sizeof(unsigned) sizeof(unsigned)
); );
BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero");
edge_list.resize(number_of_edges); edge_list.resize(number_of_edges);
hsgr_input_stream.read( hsgr_input_stream.read(
(char*) &(edge_list[0]), (char*) &(edge_list[0]),
number_of_edges*sizeof(EdgeT) number_of_edges*sizeof(EdgeT)
); );
hsgr_input_stream.close();
return number_of_nodes; return number_of_nodes;
} }

View File

@ -18,58 +18,62 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef BASECONFIGURATION_H_ #ifndef INI_FILE_H_
#define BASECONFIGURATION_H_ #define INI_FILE_H_
#include "OSRMException.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <exception> #include <exception>
#include <fstream>
#include <iostream> #include <iostream>
#include <string> #include <string>
class BaseConfiguration { class IniFile {
public: public:
BaseConfiguration(const char * configFile) { IniFile(const char * config_filename) {
std::ifstream config( configFile ); boost::filesystem::path config_file(config_filename);
if(!config) { if ( !boost::filesystem::exists( config_file ) ) {
std::cerr << "[config] .ini not found" << std::endl; std::string error = std::string(config_filename) + " not found";
return; throw OSRMException(error);
}
if ( 0 == boost::filesystem::file_size( config_file ) ) {
std::string error = std::string(config_filename) + " is empty";
throw OSRMException(error);
} }
boost::filesystem::ifstream config( config_file );
std::string line; std::string line;
try { if (config.is_open()) {
if (config.is_open()) { while ( config.good() ) {
while ( config.good() ) { getline (config,line);
getline (config,line); std::vector<std::string> tokens;
std::vector<std::string> tokens; Tokenize(line, tokens);
Tokenize(line, tokens); if(2 == tokens.size() ) {
if(2 == tokens.size() ) parameters.insert(std::make_pair(tokens[0], tokens[1]));
parameters.Add(tokens[0], tokens[1]);
} }
config.close();
} }
} catch(std::exception& e) { config.close();
ERR("[config] " << configFile << " not found -> Exception: " <<e.what());
if(config.is_open())
config.close();
} }
} }
std::string GetParameter(const char * key){ std::string GetParameter(const std::string & key){
return GetParameter(std::string(key)); return parameters.Find(key);
} }
std::string GetParameter(std::string key) { bool Holds(const std::string & key) const {
return parameters.Find(key); return parameters.Holds(key);
} }
void SetParameter(const char* key, const char* value) { void SetParameter(const char* key, const char* value) {
SetParameter(std::string(key), std::string(value)); SetParameter(std::string(key), std::string(value));
} }
void SetParameter(std::string key, std::string value) { void SetParameter(const std::string & key, const std::string & value) {
parameters.Set(key, value); parameters.insert(std::make_pair(key, value));
} }
private: private:
@ -83,31 +87,14 @@ private:
while (std::string::npos != pos || std::string::npos != lastPos) { while (std::string::npos != pos || std::string::npos != lastPos) {
std::string temp = str.substr(lastPos, pos - lastPos); std::string temp = str.substr(lastPos, pos - lastPos);
TrimStringRight(temp); boost::trim(temp);
TrimStringLeft(temp);
tokens.push_back( temp ); tokens.push_back( temp );
lastPos = str.find_first_not_of(delimiters, pos); lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos); pos = str.find_first_of(delimiters, lastPos);
} }
} }
void TrimStringRight(std::string& str) {
std::string::size_type pos = str.find_last_not_of(" ");
if (pos != std::string::npos)
str.erase(pos+1);
else
str.erase( str.begin() , str.end() );
}
void TrimStringLeft(std::string& str) {
std::string::size_type pos = str.find_first_not_of(" ");
if (pos != std::string::npos)
str.erase(0, pos);
else
str.erase( str.begin() , str.end() );
}
HashTable<std::string, std::string> parameters; HashTable<std::string, std::string> parameters;
}; };
#endif /* BASECONFIGURATION_H_ */ #endif /* INI_FILE_H_ */

View File

@ -29,7 +29,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
inline bool testDataFile(const std::string & filename){ inline bool testDataFile(const std::string & filename){
boost::filesystem::path fileToTest(filename); boost::filesystem::path fileToTest(filename);
if(!boost::filesystem::exists(fileToTest)) { if(!boost::filesystem::exists(fileToTest)) {
WARN("Failed to open file " << filename << " for reading."); SimpleLogger().Write(logWARNING) <<
"Failed to open file " << filename << " for reading.";
return false; return false;
} }
return true; return true;

39
Util/OSRMException.h Normal file
View File

@ -0,0 +1,39 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef OSRM_EXCEPTION_H
#define OSRM_EXCEPTION_H
#include <exception>
#include <string>
class OSRMException: public std::exception {
public:
OSRMException(const char * message) : message(message) {}
OSRMException(const std::string & message) : message(message) {}
virtual ~OSRMException() throw() {}
private:
virtual const char* what() const throw() {
return message.c_str();
}
const std::string message;
};
#endif /* OSRM_EXCEPTION_H */

114
Util/SimpleLogger.h Normal file
View File

@ -0,0 +1,114 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef SIMPLE_LOGGER_H_
#define SIMPLE_LOGGER_H_
#include <boost/assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread/mutex.hpp>
#include <ostream>
#include <iostream>
enum LogLevel { logINFO, logWARNING, logDEBUG };
static boost::mutex logger_mutex;
class LogPolicy : boost::noncopyable {
public:
void Unmute() {
m_is_mute = false;
}
void Mute() {
m_is_mute = true;
}
bool IsMute() const {
return m_is_mute;
}
static LogPolicy & GetInstance() {
static LogPolicy runningInstance;
return runningInstance;
}
private:
LogPolicy() : m_is_mute(true) { }
bool m_is_mute;
};
class SimpleLogger {
public:
std::ostringstream& Write(LogLevel l = logINFO) {
try {
boost::mutex::scoped_lock lock(logger_mutex);
level = l;
os << "[";
switch(level) {
case logINFO:
os << "info";
break;
case logWARNING:
os << "warn";
break;
case logDEBUG:
#ifndef NDEBUG
os << "debug";
#endif
break;
default:
BOOST_ASSERT_MSG(false, "should not happen");
break;
}
os << "] ";
} catch (...) { }
return os;
}
virtual ~SimpleLogger() {
if(!LogPolicy::GetInstance().IsMute()) {
switch(level) {
case logINFO:
std::cout << os.str() << std::endl;
break;
case logWARNING:
std::cerr << os.str() << std::endl;
break;
case logDEBUG:
#ifndef NDEBUG
std::cout << os.str() << std::endl;
#endif
break;
default:
BOOST_ASSERT_MSG(false, "should not happen");
break;
}
}
}
private:
LogLevel level;
std::ostringstream os;
};
#endif /* SIMPLE_LOGGER_H_ */

View File

@ -23,13 +23,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../typedefs.h" #include "../typedefs.h"
#include <string>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <cstdio> #include <cstdio>
#include <string>
// precision: position after decimal point // precision: position after decimal point
// length: maximum number of digits including comma and decimals // length: maximum number of digits including comma and decimals
@ -163,14 +163,4 @@ inline bool StringStartsWith(const std::string & input, const std::string & pref
return boost::starts_with(input, prefix); return boost::starts_with(input, prefix);
} }
// Function returns a 'random' filename in temporary directors.
// May not be platform independent.
inline void GetTemporaryFileName(std::string & filename) {
char buffer[L_tmpnam];
char * retPointer = tmpnam (buffer);
if(0 == retPointer)
ERR("Could not create temporary file name");
filename = buffer;
}
#endif /* STRINGUTIL_H_ */ #endif /* STRINGUTIL_H_ */

View File

@ -21,30 +21,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef TIMINGUTIL_H_ #ifndef TIMINGUTIL_H_
#define TIMINGUTIL_H_ #define TIMINGUTIL_H_
#include <climits> #include <boost/timer.hpp>
#include <cstdlib>
static boost::timer my_timer;
#ifdef _WIN32
#include <sys/timeb.h>
#include <sys/types.h>
#include <winsock.h>
void gettimeofday(struct timeval* t,void* timezone)
{ struct _timeb timebuffer;
_ftime( &timebuffer );
t->tv_sec=timebuffer.time;
t->tv_usec=1000*timebuffer.millitm;
}
#else
#include <sys/time.h>
#endif
/** Returns a timestamp (now) in seconds (incl. a fractional part). */ /** Returns a timestamp (now) in seconds (incl. a fractional part). */
static inline double get_timestamp() { static inline double get_timestamp() {
struct timeval tp; return my_timer.elapsed();
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
} }
#endif /* TIMINGUTIL_H_ */ #endif /* TIMINGUTIL_H_ */

View File

@ -55,41 +55,41 @@ const boost::uuids::uuid & UUID::GetUUID() const {
return named_uuid; return named_uuid;
} }
const bool UUID::IsMagicNumberOK() const { bool UUID::IsMagicNumberOK() const {
return 1297240911 == magic_number; return 1297240911 == magic_number;
} }
const bool UUID::TestGraphUtil(const UUID & other) const { bool UUID::TestGraphUtil(const UUID & other) const {
if(!other.IsMagicNumberOK()) { if(!other.IsMagicNumberOK()) {
ERR("hsgr input file misses magic number. Check or reprocess the file"); throw OSRMException("hsgr input file misses magic number. Check or reprocess the file");
} }
return std::equal(md5_graph, md5_graph+32, other.md5_graph); return std::equal(md5_graph, md5_graph+32, other.md5_graph);
} }
const bool UUID::TestPrepare(const UUID & other) const { bool UUID::TestPrepare(const UUID & other) const {
if(!other.IsMagicNumberOK()) { if(!other.IsMagicNumberOK()) {
ERR("extracted input file misses magic number. Check or reprocess the file"); throw OSRMException("extracted input file misses magic number. Check or reprocess the file");
} }
return std::equal(md5_prepare, md5_prepare+32, other.md5_prepare); return std::equal(md5_prepare, md5_prepare+32, other.md5_prepare);
} }
const bool UUID::TestRTree(const UUID & other) const { bool UUID::TestRTree(const UUID & other) const {
if(!other.IsMagicNumberOK()) { if(!other.IsMagicNumberOK()) {
ERR("r-tree input file misses magic number. Check or reprocess the file"); throw OSRMException("r-tree input file misses magic number. Check or reprocess the file");
} }
return std::equal(md5_tree, md5_tree+32, other.md5_tree); return std::equal(md5_tree, md5_tree+32, other.md5_tree);
} }
const bool UUID::TestNodeInfo(const UUID & other) const { bool UUID::TestNodeInfo(const UUID & other) const {
if(!other.IsMagicNumberOK()) { if(!other.IsMagicNumberOK()) {
ERR("nodes file misses magic number. Check or reprocess the file"); throw OSRMException("nodes file misses magic number. Check or reprocess the file");
} }
return std::equal(md5_nodeinfo, md5_nodeinfo+32, other.md5_nodeinfo); return std::equal(md5_nodeinfo, md5_nodeinfo+32, other.md5_nodeinfo);
} }
const bool UUID::TestQueryObjects(const UUID & other) const { bool UUID::TestQueryObjects(const UUID & other) const {
if(!other.IsMagicNumberOK()) { if(!other.IsMagicNumberOK()) {
ERR("missing magic number. Check or reprocess the file"); throw OSRMException("missing magic number. Check or reprocess the file");
} }
return std::equal(md5_objects, md5_objects+32, other.md5_objects); return std::equal(md5_objects, md5_objects+32, other.md5_objects);
} }

View File

@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef UUID_H #ifndef UUID_H
#define UUID_H #define UUID_H
#include "OSRMException.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@ -40,12 +41,12 @@ public:
UUID(); UUID();
~UUID(); ~UUID();
const boost::uuids::uuid & GetUUID() const; const boost::uuids::uuid & GetUUID() const;
const bool IsMagicNumberOK() const; bool IsMagicNumberOK() const;
const bool TestGraphUtil(const UUID & other) const; bool TestGraphUtil(const UUID & other) const;
const bool TestPrepare(const UUID & other) const; bool TestPrepare(const UUID & other) const;
const bool TestRTree(const UUID & other) const; bool TestRTree(const UUID & other) const;
const bool TestNodeInfo(const UUID & other) const; bool TestNodeInfo(const UUID & other) const;
const bool TestQueryObjects(const UUID & other) const; bool TestQueryObjects(const UUID & other) const;
private: private:
const unsigned magic_number; const unsigned magic_number;
char md5_prepare[33]; char md5_prepare[33];
@ -59,4 +60,4 @@ private:
bool has_64_bits; bool has_64_bits;
}; };
#endif /* UUID_H */ #endif /* UUID_H */

View File

@ -0,0 +1,45 @@
# Based on @berenm's pull request https://github.com/quarnster/SublimeClang/pull/135
# Create the database with cmake with for example: cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
# or you could have set(CMAKE_EXPORT_COMPILE_COMMANDS ON) in your CMakeLists.txt
# Usage within SublimeClang:
# "sublimeclang_options_script": "python ${home}/code/cmake_options_script.py ${project_path:build}/compile_commands.json",
import re
import os
import os.path
import pickle
import sys
import json
compilation_database_pattern = re.compile('(?<=\s)-[DIOUWfgs][^=\s]+(?:=\\"[^"]+\\"|=[^"]\S+)?')
def load_db(filename):
compilation_database = {}
with open(filename) as compilation_database_file:
compilation_database_entries = json.load(compilation_database_file)
total = len(compilation_database_entries)
entry = 0
for compilation_entry in compilation_database_entries:
entry = entry + 1
compilation_database[compilation_entry["file"]] = [ p.strip() for p in compilation_database_pattern.findall(compilation_entry["command"]) ]
return compilation_database
scriptpath = os.path.dirname(os.path.abspath(sys.argv[1]))
cache_file = "%s/cached_options.txt" % (scriptpath)
db = None
if os.access(cache_file, os.R_OK) == 0:
db = load_db(sys.argv[1])
f = open(cache_file, "wb")
pickle.dump(db, f)
f.close()
else:
f = open(cache_file)
db = pickle.load(f)
f.close()
if db and sys.argv[2] in db:
for option in db[sys.argv[2]]:
print option

View File

@ -26,11 +26,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "DataStructures/QueryEdge.h" #include "DataStructures/QueryEdge.h"
#include "DataStructures/StaticGraph.h" #include "DataStructures/StaticGraph.h"
#include "DataStructures/StaticRTree.h" #include "DataStructures/StaticRTree.h"
#include "Util/BaseConfiguration.h" #include "Util/IniFile.h"
#include "Util/GraphLoader.h" #include "Util/GraphLoader.h"
#include "Util/InputFileUtil.h" #include "Util/InputFileUtil.h"
#include "Util/LuaUtil.h" #include "Util/LuaUtil.h"
#include "Util/OpenMPWrapper.h" #include "Util/OpenMPWrapper.h"
#include "Util/OSRMException.h"
#include "Util/SimpleLogger.h"
#include "Util/StringUtil.h" #include "Util/StringUtil.h"
#include "typedefs.h" #include "typedefs.h"
@ -48,18 +50,22 @@ or see http://www.gnu.org/licenses/agpl.txt.
typedef QueryEdge::EdgeData EdgeData; typedef QueryEdge::EdgeData EdgeData;
typedef DynamicGraph<EdgeData>::InputEdge InputEdge; typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
typedef StaticGraph<EdgeData>::InputEdge StaticEdge; typedef StaticGraph<EdgeData>::InputEdge StaticEdge;
typedef BaseConfiguration ContractorConfiguration; typedef IniFile ContractorConfiguration;
std::vector<NodeInfo> internalToExternalNodeMapping; std::vector<NodeInfo> internalToExternalNodeMapping;
std::vector<_Restriction> inputRestrictions; std::vector<TurnRestriction> inputRestrictions;
std::vector<NodeID> bollardNodes; std::vector<NodeID> bollardNodes;
std::vector<NodeID> trafficLightNodes; std::vector<NodeID> trafficLightNodes;
std::vector<ImportEdge> edgeList; std::vector<ImportEdge> edgeList;
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
try { try {
LogPolicy::GetInstance().Unmute();
if(argc < 3) { if(argc < 3) {
ERR("usage: " << std::endl << argv[0] << " <osrm-data> <osrm-restrictions> [<profile>]"); SimpleLogger().Write(logWARNING) <<
"usage: \n" <<
argv[0] << " <osrm-data> <osrm-restrictions> [<profile>]";
return -1;
} }
double startupTime = get_timestamp(); double startupTime = get_timestamp();
@ -71,32 +77,39 @@ int main (int argc, char *argv[]) {
number_of_threads = rawNumber; number_of_threads = rawNumber;
} }
omp_set_num_threads(number_of_threads); omp_set_num_threads(number_of_threads);
LogPolicy::GetInstance().Unmute();
INFO("Using restrictions from file: " << argv[2]); SimpleLogger().Write() << "Using restrictions from file: " << argv[2];
std::ifstream restrictionsInstream(argv[2], std::ios::binary); std::ifstream restrictionsInstream(argv[2], std::ios::binary);
if(!restrictionsInstream.good()) { if(!restrictionsInstream.good()) {
ERR("Could not access <osrm-restrictions> files"); std::cerr <<
"Could not access <osrm-restrictions> files" << std::endl;
} }
_Restriction restriction; TurnRestriction restriction;
UUID uuid_loaded, uuid_orig; UUID uuid_loaded, uuid_orig;
unsigned usableRestrictionsCounter(0); unsigned usableRestrictionsCounter(0);
restrictionsInstream.read((char*)&uuid_loaded, sizeof(UUID)); restrictionsInstream.read((char*)&uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestPrepare(uuid_orig) ) { if( !uuid_loaded.TestPrepare(uuid_orig) ) {
WARN( SimpleLogger().Write(logWARNING) <<
".restrictions was prepared with different build.\n" ".restrictions was prepared with different build.\n"
"Reprocess to get rid of this warning." "Reprocess to get rid of this warning.";
)
} }
restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned)); restrictionsInstream.read(
(char*)&usableRestrictionsCounter,
sizeof(unsigned)
);
inputRestrictions.resize(usableRestrictionsCounter); inputRestrictions.resize(usableRestrictionsCounter);
restrictionsInstream.read((char *)&(inputRestrictions[0]), usableRestrictionsCounter*sizeof(_Restriction)); restrictionsInstream.read(
(char *)&(inputRestrictions[0]),
usableRestrictionsCounter*sizeof(TurnRestriction)
);
restrictionsInstream.close(); restrictionsInstream.close();
std::ifstream in; std::ifstream in;
in.open (argv[1], std::ifstream::in | std::ifstream::binary); in.open (argv[1], std::ifstream::in | std::ifstream::binary);
if (!in.is_open()) { if (!in.is_open()) {
ERR("Cannot open " << argv[1]); throw OSRMException("Cannot open osrm input file");
} }
std::string nodeOut(argv[1]); nodeOut += ".nodes"; std::string nodeOut(argv[1]); nodeOut += ".nodes";
@ -107,7 +120,7 @@ int main (int argc, char *argv[]) {
/*** Setup Scripting Environment ***/ /*** Setup Scripting Environment ***/
if(!testDataFile( (argc > 3 ? argv[3] : "profile.lua") )) { if(!testDataFile( (argc > 3 ? argv[3] : "profile.lua") )) {
ERR("Need profile.lua to apply traffic signal penalty"); throw OSRMException("Cannot open profile.lua ");
} }
// Create a new lua state // Create a new lua state
@ -123,20 +136,34 @@ int main (int argc, char *argv[]) {
luaAddScriptFolderToLoadPath( myLuaState, (argc > 3 ? argv[3] : "profile.lua") ); luaAddScriptFolderToLoadPath( myLuaState, (argc > 3 ? argv[3] : "profile.lua") );
// Now call our function in a lua script // Now call our function in a lua script
INFO("Parsing speedprofile from " << (argc > 3 ? argv[3] : "profile.lua") ); SimpleLogger().Write() <<
"Parsing speedprofile from " <<
(argc > 3 ? argv[3] : "profile.lua");
if(0 != luaL_dofile(myLuaState, (argc > 3 ? argv[3] : "profile.lua") )) { if(0 != luaL_dofile(myLuaState, (argc > 3 ? argv[3] : "profile.lua") )) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block"); std::cerr <<
lua_tostring(myLuaState,-1) <<
" occured in scripting block" <<
std::endl;
} }
EdgeBasedGraphFactory::SpeedProfileProperties speedProfile; EdgeBasedGraphFactory::SpeedProfileProperties speedProfile;
if(0 != luaL_dostring( myLuaState, "return traffic_signal_penalty\n")) { if(0 != luaL_dostring( myLuaState, "return traffic_signal_penalty\n")) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block"); std::cerr <<
lua_tostring(myLuaState,-1) <<
" occured in scripting block" <<
std::endl;
return -1;
} }
speedProfile.trafficSignalPenalty = 10*lua_tointeger(myLuaState, -1); speedProfile.trafficSignalPenalty = 10*lua_tointeger(myLuaState, -1);
if(0 != luaL_dostring( myLuaState, "return u_turn_penalty\n")) { if(0 != luaL_dostring( myLuaState, "return u_turn_penalty\n")) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block"); std::cerr <<
lua_tostring(myLuaState,-1) <<
" occured in scripting block" <<
std::endl;
return -1;
} }
speedProfile.uTurnPenalty = 10*lua_tointeger(myLuaState, -1); speedProfile.uTurnPenalty = 10*lua_tointeger(myLuaState, -1);
@ -145,20 +172,31 @@ int main (int argc, char *argv[]) {
std::vector<ImportEdge> edgeList; std::vector<ImportEdge> edgeList;
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions); NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
in.close(); in.close();
INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights"); SimpleLogger().Write() <<
if(0 == edgeList.size()) inputRestrictions.size() <<
ERR("The input data is broken. It is impossible to do any turns in this graph"); " restrictions, " <<
bollardNodes.size() <<
" bollard nodes, " <<
trafficLightNodes.size() <<
" traffic lights";
if(0 == edgeList.size()) {
std::cerr <<
"The input data is broken. "
"It is impossible to do any turns in this graph" <<
std::endl;
return -1;
}
/*** /***
* Building an edge-expanded graph from node-based input an turn restrictions * Building an edge-expanded graph from node-based input an turn restrictions
*/ */
INFO("Generating edge-expanded graph representation"); SimpleLogger().Write() << "Generating edge-expanded graph representation";
EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile); EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile);
std::vector<ImportEdge>().swap(edgeList); std::vector<ImportEdge>().swap(edgeList);
edgeBasedGraphFactory->Run(edgeOut.c_str(), myLuaState); edgeBasedGraphFactory->Run(edgeOut.c_str(), myLuaState);
std::vector<_Restriction>().swap(inputRestrictions); std::vector<TurnRestriction>().swap(inputRestrictions);
std::vector<NodeID>().swap(bollardNodes); std::vector<NodeID>().swap(bollardNodes);
std::vector<NodeID>().swap(trafficLightNodes); std::vector<NodeID>().swap(trafficLightNodes);
NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes(); NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes();
@ -172,7 +210,7 @@ int main (int argc, char *argv[]) {
* Writing info on original (node-based) nodes * Writing info on original (node-based) nodes
*/ */
INFO("writing node map ..."); SimpleLogger().Write() << "writing node map ...";
std::ofstream mapOutFile(nodeOut.c_str(), std::ios::binary); std::ofstream mapOutFile(nodeOut.c_str(), std::ios::binary);
mapOutFile.write((char *)&(internalToExternalNodeMapping[0]), internalToExternalNodeMapping.size()*sizeof(NodeInfo)); mapOutFile.write((char *)&(internalToExternalNodeMapping[0]), internalToExternalNodeMapping.size()*sizeof(NodeInfo));
mapOutFile.close(); mapOutFile.close();
@ -184,7 +222,7 @@ int main (int argc, char *argv[]) {
* Building grid-like nearest-neighbor data structure * Building grid-like nearest-neighbor data structure
*/ */
INFO("building r-tree ..."); SimpleLogger().Write() << "building r-tree ...";
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * rtree = StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * rtree =
new StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode>( new StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode>(
nodeBasedEdgeList, nodeBasedEdgeList,
@ -195,17 +233,21 @@ int main (int argc, char *argv[]) {
IteratorbasedCRC32<std::vector<EdgeBasedGraphFactory::EdgeBasedNode> > crc32; IteratorbasedCRC32<std::vector<EdgeBasedGraphFactory::EdgeBasedNode> > crc32;
unsigned crc32OfNodeBasedEdgeList = crc32(nodeBasedEdgeList.begin(), nodeBasedEdgeList.end() ); unsigned crc32OfNodeBasedEdgeList = crc32(nodeBasedEdgeList.begin(), nodeBasedEdgeList.end() );
nodeBasedEdgeList.clear(); nodeBasedEdgeList.clear();
INFO("CRC32 based checksum is " << crc32OfNodeBasedEdgeList); SimpleLogger().Write() << "CRC32: " << crc32OfNodeBasedEdgeList;
/*** /***
* Contracting the edge-expanded graph * Contracting the edge-expanded graph
*/ */
INFO("initializing contractor"); SimpleLogger().Write() << "initializing contractor";
Contractor* contractor = new Contractor( edgeBasedNodeNumber, edgeBasedEdgeList ); Contractor* contractor = new Contractor( edgeBasedNodeNumber, edgeBasedEdgeList );
double contractionStartedTimestamp(get_timestamp()); double contractionStartedTimestamp(get_timestamp());
contractor->Run(); contractor->Run();
INFO("Contraction took " << get_timestamp() - contractionStartedTimestamp << " sec"); const double contraction_duration = (get_timestamp() - contractionStartedTimestamp);
SimpleLogger().Write() <<
"Contraction took " <<
contraction_duration <<
" sec";
DeallocatingVector< QueryEdge > contractedEdgeList; DeallocatingVector< QueryEdge > contractedEdgeList;
contractor->GetEdges( contractedEdgeList ); contractor->GetEdges( contractedEdgeList );
@ -215,11 +257,15 @@ int main (int argc, char *argv[]) {
* Sorting contracted edges in a way that the static query graph can read some in in-place. * Sorting contracted edges in a way that the static query graph can read some in in-place.
*/ */
INFO("Building Node Array"); SimpleLogger().Write() << "Building Node Array";
std::sort(contractedEdgeList.begin(), contractedEdgeList.end()); std::sort(contractedEdgeList.begin(), contractedEdgeList.end());
unsigned numberOfNodes = 0; unsigned numberOfNodes = 0;
unsigned numberOfEdges = contractedEdgeList.size(); unsigned numberOfEdges = contractedEdgeList.size();
INFO("Serializing compacted graph of " << numberOfEdges << " edges"); SimpleLogger().Write() <<
"Serializing compacted graph of " <<
numberOfEdges <<
" edges";
std::ofstream hsgr_output_stream(graphOut.c_str(), std::ios::binary); std::ofstream hsgr_output_stream(graphOut.c_str(), std::ios::binary);
hsgr_output_stream.write((char*)&uuid_orig, sizeof(UUID) ); hsgr_output_stream.write((char*)&uuid_orig, sizeof(UUID) );
BOOST_FOREACH(const QueryEdge & edge, contractedEdgeList) { BOOST_FOREACH(const QueryEdge & edge, contractedEdgeList) {
@ -261,8 +307,16 @@ int main (int argc, char *argv[]) {
currentEdge.target = contractedEdgeList[edge].target; currentEdge.target = contractedEdgeList[edge].target;
currentEdge.data = contractedEdgeList[edge].data; currentEdge.data = contractedEdgeList[edge].data;
if(currentEdge.data.distance <= 0) { if(currentEdge.data.distance <= 0) {
INFO("Edge: " << i << ",source: " << contractedEdgeList[edge].source << ", target: " << contractedEdgeList[edge].target << ", dist: " << currentEdge.data.distance); SimpleLogger().Write(logWARNING) <<
ERR("Failed at edges of node " << node << " of " << numberOfNodes); "Edge: " << i <<
",source: " << contractedEdgeList[edge].source <<
", target: " << contractedEdgeList[edge].target <<
", dist: " << currentEdge.data.distance;
SimpleLogger().Write(logWARNING) <<
"Failed at edges of node " << node <<
" of " << numberOfNodes;
return -1;
} }
//Serialize edges //Serialize edges
hsgr_output_stream.write((char*) &currentEdge, sizeof(StaticGraph<EdgeData>::_StrEdge)); hsgr_output_stream.write((char*) &currentEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
@ -270,16 +324,24 @@ int main (int argc, char *argv[]) {
++usedEdgeCounter; ++usedEdgeCounter;
} }
} }
double endTime = (get_timestamp() - startupTime); SimpleLogger().Write() << "Preprocessing : " <<
INFO("Expansion : " << (nodeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< (edgeBasedNodeNumber/expansionHasFinishedTime) << " edges/sec"); (get_timestamp() - startupTime) << " seconds";
INFO("Contraction: " << (edgeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< usedEdgeCounter/endTime << " edges/sec"); SimpleLogger().Write() << "Expansion : " <<
(nodeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and " <<
(edgeBasedNodeNumber/expansionHasFinishedTime) << " edges/sec";
SimpleLogger().Write() << "Contraction: " <<
(edgeBasedNodeNumber/contraction_duration) << " nodes/sec and " <<
usedEdgeCounter/contraction_duration << " edges/sec";
hsgr_output_stream.close(); hsgr_output_stream.close();
//cleanedEdgeList.clear(); //cleanedEdgeList.clear();
_nodes.clear(); _nodes.clear();
INFO("finished preprocessing"); SimpleLogger().Write() << "finished preprocessing";
} catch (std::exception &e) { } catch ( const std::exception &e ) {
ERR("Exception occured: " << e.what()); SimpleLogger().Write(logWARNING) <<
"Exception occured: " << e.what() << std::endl;
return -1;
} }
return 0; return 0;
} }

View File

@ -23,10 +23,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "Extractor/ScriptingEnvironment.h" #include "Extractor/ScriptingEnvironment.h"
#include "Extractor/PBFParser.h" #include "Extractor/PBFParser.h"
#include "Extractor/XMLParser.h" #include "Extractor/XMLParser.h"
#include "Util/BaseConfiguration.h" #include "Util/IniFile.h"
#include "Util/InputFileUtil.h" #include "Util/InputFileUtil.h"
#include "Util/MachineInfo.h" #include "Util/MachineInfo.h"
#include "Util/OpenMPWrapper.h" #include "Util/OpenMPWrapper.h"
#include "Util/OSRMException.h"
#include "Util/SimpleLogger.h"
#include "Util/StringUtil.h" #include "Util/StringUtil.h"
#include "Util/UUID.h" #include "Util/UUID.h"
#include "typedefs.h" #include "typedefs.h"
@ -42,18 +44,23 @@ UUID uuid;
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
try { try {
LogPolicy::GetInstance().Unmute();
double startup_time = get_timestamp(); double startup_time = get_timestamp();
if(argc < 2) { if(argc < 2) {
ERR("usage: \n" << argv[0] << " <file.osm/.osm.bz2/.osm.pbf> [<profile.lua>]"); SimpleLogger().Write(logWARNING) <<
"usage: \n" <<
argv[0] <<
" <file.osm/.osm.bz2/.osm.pbf> [<profile.lua>]";
return -1;
} }
/*** Setup Scripting Environment ***/ /*** Setup Scripting Environment ***/
ScriptingEnvironment scriptingEnvironment((argc > 2 ? argv[2] : "profile.lua")); ScriptingEnvironment scriptingEnvironment((argc > 2 ? argv[2] : "profile.lua"));
unsigned number_of_threads = omp_get_num_procs(); unsigned number_of_threads = omp_get_num_procs();
if(testDataFile("extractor.ini")) { if(testDataFile("extractor.ini")) {
BaseConfiguration extractorConfig("extractor.ini"); IniFile extractorConfig("extractor.ini");
unsigned rawNumber = stringToInt(extractorConfig.GetParameter("Threads")); unsigned rawNumber = stringToInt(extractorConfig.GetParameter("Threads"));
if( rawNumber != 0 && rawNumber <= number_of_threads) { if( rawNumber != 0 && rawNumber <= number_of_threads) {
number_of_threads = rawNumber; number_of_threads = rawNumber;
@ -61,7 +68,7 @@ int main (int argc, char *argv[]) {
} }
omp_set_num_threads(number_of_threads); omp_set_num_threads(number_of_threads);
INFO("extracting data from input file " << argv[1]); SimpleLogger().Write() << "extracting data from input file " << argv[1];
bool file_has_pbf_format(false); bool file_has_pbf_format(false);
std::string output_file_name(argv[1]); std::string output_file_name(argv[1]);
std::string restrictionsFileName(argv[1]); std::string restrictionsFileName(argv[1]);
@ -95,7 +102,7 @@ int main (int argc, char *argv[]) {
unsigned amountOfRAM = 1; unsigned amountOfRAM = 1;
unsigned installedRAM = GetPhysicalmemory(); unsigned installedRAM = GetPhysicalmemory();
if(installedRAM < 2048264) { if(installedRAM < 2048264) {
WARN("Machine has less than 2GB RAM."); SimpleLogger().Write(logWARNING) << "Machine has less than 2GB RAM.";
} }
StringMap stringMap; StringMap stringMap;
@ -111,28 +118,32 @@ int main (int argc, char *argv[]) {
} }
if(!parser->ReadHeader()) { if(!parser->ReadHeader()) {
ERR("Parser not initialized!"); throw OSRMException("Parser not initialized!");
} }
INFO("Parsing in progress.."); SimpleLogger().Write() << "Parsing in progress..";
double parsing_start_time = get_timestamp(); double parsing_start_time = get_timestamp();
parser->Parse(); parser->Parse();
INFO("Parsing finished after " << SimpleLogger().Write() << "Parsing finished after " <<
(get_timestamp() - parsing_start_time) << (get_timestamp() - parsing_start_time) <<
" seconds" " seconds";
);
externalMemory.PrepareData(output_file_name, restrictionsFileName, amountOfRAM); externalMemory.PrepareData(output_file_name, restrictionsFileName, amountOfRAM);
delete parser; delete parser;
delete extractCallBacks; delete extractCallBacks;
INFO("extraction finished after " << get_timestamp() - startup_time << "s"); SimpleLogger().Write() <<
"extraction finished after " << get_timestamp() - startup_time <<
"s";
std::cout << "\nRun:\n" SimpleLogger().Write() << "\nRun:\n./osrm-prepare " <<
<< "./osrm-prepare " << output_file_name << " " << restrictionsFileName output_file_name <<
<< std::endl; " " <<
return 0; restrictionsFileName <<
std::endl;
} catch(std::exception & e) { } catch(std::exception & e) {
WARN("unhandled exception: " << e.what()); SimpleLogger().Write(logWARNING) << "unhandled exception: " << e.what();
return -1;
} }
return 0;
} }

View File

@ -15,7 +15,7 @@ Feature: Bike - Max speed restrictions
| highway | maxspeed | bothw | | highway | maxspeed | bothw |
| residential | | 49s ~10% | | residential | | 49s ~10% |
| residential | 80 | 49s ~10% | | residential | 80 | 49s ~10% |
@todo @todo
Scenario: Bicycle - Maxspeed formats Scenario: Bicycle - Maxspeed formats
Then routability should be Then routability should be
@ -68,3 +68,20 @@ Feature: Bike - Max speed restrictions
| 1 | 10 | | run | snail | | 1 | 10 | | run | snail |
| 1 | | 10 | snail | run | | 1 | | 10 | snail | run |
| 1 | 5 | 10 | walk | run | | 1 | 5 | 10 | walk | run |
Scenario: Bike - Maxspeed should not allow routing on unroutable ways
Then routability should be
| highway | railway | access | maxspeed | maxspeed:forward | maxspeed:backward | bothw |
| primary | | | | | | x |
| secondary | | no | | | | |
| secondary | | no | 100 | | | |
| secondary | | no | | 100 | | |
| secondary | | no | | | 100 | |
| (nil) | train | | | | | |
| (nil) | train | | 100 | | | |
| (nil) | train | | | 100 | | |
| (nil) | train | | | | 100 | |
| runway | | | | | | |
| runway | | | 100 | | | |
| runway | | | | 100 | | |
| runway | | | | | 100 | |

View File

@ -52,3 +52,20 @@ Feature: Car - Max speed restrictions
| 1 | 10 | | run | snail | | 1 | 10 | | run | snail |
| 1 | | 10 | snail | run | | 1 | | 10 | snail | run |
| 1 | 5 | 10 | walk | run | | 1 | 5 | 10 | walk | run |
Scenario: Car - Maxspeed should not allow routing on unroutable ways
Then routability should be
| highway | railway | access | maxspeed | maxspeed:forward | maxspeed:backward | bothw |
| primary | | | | | | x |
| secondary | | no | | | | |
| secondary | | no | 100 | | | |
| secondary | | no | | 100 | | |
| secondary | | no | | | 100 | |
| (nil) | train | | | | | |
| (nil) | train | | 100 | | | |
| (nil) | train | | | 100 | | |
| (nil) | train | | | | 100 | |
| runway | | | | | | |
| runway | | | 100 | | | |
| runway | | | | 100 | | |
| runway | | | | | 100 | |

View File

@ -1,9 +1,9 @@
@routing @weird @routing @weird @todo
Feature: Weird routings discovered Feature: Weird routings discovered
Background: Background:
Given the profile "testbot" Given the profile "testbot"
Scenario: Routing on a oneway roundabout Scenario: Routing on a oneway roundabout
Given the node map Given the node map
| | d | c | | | | d | c | |
@ -39,4 +39,41 @@ Feature: Weird routings discovered
| f | e | fg,gh,ha,ab,bc,cd,de | | f | e | fg,gh,ha,ab,bc,cd,de |
| g | f | gh,ha,ab,bc,cd,de,ef | | g | f | gh,ha,ab,bc,cd,de,ef |
| h | g | ha,ab,bc,cd,de,ef,fg | | h | g | ha,ab,bc,cd,de,ef,fg |
| a | h | ab,bc,cd,de,ef,fg,gh | | a | h | ab,bc,cd,de,ef,fg,gh |
Scenario: Routing on a oneway roundabout
Given the node map
| | d | c | |
| e | | | b |
| f | | | a |
| | g | h | |
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
| cd | yes |
| de | yes |
| ef | yes |
| fg | yes |
| gh | yes |
| ha | yes |
When I route I should get
| from | to | route |
| a | b | ab |
| b | c | bc |
| c | d | cd |
| d | e | de |
| e | f | ef |
| f | g | fg |
| g | h | gh |
| h | a | ha |
| b | a | bc,cd,de,ef,fg,gh,ha |
| c | b | cd,de,ef,fg,gh,ha,ab |
| d | c | de,ef,fg,gh,ha,ab,bc |
| e | d | ef,fg,gh,ha,ab,bc,cd |
| f | e | fg,gh,ha,ab,bc,cd,de |
| g | f | gh,ha,ab,bc,cd,de,ef |
| h | g | ha,ab,bc,cd,de,ef,fg |
| a | h | ab,bc,cd,de,ef,fg,gh |

View File

@ -4,7 +4,7 @@ DEFAULT_PORT = 5000
puts "Ruby version #{RUBY_VERSION}" puts "Ruby version #{RUBY_VERSION}"
unless RUBY_VERSION =~ /^1.9/ unless RUBY_VERSION.to_f >= 1.9
raise "*** Please upgrade to Ruby 1.9.x to run the OSRM cucumber tests" raise "*** Please upgrade to Ruby 1.9.x to run the OSRM cucumber tests"
end end

View File

@ -1,5 +1,8 @@
require 'digest/sha1' require 'digest/sha1'
bin_extract_hash = nil
profile_hashes = nil
def hash_of_files paths def hash_of_files paths
paths = [paths] unless paths.is_a? Array paths = [paths] unless paths.is_a? Array
hash = Digest::SHA1.new hash = Digest::SHA1.new
@ -16,8 +19,8 @@ end
def profile_hash def profile_hash
@@profile_hashes ||= {} profile_hashes ||= {}
@@profile_hashes[@profile] ||= hash_of_files "#{PROFILES_PATH}/#{@profile}.lua" profile_hashes[@profile] ||= hash_of_files "#{PROFILES_PATH}/#{@profile}.lua"
end end
def osm_hash def osm_hash
@ -29,15 +32,15 @@ def lua_lib_hash
end end
def bin_extract_hash def bin_extract_hash
@@bin_extract_hash ||= hash_of_files "#{BIN_PATH}/osrm-extract" bin_extract_hash ||= hash_of_files "#{BIN_PATH}/osrm-extract"
end end
def bin_prepare_hash def bin_prepare_hash
@@bin_prepare_hash ||= hash_of_files "#{BIN_PATH}/osrm-prepare" bin_prepare_hash ||= hash_of_files "#{BIN_PATH}/osrm-prepare"
end end
def bin_routed_hash def bin_routed_hash
@@bin_routed_hash ||= hash_of_files "#{BIN_PATH}/osrm-routed" bin_routed_hash ||= hash_of_files "#{BIN_PATH}/osrm-routed"
end end
#combine state of data, profile and binaries into a hash that identifies the exact test scenario #combine state of data, profile and binaries into a hash that identifies the exact test scenario

View File

@ -1,23 +1,25 @@
require 'OSM/StreamParser' require 'OSM/StreamParser'
locations = nil
class OSMTestParserCallbacks < OSM::Callbacks class OSMTestParserCallbacks < OSM::Callbacks
@@locations = nil locations = nil
def self.locations def self.locations
if @@locations if locations
@@locations locations
else else
#parse the test file, so we can later reference nodes and ways by name in tests #parse the test file, so we can later reference nodes and ways by name in tests
@@locations = {} locations = {}
file = 'test/data/test.osm' file = 'test/data/test.osm'
callbacks = OSMTestParserCallbacks.new callbacks = OSMTestParserCallbacks.new
parser = OSM::StreamParser.new(:filename => file, :callbacks => callbacks) parser = OSM::StreamParser.new(:filename => file, :callbacks => callbacks)
parser.parse parser.parse
puts @@locations puts locations
end end
end end
def node(node) def node(node)
@@locations[node.name] = [node.lat,node.lon] locations[node.name] = [node.lat,node.lon]
end end
end end

View File

@ -1,27 +1,27 @@
@routing @basic @routing @basic
Feature: Basic Routing Feature: Basic Routing
Background: Background:
Given the profile "testbot" Given the profile "testbot"
@smallest @smallest
Scenario: A single way with two nodes Scenario: A single way with two nodes
Given the node map Given the node map
| a | b | | a | b |
And the ways And the ways
| nodes | | nodes |
| ab | | ab |
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | b | ab | | a | b | ab |
| b | a | ab | | b | a | ab |
Scenario: Routing in between two nodes of way Scenario: Routing in between two nodes of way
Given the node map Given the node map
| a | b | 1 | 2 | c | d | | a | b | 1 | 2 | c | d |
And the ways And the ways
| nodes | | nodes |
| abcd | | abcd |
@ -57,12 +57,12 @@ Feature: Basic Routing
Scenario: Two ways connected in a straight line Scenario: Two ways connected in a straight line
Given the node map Given the node map
| a | b | c | | a | b | c |
And the ways And the ways
| nodes | | nodes |
| ab | | ab |
| bc | | bc |
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | c | ab,bc | | a | c | ab,bc |
@ -71,17 +71,17 @@ Feature: Basic Routing
| b | a | ab | | b | a | ab |
| b | c | bc | | b | c | bc |
| c | b | bc | | c | b | bc |
Scenario: 2 unconnected parallel ways Scenario: 2 unconnected parallel ways
Given the node map Given the node map
| a | b | c | | a | b | c |
| d | e | f | | d | e | f |
And the ways And the ways
| nodes | | nodes |
| abc | | abc |
| def | | def |
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | b | abc | | a | b | abc |
@ -122,7 +122,7 @@ Feature: Basic Routing
| ab | | ab |
| bc | | bc |
| ca | | ca |
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | b | ab | | a | b | ab |
@ -154,7 +154,7 @@ Feature: Basic Routing
| cv | | cv |
| vw | | vw |
| wc | | wc |
When I route I should get When I route I should get
| from | to | route | | from | to | route |
| a | b | ab | | a | b | ab |
@ -183,7 +183,7 @@ Feature: Basic Routing
| c | a | abc | | c | a | abc |
| c | e | cde | | c | e | cde |
| e | c | cde | | e | c | cde |
Scenario: Grid city center Scenario: Grid city center
Given the node map Given the node map
| a | b | c | d | | a | b | c | d |
@ -233,40 +233,3 @@ Feature: Basic Routing
| d | a | abcd | | d | a | abcd |
| a | m | aeim | | a | m | aeim |
| m | a | aeim | | m | a | aeim |
Scenario: Routing on a oneway roundabout
Given the node map
| | d | c | |
| e | | | b |
| f | | | a |
| | g | h | |
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
| cd | yes |
| de | yes |
| ef | yes |
| fg | yes |
| gh | yes |
| ha | yes |
When I route I should get
| from | to | route |
| a | b | ab |
| b | c | bc |
| c | d | cd |
| d | e | de |
| e | f | ef |
| f | g | fg |
| g | h | gh |
| h | a | ha |
| b | a | bc,cd,de,ef,fg,gh,ha |
| c | b | cd,de,ef,fg,gh,ha,ab |
| d | c | de,ef,fg,gh,ha,ab,bc |
| e | d | ef,fg,gh,ha,ab,bc,cd |
| f | e | fg,gh,ha,ab,bc,cd,de |
| g | f | gh,ha,ab,bc,cd,de,ef |
| h | g | ha,ab,bc,cd,de,ef,fg |
| a | h | ab,bc,cd,de,ef,fg,gh |

View File

@ -3,13 +3,13 @@ Feature: Durations
Background: Background:
Given the profile "testbot" Given the profile "testbot"
Scenario: Duration of ways Scenario: Duration of ways
Given the node map Given the node map
| a | b | | | | f | | a | b | | | | f |
| | | | e | | | | | | | e | | |
| | c | | | d | | | | c | | | d | |
And the ways And the ways
| nodes | highway | duration | | nodes | highway | duration |
| ab | primary | 0:01 | | ab | primary | 0:01 |
@ -23,9 +23,9 @@ Feature: Durations
| a | b | ab | 100m +-1 | 60s +-1 | | a | b | ab | 100m +-1 | 60s +-1 |
| b | c | bc | 200m +-1 | 600s +-1 | | b | c | bc | 200m +-1 | 600s +-1 |
| c | d | cd | 300m +-1 | 3600s +-1 | | c | d | cd | 300m +-1 | 3600s +-1 |
| d | e | de | 144m +-2 | 36000s +-1 | | d | e | de | 141m +-2 | 36000s +-1 |
| e | f | ef | 224m +-2 | 3723s +-1 | | e | f | ef | 224m +-2 | 3723s +-1 |
@todo @todo
Scenario: Partial duration of ways Scenario: Partial duration of ways
Given the node map Given the node map

View File

@ -1,18 +1,18 @@
@routing @testbot @opposite @routing @testbot @opposite
Feature: Separate settings for forward/backward direction Feature: Separate settings for forward/backward direction
Background: Background:
Given the profile "testbot" Given the profile "testbot"
Scenario: Testbot - Going against the flow Scenario: Testbot - Going against the flow
Given the node map Given the node map
| a | b | c | d | | a | b | c | d |
And the ways And the ways
| nodes | highway | | nodes | highway |
| abcd | river | | abcd | river |
When I route I should get When I route I should get
| from | to | route | distance | time | | from | to | route | distance | time |
| a | d | abcd | 300 +- 1m | 30s | | a | d | abcd | 300 +- 1m | 31s |
| d | a | abcd | 300 +- 1m | 68s | | d | a | abcd | 300 +- 1m | 68s |

View File

@ -14,7 +14,7 @@ default_speed = 15
walking_speed = 6 walking_speed = 6
bicycle_speeds = { bicycle_speeds = {
["cycleway"] = default_speed, ["cycleway"] = default_speed,
["primary"] = default_speed, ["primary"] = default_speed,
["primary_link"] = default_speed, ["primary_link"] = default_speed,
@ -33,13 +33,13 @@ bicycle_speeds = {
--["pedestrian"] = 12, --["pedestrian"] = 12,
} }
pedestrian_speeds = { pedestrian_speeds = {
["footway"] = walking_speed, ["footway"] = walking_speed,
["pedestrian"] = walking_speed, ["pedestrian"] = walking_speed,
["steps"] = 2 ["steps"] = 2
} }
railway_speeds = { railway_speeds = {
["train"] = 10, ["train"] = 10,
["railway"] = 10, ["railway"] = 10,
["subway"] = 10, ["subway"] = 10,
@ -48,24 +48,24 @@ railway_speeds = {
["tram"] = 10 ["tram"] = 10
} }
platform_speeds = { platform_speeds = {
["platform"] = walking_speed ["platform"] = walking_speed
} }
amenity_speeds = { amenity_speeds = {
["parking"] = 10, ["parking"] = 10,
["parking_entrance"] = 10 ["parking_entrance"] = 10
} }
man_made_speeds = { man_made_speeds = {
["pier"] = walking_speed ["pier"] = walking_speed
} }
route_speeds = { route_speeds = {
["ferry"] = 5 ["ferry"] = 5
} }
surface_speeds = { surface_speeds = {
["cobblestone:flattened"] = 10, ["cobblestone:flattened"] = 10,
["paving_stones"] = 10, ["paving_stones"] = 10,
["compacted"] = 10, ["compacted"] = 10,
@ -80,7 +80,7 @@ surface_speeds = {
["earth"] = 6, ["earth"] = 6,
["grass"] = 6, ["grass"] = 6,
["mud"] = 3, ["mud"] = 3,
["sand"] = 3 ["sand"] = 3
} }
take_minimum_of_speeds = true take_minimum_of_speeds = true
@ -96,7 +96,7 @@ turn_bias = 1.4
-- End of globals -- End of globals
function get_exceptions(vector) function get_exceptions(vector)
for i,v in ipairs(restriction_exception_tags) do for i,v in ipairs(restriction_exception_tags) do
vector:Add(v) vector:Add(v)
end end
end end
@ -105,12 +105,12 @@ function node_function (node)
local barrier = node.tags:Find ("barrier") local barrier = node.tags:Find ("barrier")
local access = Access.find_access_tag(node, access_tags_hierachy) local access = Access.find_access_tag(node, access_tags_hierachy)
local traffic_signal = node.tags:Find("highway") local traffic_signal = node.tags:Find("highway")
-- flag node if it carries a traffic light -- flag node if it carries a traffic light
if traffic_signal == "traffic_signals" then if traffic_signal == "traffic_signals" then
node.traffic_light = true node.traffic_light = true
end end
-- parse access and barrier tags -- parse access and barrier tags
if access and access ~= "" then if access and access ~= "" then
if access_tag_blacklist[access] then if access_tag_blacklist[access] then
@ -125,7 +125,7 @@ function node_function (node)
node.bollard = true node.bollard = true
end end
end end
return 1 return 1
end end
@ -137,21 +137,21 @@ function way_function (way)
local railway = way.tags:Find("railway") local railway = way.tags:Find("railway")
local amenity = way.tags:Find("amenity") local amenity = way.tags:Find("amenity")
local public_transport = way.tags:Find("public_transport") local public_transport = way.tags:Find("public_transport")
if (not highway or highway == '') and if (not highway or highway == '') and
(not route or route == '') and (not route or route == '') and
(not railway or railway=='') and (not railway or railway=='') and
(not amenity or amenity=='') and (not amenity or amenity=='') and
(not man_made or man_made=='') and (not man_made or man_made=='') and
(not public_transport or public_transport=='') (not public_transport or public_transport=='')
then then
return 0 return 0
end end
-- don't route on ways or railways that are still under construction -- don't route on ways or railways that are still under construction
if highway=='construction' or railway=='construction' then if highway=='construction' or railway=='construction' then
return 0 return 0
end end
-- access -- access
local access = Access.find_access_tag(way, access_tags_hierachy) local access = Access.find_access_tag(way, access_tags_hierachy)
if access_tag_blacklist[access] then if access_tag_blacklist[access] then
@ -178,7 +178,7 @@ function way_function (way)
local foot = way.tags:Find("foot") local foot = way.tags:Find("foot")
local surface = way.tags:Find("surface") local surface = way.tags:Find("surface")
-- name -- name
if "" ~= ref and "" ~= name then if "" ~= ref and "" ~= name then
way.name = name .. ' / ' .. ref way.name = name .. ' / ' .. ref
elseif "" ~= ref then elseif "" ~= ref then
@ -214,7 +214,7 @@ function way_function (way)
elseif railway and railway_speeds[railway] then elseif railway and railway_speeds[railway] then
-- railways -- railways
if access and access_tag_whitelist[access] then if access and access_tag_whitelist[access] then
way.speed = railway_speeds[railway] way.speed = railway_speeds[railway]
way.direction = Way.bidirectional way.direction = Way.bidirectional
end end
elseif amenity and amenity_speeds[amenity] then elseif amenity and amenity_speeds[amenity] then
@ -242,7 +242,7 @@ function way_function (way)
end end
end end
end end
-- direction -- direction
way.direction = Way.bidirectional way.direction = Way.bidirectional
local impliedOneway = false local impliedOneway = false
@ -250,7 +250,7 @@ function way_function (way)
way.direction = Way.oneway way.direction = Way.oneway
impliedOneway = true impliedOneway = true
end end
if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then
way.direction = Way.oneway way.direction = Way.oneway
elseif onewayClass == "no" or onewayClass == "0" or onewayClass == "false" then elseif onewayClass == "no" or onewayClass == "0" or onewayClass == "false" then
@ -284,7 +284,7 @@ function way_function (way)
elseif oneway == "yes" or oneway == "1" or oneway == "true" then elseif oneway == "yes" or oneway == "1" or oneway == "true" then
way.direction = Way.oneway way.direction = Way.oneway
end end
-- pushing bikes -- pushing bikes
if bicycle_speeds[highway] or pedestrian_speeds[highway] then if bicycle_speeds[highway] or pedestrian_speeds[highway] then
if foot ~= 'no' then if foot ~= 'no' then
@ -303,7 +303,7 @@ function way_function (way)
end end
end end
-- cycleways -- cycleways
if cycleway and cycleway_tags[cycleway] then if cycleway and cycleway_tags[cycleway] then
way.speed = bicycle_speeds["cycleway"] way.speed = bicycle_speeds["cycleway"]
@ -312,7 +312,7 @@ function way_function (way)
elseif cycleway_right and cycleway_tags[cycleway_right] then elseif cycleway_right and cycleway_tags[cycleway_right] then
way.speed = bicycle_speeds["cycleway"] way.speed = bicycle_speeds["cycleway"]
end end
-- surfaces -- surfaces
if surface then if surface then
surface_speed = surface_speeds[surface] surface_speed = surface_speeds[surface]
@ -331,7 +331,7 @@ function way_function (way)
end end
-- Override speed settings if explicit forward/backward maxspeeds are given -- Override speed settings if explicit forward/backward maxspeeds are given
if maxspeed_forward ~= nil and maxspeed_forward > 0 then if way.speed > 0 and maxspeed_forward ~= nil and maxspeed_forward > 0 then
if Way.bidirectional == way.direction then if Way.bidirectional == way.direction then
way.backward_speed = way.speed way.backward_speed = way.speed
end end
@ -342,7 +342,7 @@ function way_function (way)
end end
way.type = 1 way.type = 1
return 1 return 1
end end

View File

@ -197,7 +197,7 @@ function way_function (way)
end end
-- Override speed settings if explicit forward/backward maxspeeds are given -- Override speed settings if explicit forward/backward maxspeeds are given
if maxspeed_forward ~= nil and maxspeed_forward > 0 then if way.speed > 0 and maxspeed_forward ~= nil and maxspeed_forward > 0 then
if Way.bidirectional == way.direction then if Way.bidirectional == way.direction then
way.backward_speed = way.speed way.backward_speed = way.speed
end end
@ -211,7 +211,6 @@ function way_function (way)
if ignore_in_grid[highway] ~= nil and ignore_in_grid[highway] then if ignore_in_grid[highway] ~= nil and ignore_in_grid[highway] then
way.ignore_in_grid = true way.ignore_in_grid = true
end end
way.type = 1 way.type = 1
return 1 return 1
end end

View File

@ -23,9 +23,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "Server/ServerFactory.h" #include "Server/ServerFactory.h"
#include "Util/BaseConfiguration.h" #include "Util/IniFile.h"
#include "Util/InputFileUtil.h" #include "Util/InputFileUtil.h"
#include "Util/OpenMPWrapper.h" #include "Util/OpenMPWrapper.h"
#include "Util/SimpleLogger.h"
#include "Util/UUID.h" #include "Util/UUID.h"
#ifdef __linux__ #ifdef __linux__
@ -61,9 +62,12 @@ BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
#endif #endif
int main (int argc, char * argv[]) { int main (int argc, char * argv[]) {
try {
LogPolicy::GetInstance().Unmute();
#ifdef __linux__ #ifdef __linux__
if(!mlockall(MCL_CURRENT | MCL_FUTURE)) if(!mlockall(MCL_CURRENT | MCL_FUTURE)) {
WARN("Process " << argv[0] << "could not be locked to RAM"); SimpleLogger().Write(logWARNING) << "Process " << argv[0] << "could not be locked to RAM";
}
#endif #endif
#ifdef __linux__ #ifdef __linux__
@ -77,11 +81,10 @@ int main (int argc, char * argv[]) {
//exit(-1); //exit(-1);
//} //}
try {
//std::cout << "fingerprint: " << UUID::GetInstance().GetUUID() << std::endl; //std::cout << "fingerprint: " << UUID::GetInstance().GetUUID() << std::endl;
std::cout << "starting up engines, compiled at " << SimpleLogger().Write() <<
__DATE__ << ", " __TIME__ << std::endl; "starting up engines, compiled at " << __DATE__ << ", " __TIME__;
#ifndef _WIN32 #ifndef _WIN32
int sig = 0; int sig = 0;
@ -91,7 +94,7 @@ int main (int argc, char * argv[]) {
pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
#endif #endif
BaseConfiguration serverConfig((argc > 1 ? argv[1] : "server.ini")); IniFile serverConfig((argc > 1 ? argv[1] : "server.ini"));
OSRM routing_machine((argc > 1 ? argv[1] : "server.ini")); OSRM routing_machine((argc > 1 ? argv[1] : "server.ini"));
Server * s = ServerFactory::CreateServer(serverConfig); Server * s = ServerFactory::CreateServer(serverConfig);
@ -122,7 +125,7 @@ int main (int argc, char * argv[]) {
std::cout << "[server] stopping threads" << std::endl; std::cout << "[server] stopping threads" << std::endl;
if(!t.timed_join(boost::posix_time::seconds(2))) { if(!t.timed_join(boost::posix_time::seconds(2))) {
// INFO("Threads did not finish within 2 seconds. Hard abort!"); SimpleLogger().Write(logDEBUG) << "Threads did not finish within 2 seconds. Hard abort!";
} }
std::cout << "[server] freeing objects" << std::endl; std::cout << "[server] freeing objects" << std::endl;

View File

@ -33,30 +33,20 @@ or see http://www.gnu.org/licenses/agpl.txt.
#endif #endif
#include <iostream> #include <iostream>
#include <ostream>
#define INFO(x) do {std::cout << "[i " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0); // Necessary workaround for Windows as VS doesn't implement C99
#define ERR(x) do {std::cerr << "[! " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl; std::exit(-1);} while(0); #ifdef _MSC_VER
#define WARN(x) do {std::cerr << "[? " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0);
#ifdef NDEBUG
#define DEBUG(x)
#else
#define DEBUG(x) do {std::cout << "[d " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0);
#endif
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
#endif #endif
// Necessary workaround for Windows as VS doesn't implement C99
#ifdef _MSC_VER
template<typename digitT> template<typename digitT>
digitT round(digitT x) { digitT round(digitT x) {
return std::floor(x + 0.5); return std::floor(x + 0.5);
} }
#endif #endif
typedef unsigned int NodeID; typedef unsigned int NodeID;
typedef unsigned int EdgeID; typedef unsigned int EdgeID;
typedef unsigned int EdgeWeight; typedef unsigned int EdgeWeight;