diff --git a/.travis.yml b/.travis.yml index 5d2da251c..d276e287b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_script: - bundle install - mkdir build - cd build - - cmake .. + - cmake .. $CMAKEOPTIONS script: make after_script: - cd .. @@ -20,8 +20,8 @@ branches: - master - develop env: - - OPTIONS="-DCMAKE_BUILD_TYPE=Release" - - OPTIONS="-DCMAKE_BUILD_TYPE=Debug" + - CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release" + - CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug" notifications: irc: channels: diff --git a/Algorithms/CRC32.cpp b/Algorithms/CRC32.cpp index d2f821cb4..cb72e85c6 100644 --- a/Algorithms/CRC32.cpp +++ b/Algorithms/CRC32.cpp @@ -62,10 +62,10 @@ CRC32::CRC32CFunctionPtr CRC32::detectBestCRC32C() { unsigned ecx = cpuid(1); bool hasSSE42 = ecx & (1 << SSE42_BIT); if (hasSSE42) { - std::cout << "using hardware base sse computation" << std::endl; + SimpleLogger().Write() << "using hardware base sse computation"; return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated; } else { - std::cout << "using software base sse computation" << std::endl; + SimpleLogger().Write() << "using software base sse computation"; return &CRC32::SoftwareBasedCRC32; //crc32cSlicingBy8; } } diff --git a/Algorithms/CRC32.h b/Algorithms/CRC32.h index 6321030b7..fb7e50613 100644 --- a/Algorithms/CRC32.h +++ b/Algorithms/CRC32.h @@ -21,6 +21,8 @@ #ifndef CRC32_H_ #define CRC32_H_ +#include "../Util/SimpleLogger.h" + #include // for boost::crc_32_type #include diff --git a/Algorithms/IteratorBasedCRC32.h b/Algorithms/IteratorBasedCRC32.h index 5d4415cb5..55a8f8084 100644 --- a/Algorithms/IteratorBasedCRC32.h +++ b/Algorithms/IteratorBasedCRC32.h @@ -22,6 +22,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef ITERATORBASEDCRC32_H_ #define ITERATORBASEDCRC32_H_ +#include "../Util/SimpleLogger.h" + #include // for boost::crc_32_type #include @@ -80,10 +82,10 @@ private: unsigned ecx = cpuid(1); bool hasSSE42 = ecx & (1 << SSE42_BIT); if (hasSSE42) { - std::cout << "using hardware base sse computation" << std::endl; + SimpleLogger().Write() << "using hardware based CRC32 computation"; return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated; } else { - std::cout << "using software base sse computation" << std::endl; + SimpleLogger().Write() << "using software based CRC32 computation"; return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8; } } @@ -93,7 +95,7 @@ public: crcFunction = detectBestCRC32C(); } - virtual ~IteratorbasedCRC32() {}; + virtual ~IteratorbasedCRC32() { } unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) { unsigned crc = 0; diff --git a/Algorithms/PolylineCompressor.h b/Algorithms/PolylineCompressor.h index db90ef6ff..3e14c6639 100644 --- a/Algorithms/PolylineCompressor.h +++ b/Algorithms/PolylineCompressor.h @@ -56,11 +56,14 @@ private: } public: - inline void printEncodedString(const std::vector& polyline, std::string &output) const { + inline void printEncodedString( + const std::vector & polyline, + std::string & output + ) const { std::vector deltaNumbers; output += "\""; if(!polyline.empty()) { - _Coordinate lastCoordinate = polyline[0].location; + FixedPointCoordinate lastCoordinate = polyline[0].location; deltaNumbers.push_back( lastCoordinate.lat ); deltaNumbers.push_back( lastCoordinate.lon ); 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& polyline, std::string &output) const { std::vector deltaNumbers(2*polyline.size()); output += "\""; if(!polyline.empty()) { @@ -91,7 +94,7 @@ public: output += "\""; } - inline void printUnencodedString(std::vector<_Coordinate> & polyline, std::string & output) const { + inline void printUnencodedString(std::vector & polyline, std::string & output) const { output += "["; std::string tmp; for(unsigned i = 0; i < polyline.size(); i++) { diff --git a/Algorithms/StronglyConnectedComponents.h b/Algorithms/StronglyConnectedComponents.h index 4ef81e90f..f2376727e 100644 --- a/Algorithms/StronglyConnectedComponents.h +++ b/Algorithms/StronglyConnectedComponents.h @@ -28,11 +28,13 @@ Strongly connected components using Tarjan's Algorithm #include "../DataStructures/DeallocatingVector.h" #include "../DataStructures/DynamicGraph.h" #include "../DataStructures/ImportEdge.h" -#include "../DataStructures/NodeCoords.h" +#include "../DataStructures/QueryNode.h" #include "../DataStructures/Percent.h" #include "../DataStructures/Restriction.h" #include "../DataStructures/TurnInstructions.h" +#include "../Util/SimpleLogger.h" + #include #include #include @@ -116,9 +118,21 @@ private: DeallocatingVector edgeBasedNodes; public: - TarjanSCC(int nodes, std::vector & inputEdges, std::vector & bn, std::vector & tl, std::vector<_Restriction> & irs, std::vector & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) { - BOOST_FOREACH(_Restriction & restriction, irs) { - std::pair restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); + TarjanSCC( + int nodes, + std::vector & inputEdges, + std::vector & bn, + std::vector & tl, + std::vector & irs, + std::vector & nI + ) : + inputNodeInfoList(nI), + numberOfTurnRestrictions(irs.size()) + { + BOOST_FOREACH(const TurnRestriction & restriction, irs) { + std::pair restrictionSource = std::make_pair( + restriction.fromNode, restriction.viaNode + ); unsigned index; RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); 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) { @@ -243,7 +259,7 @@ public: bool beforeRecursion = recursionStack.top().first; TarjanStackFrame currentFrame = recursionStack.top().second; NodeID v = currentFrame.v; -// INFO("popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion"); +// SimpleLogger().Write() << "popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion"; recursionStack.pop(); if(beforeRecursion) { @@ -256,45 +272,45 @@ public: tarjanStack.push(v); tarjanNodes[v].onStack = true; ++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 for(TarjanDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { TarjanDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2); -// INFO("traversing edge (" << v << "," << vprime << ")"); +// SimpleLogger().Write() << "traversing edge (" << v << "," << vprime << ")"; if(UINT_MAX == tarjanNodes[vprime].index) { recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v))); } else { -// INFO("Node " << vprime << " is already explored"); +// SimpleLogger().Write() << "Node " << vprime << " is already explored"; if(tarjanNodes[vprime].onStack) { 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; // } else { -// INFO("But node " << vprime << " is not on stack"); +// SimpleLogger().Write() << "But node " << vprime << " is not on stack"; } } } } 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 // NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent ); -// INFO("parent=" << currentFrame.parent); -// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink); +// SimpleLogger().Write() << "parent=" << currentFrame.parent; +// 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 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 //Check if we found a cycle. This is the bottom part of the recursion if(tarjanNodes[v].lowlink == tarjanNodes[v].index) { NodeID vprime; do { -// INFO("identified component " << currentComponent << ": " << tarjanStack.top()); +// SimpleLogger().Write() << "identified component " << currentComponent << ": " << tarjanStack.top(); vprime = tarjanStack.top(); tarjanStack.pop(); tarjanNodes[vprime].onStack = false; componentsIndex[vprime] = currentComponent; @@ -302,7 +318,7 @@ public: } while( v != vprime); vectorOfComponentSizes.push_back(sizeOfCurrentComponent); if(sizeOfCurrentComponent > 1000) - INFO("large component [" << currentComponent << "]=" << sizeOfCurrentComponent); + SimpleLogger().Write() << "large component [" << currentComponent << "]=" << sizeOfCurrentComponent; ++currentComponent; 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; for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){ if(1 == vectorOfComponentSizes[i]) ++singleCounter; } - INFO("identified " << singleCounter << " SCCs of size 1"); + SimpleLogger().Write() << "identified " << singleCounter << " SCCs of size 1"; uint64_t total_network_distance = 0; p.reinit(_nodeBasedGraph->GetNumberOfNodes()); 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 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; - lineString.addPoint(inputNodeInfoList[u].lon/100000., inputNodeInfoList[u].lat/100000.); - lineString.addPoint(inputNodeInfoList[v].lon/100000., inputNodeInfoList[v].lat/100000.); + lineString.addPoint(inputNodeInfoList[u].lon/COORDINATE_PRECISION, inputNodeInfoList[u].lat/COORDINATE_PRECISION); + lineString.addPoint(inputNodeInfoList[v].lon/COORDINATE_PRECISION, inputNodeInfoList[v].lat/COORDINATE_PRECISION); OGRFeature *poFeature; poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() ); poFeature->SetGeometry( &lineString ); - if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) - { - ERR( "Failed to create feature in shapefile.\n" ); + if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) { + throw OSRMException( + "Failed to create feature in shapefile." + ); } OGRFeature::DestroyFeature( poFeature ); } @@ -362,7 +379,7 @@ public: OGRDataSource::DestroyDataSource( poDS ); std::vector().swap(vectorOfComponentSizes); std::vector().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: unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const { diff --git a/CMakeLists.txt b/CMakeLists.txt index b17f1149a..7d047faa6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 2.6) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project(OSRM) include(FindPackageHandleStandardArgs) diff --git a/Contractor/ContractionCleanup.h b/Contractor/ContractionCleanup.h deleted file mode 100644 index e42dad3a7..000000000 --- a/Contractor/ContractionCleanup.h +++ /dev/null @@ -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 -#ifndef _WIN32 -#include -#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::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 diff --git a/Contractor/Contractor.h b/Contractor/Contractor.h index 18bee5de6..1ffc0435b 100644 --- a/Contractor/Contractor.h +++ b/Contractor/Contractor.h @@ -29,6 +29,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../DataStructures/XORFastHash.h" #include "../DataStructures/XORFastHashStorage.h" #include "../Util/OpenMPWrapper.h" +#include "../Util/SimpleLogger.h" #include "../Util/StringUtil.h" #include @@ -124,7 +125,8 @@ public: BOOST_ASSERT_MSG( newEdge.data.distance > 0, "edge distance < 1" ); #ifndef NDEBUG 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 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) { - // INFO(" ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via); + // SimpleLogger().Write() << " ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via; // } //Create temporary file @@ -430,19 +432,20 @@ public: // avgdegree /= 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); } - BOOST_FOREACH(_ThreadData * data, threadData) + BOOST_FOREACH(_ThreadData * data, threadData) { delete data; + } threadData.clear(); } template< class Edge > inline void GetEdges( DeallocatingVector< Edge >& edges ) { Percent p (_graph->GetNumberOfNodes()); - INFO("Getting edges of minimized graph"); + SimpleLogger().Write() << "Getting edges of minimized graph"; NodeID numberOfNodes = _graph->GetNumberOfNodes(); if(_graph->GetNumberOfNodes()) { for ( NodeID node = 0; node < numberOfNodes; ++node ) { diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index 13f49ecb7..8d71db190 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -20,188 +20,262 @@ #include "EdgeBasedGraphFactory.h" -template<> -EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector & inputEdges, std::vector & bn, std::vector & tl, std::vector<_Restriction> & irs, std::vector & nI, SpeedProfileProperties sp) : speedProfile(sp), inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) { - BOOST_FOREACH(const _Restriction & restriction, irs) { - std::pair restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); +EdgeBasedGraphFactory::EdgeBasedGraphFactory( + int number_of_nodes, + std::vector & input_edge_list, + std::vector & barrier_node_list, + std::vector & traffic_light_node_list, + std::vector & input_restrictions_list, + std::vector & 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 restriction_source = + std::make_pair(restriction.fromNode, restriction.viaNode); unsigned index; - RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); - if(restrIter == _restrictionMap.end()) { - index = _restrictionBucketVector.size(); - _restrictionBucketVector.resize(index+1); - _restrictionMap[restrictionSource] = index; + RestrictionMap::iterator restriction_iter = m_restriction_map.find(restriction_source); + if(restriction_iter == m_restriction_map.end()) { + index = m_restriction_bucket_list.size(); + m_restriction_bucket_list.resize(index+1); + m_restriction_map[restriction_source] = index; } else { - index = restrIter->second; + index = restriction_iter->second; //Map already contains an is_only_*-restriction - if(_restrictionBucketVector.at(index).begin()->second) + if(m_restriction_bucket_list.at(index).begin()->second) { 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. - _restrictionBucketVector.at(index).clear(); + m_turn_restrictions_count -= m_restriction_bucket_list.at(index).size(); + m_restriction_bucket_list.at(index).clear(); } } - - _restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly)); + ++m_turn_restrictions_count; + m_restriction_bucket_list.at(index).push_back( + std::make_pair( restriction.toNode, restriction.flags.isOnly) + ); } - _barrierNodes.insert(bn.begin(), bn.end()); - _trafficLights.insert(tl.begin(), tl.end()); + m_barrier_nodes.insert( + barrier_node_list.begin(), + barrier_node_list.end() + ); - DeallocatingVector< _NodeBasedEdge > edges; - _NodeBasedEdge edge; - for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) { - if(!i->isForward()) { - edge.source = i->target(); - edge.target = i->source(); - edge.data.backward = i->isForward(); - edge.data.forward = i->isBackward(); + m_traffic_lights.insert( + traffic_light_node_list.begin(), + traffic_light_node_list.end() + ); + + DeallocatingVector< NodeBasedEdge > edges_list; + NodeBasedEdge edge; + 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 { - edge.source = i->source(); - edge.target = i->target(); - edge.data.forward = i->isForward(); - edge.data.backward = i->isBackward(); + edge.source = import_edge.source(); + edge.target = import_edge.target(); + edge.data.forward = import_edge.isForward(); + edge.data.backward = import_edge.isBackward(); } if(edge.source == edge.target) { 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 ); edge.data.shortcut = false; - edge.data.roundabout = i->isRoundabout(); - edge.data.ignoreInGrid = i->ignoreInGrid(); - edge.data.nameID = i->name(); - edge.data.type = i->type(); - edge.data.isAccessRestricted = i->isAccessRestricted(); - edge.data.edgeBasedNodeID = edges.size(); - edge.data.contraFlow = i->isContraFlow(); - edges.push_back( edge ); + edge.data.roundabout = import_edge.isRoundabout(); + edge.data.ignoreInGrid = import_edge.ignoreInGrid(); + edge.data.nameID = import_edge.name(); + edge.data.type = import_edge.type(); + edge.data.isAccessRestricted = import_edge.isAccessRestricted(); + edge.data.edgeBasedNodeID = edges_list.size(); + edge.data.contraFlow = import_edge.isContraFlow(); + edges_list.push_back( edge ); if( edge.data.backward ) { std::swap( edge.source, edge.target ); - edge.data.forward = i->isBackward(); - edge.data.backward = i->isForward(); - edge.data.edgeBasedNodeID = edges.size(); - edges.push_back( edge ); + edge.data.forward = import_edge.isBackward(); + edge.data.backward = import_edge.isForward(); + edge.data.edgeBasedNodeID = edges_list.size(); + edges_list.push_back( edge ); } } - std::vector().swap(inputEdges); - std::sort( edges.begin(), edges.end() ); - _nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges ); + std::vector().swap(input_edge_list); + std::sort( edges_list.begin(), edges_list.end() ); + m_node_based_graph = boost::make_shared( + number_of_nodes, edges_list + ); } -void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) { +void EdgeBasedGraphFactory::GetEdgeBasedEdges( + DeallocatingVector< EdgeBasedEdge >& output_edge_list +) { BOOST_ASSERT_MSG( - 0 == outputEdgeList.size(), + 0 == output_edge_list.size(), "Vector is not empty" ); - edgeBasedEdges.swap(outputEdgeList); + m_edge_based_edge_list.swap(output_edge_list); } void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector & nodes) { #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.lat2 != INT_MAX); assert(node.lon2 != INT_MAX); } #endif - nodes.swap(edgeBasedNodes); + nodes.swap(m_edge_based_node_list); } -NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const { - std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); - RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); - if (restrIter != _restrictionMap.end()) { - unsigned index = restrIter->second; - BOOST_FOREACH(const RestrictionSource & restrictionTarget, _restrictionBucketVector.at(index)) { - if(restrictionTarget.second) { - return restrictionTarget.first; +NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn( + const NodeID u, + const NodeID v +) const { + const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v); + RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source); + if (restriction_iter != m_restriction_map.end()) { + 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; } -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. - std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); - RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); - if (restrIter != _restrictionMap.end()) { - unsigned index = restrIter->second; - BOOST_FOREACH(RestrictionTarget restrictionTarget, _restrictionBucketVector.at(index)) { - if(w == restrictionTarget.first) + const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v); + RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source); + if (restriction_iter != m_restriction_map.end()) { + const unsigned index = restriction_iter->second; + BOOST_FOREACH( + const RestrictionTarget & restriction_target, + m_restriction_bucket_list.at(index) + ) { + if(w == restriction_target.first) { return true; + } } } return false; } void EdgeBasedGraphFactory::InsertEdgeBasedNode( - _NodeBasedDynamicGraph::EdgeIterator e1, - _NodeBasedDynamicGraph::NodeIterator u, - _NodeBasedDynamicGraph::NodeIterator v, + EdgeIterator e1, + NodeIterator u, + NodeIterator v, bool belongsToTinyComponent) { - _NodeBasedDynamicGraph::EdgeData & data = _nodeBasedGraph->GetEdgeData(e1); + EdgeData & data = m_node_based_graph->GetEdgeData(e1); EdgeBasedNode currentNode; currentNode.nameID = data.nameID; - currentNode.lat1 = inputNodeInfoList[u].lat; - currentNode.lon1 = inputNodeInfoList[u].lon; - currentNode.lat2 = inputNodeInfoList[v].lat; - currentNode.lon2 = inputNodeInfoList[v].lon; + currentNode.lat1 = m_node_info_list[u].lat; + currentNode.lon1 = m_node_info_list[u].lon; + currentNode.lat2 = m_node_info_list[v].lat; + currentNode.lon2 = m_node_info_list[v].lon; currentNode.belongsToTinyComponent = belongsToTinyComponent; currentNode.id = data.edgeBasedNodeID; currentNode.ignoreInGrid = data.ignoreInGrid; 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) { - Percent p(_nodeBasedGraph->GetNumberOfNodes()); - int numberOfSkippedTurns(0); - int nodeBasedEdgeCounter(0); - unsigned numberOfOriginalEdges(0); - std::ofstream originalEdgeDataOutFile(originalEdgeDataFilename, std::ios::binary); - originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned)); +void EdgeBasedGraphFactory::Run( + const char * original_edge_data_filename, + lua_State *lua_state +) { + SimpleLogger().Write() << "Identifying components of the road network"; + 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 - std::queue > bfsQueue; - std::vector componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX); - std::vector vectorOfComponentSizes; - unsigned currentComponent = 0, sizeOfCurrentComponent = 0; + std::queue > bfs_queue; + std::vector component_index_list( + m_node_based_graph->GetNumberOfNodes(), + UINT_MAX + ); + + std::vector component_size_list; //put unexplorered node with parent pointer into queue - for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) { - if(UINT_MAX == componentsIndex[node]) { - bfsQueue.push(std::make_pair(node, node)); + for( + NodeID node = 0, + 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 - componentsIndex[node] = currentComponent; + component_index_list[node] = current_component; p.printIncrement(); - while(!bfsQueue.empty()) { + while(!bfs_queue.empty()) { //fetch element from BFS queue - std::pair currentQueueItem = bfsQueue.front(); - bfsQueue.pop(); - // INFO("sizeof queue: " << bfsQueue.size() << ", sizeOfCurrentComponents: " << sizeOfCurrentComponent << ", settled nodes: " << settledNodes++ << ", max: " << endNodes); - const NodeID v = currentQueueItem.first; //current node - const NodeID u = currentQueueItem.second; //parent + std::pair current_queue_item = bfs_queue.front(); + bfs_queue.pop(); + // SimpleLogger().Write() << "sizeof queue: " << bfs_queue.size() << + // ", current_component_sizes: " << current_component_size << + //", 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 - ++sizeOfCurrentComponent; - const bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); - if(!isBollardNode) { - const NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); + ++current_component_size; + const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); + if(!is_barrier_node) { + const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v); //relaxieren edge outgoing edge like below where edge-expanded graph - for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { - _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); + for( + 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; } - if( u != w ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. - if (!CheckIfTurnIsRestricted(u, v, w) ) { //only add an edge if turn is not prohibited - //insert next (node, parent) only if w has not yet been explored - if(UINT_MAX == componentsIndex[w]) { + if( u != w ) { + //only add an edge if turn is not a U-turn except + //when it is at the end of a dead-end street. + 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 - componentsIndex[w] = currentComponent; - bfsQueue.push(std::make_pair(w,v)); + component_index_list[w] = current_component; + bfs_queue.push(std::make_pair(w,v)); p.printIncrement(); } } @@ -210,149 +284,228 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State } } //push size into vector - vectorOfComponentSizes.push_back(sizeOfCurrentComponent); + component_size_list.push_back(current_component_size); //reset counters; - sizeOfCurrentComponent = 0; - ++currentComponent; + current_component_size = 0; + ++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. - for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { - for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { - _NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); + for( + NodeIterator u = 0, + 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) { - assert(e1 != UINT_MAX); - assert(u != UINT_MAX); - assert(v != UINT_MAX); - //edges that end on bollard nodes may actually be in two distinct components - InsertEdgeBasedNode(e1, u, v, (std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 1000) ); + if(m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX) { + BOOST_ASSERT_MSG(e1 != UINT_MAX, "edge id invalid"); + BOOST_ASSERT_MSG(u != UINT_MAX, "souce node invalid"); + BOOST_ASSERT_MSG(v != UINT_MAX, "target node invalid"); + //Note: edges that end on barrier nodes or on a turn restriction + //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().swap(vectorOfComponentSizes); - std::vector().swap(componentsIndex); - + std::vector().swap(component_size_list); + BOOST_ASSERT_MSG( + 0 == component_size_list.capacity(), + "component size vector not deallocated" + ); + std::vector().swap(component_index_list); + BOOST_ASSERT_MSG( + 0 == component_index_list.capacity(), + "component index vector not deallocated" + ); std::vector original_edge_data_vector; original_edge_data_vector.reserve(10000); //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. - for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { - for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { - ++nodeBasedEdgeCounter; - _NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); - bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); - //EdgeWeight heightPenalty = ComputeHeightPenalty(u, v); - NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); - for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { - const _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); - - if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. - ++numberOfSkippedTurns; + //Three nested loop look super-linear, but we are dealing with a (kind of) + //linear number of turns only. + for( + NodeIterator u = 0, + last_node = m_node_based_graph->GetNumberOfNodes(); + u < last_node; + ++u + ) { + for( + EdgeIterator e1 = m_node_based_graph->BeginEdges(u), + last_edge_u = m_node_based_graph->EndEdges(u); + e1 < last_edge_u; + ++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; } - if(u == w && 1 != _nodeBasedGraph->GetOutDegree(v) ) { + if(u == w && 1 != m_node_based_graph->GetOutDegree(v) ) { continue; } - if( !isBollardNode ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. - if (!CheckIfTurnIsRestricted(u, v, w) || (onlyToNode != UINT_MAX && w == onlyToNode)) { //only add an edge if turn is not prohibited - const _NodeBasedDynamicGraph::EdgeData edgeData1 = _nodeBasedGraph->GetEdgeData(e1); - const _NodeBasedDynamicGraph::EdgeData edgeData2 = _nodeBasedGraph->GetEdgeData(e2); - assert(edgeData1.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); - assert(edgeData2.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); + if( !is_barrier_node ) { + //only add an edge if turn is not a U-turn except when it is + //at the end of a dead-end street + if ( + !CheckIfTurnIsRestricted(u, v, w) || + (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; } - unsigned distance = edgeData1.distance; - if(_trafficLights.find(v) != _trafficLights.end()) { - distance += speedProfile.trafficSignalPenalty; + unsigned distance = edge_data1.distance; + if(m_traffic_lights.find(v) != m_traffic_lights.end()) { + 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 += heightPenalty; - //distance += ComputeTurnPenalty(u, v, w); - assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID); - OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction); - original_edge_data_vector.push_back(oed); - ++numberOfOriginalEdges; + assert(edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID); + original_edge_data_vector.push_back( + OriginalEdgeData( + v, + edge_data2.nameID, + turnInstruction + ) + ); + ++original_edges_counter; 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(); } - EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false ); - edgeBasedEdges.push_back(newEdge); + m_edge_based_edge_list.push_back( + EdgeBasedEdge( + edge_data1.edgeBasedNodeID, + edge_data2.edgeBasedNodeID, + m_edge_based_edge_list.size(), + distance, + true, + false + ) + ); } else { - ++numberOfSkippedTurns; + ++skipped_turns_counter; } } } } p.printIncrement(); } - originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); - originalEdgeDataOutFile.seekp(std::ios::beg); - originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned)); - originalEdgeDataOutFile.close(); + edge_data_file.write( + (char*)&(original_edge_data_vector[0]), + original_edge_data_vector.size()*sizeof(OriginalEdgeData) + ); + 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"); -// std::sort(edgeBasedNodes.begin(), edgeBasedNodes.end()); -// INFO("Removing duplicate nodes (if any)"); -// edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() ); -// INFO("Applying vector self-swap trick to free up memory"); -// INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity()); -// std::vector(edgeBasedNodes).swap(edgeBasedNodes); -// INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity()); - INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges"); - INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges"); -// INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << 2*((double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter)); - INFO("Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions."); - INFO("Generated " << edgeBasedNodes.size() << " edge based nodes"); + SimpleLogger().Write() << + "Generated " << m_edge_based_node_list.size() << " edge based nodes"; + SimpleLogger().Write() << + "Node-based graph contains " << node_based_edge_counter << " edges"; + SimpleLogger().Write() << + "Edge-expanded graph ..."; + SimpleLogger().Write() << + " contains " << m_edge_based_edge_list.size() << " edges"; + SimpleLogger().Write() << + " skips " << skipped_turns_counter << " turns, " + "defined by " << m_turn_restrictions_count << " restrictions"; } -TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, unsigned& penalty, lua_State *myLuaState) const { - const double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]); +int EdgeBasedGraphFactory::GetTurnPenalty( + 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 ) { - try { + if( speed_profile.has_turn_penalty_function ) { + try { //call lua profile to compute turn penalty - penalty = luabind::call_function( myLuaState, "turn_function", 180-angle ); + return luabind::call_function( + lua_state, + "turn_function", + 180.-angle + ); } catch (const luabind::error &er) { - std::cerr << er.what() << std::endl; - //TODO handle lua errors + SimpleLogger().Write(logWARNING) << er.what(); } - } else { - penalty = 0; } + return 0; +} +TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn( + const NodeID u, + const NodeID v, + const NodeID w +) const { if(u == w) { return TurnInstructions.UTurn; } - _NodeBasedDynamicGraph::EdgeIterator edge1 = _nodeBasedGraph->FindEdge(u, v); - _NodeBasedDynamicGraph::EdgeIterator edge2 = _nodeBasedGraph->FindEdge(v, w); + EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v); + EdgeIterator edge2 = m_node_based_graph->FindEdge(v, w); - _NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1); - _NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2); + EdgeData & data1 = m_node_based_graph->GetEdgeData(edge1); + EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2); if(!data1.contraFlow && data2.contraFlow) { return TurnInstructions.EnterAgainstAllowedDirection; @@ -364,7 +517,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID //roundabouts need to be handled explicitely if(data1.roundabout && data2.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. 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( (data1.nameID == data2.nameID) && (0 != data1.nameID)) { - return TurnInstructions.NoTurn; - } - if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) { - return TurnInstructions.NoTurn; + //If street names stay the same and if we are certain that it is not a + //a segment of a roundabout, we skip it. + if( data1.nameID == data2.nameID ) { + //TODO: Here we should also do a small graph exploration to check for + // more complex situations + 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); } unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const { - return _nodeBasedGraph->GetNumberOfEdges(); -} - -/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/ -template -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; + return m_node_based_graph->GetNumberOfEdges(); } diff --git a/Contractor/EdgeBasedGraphFactory.h b/Contractor/EdgeBasedGraphFactory.h index 7949af6ff..5f4df157b 100644 --- a/Contractor/EdgeBasedGraphFactory.h +++ b/Contractor/EdgeBasedGraphFactory.h @@ -18,9 +18,7 @@ or see http://www.gnu.org/licenses/agpl.txt. */ -/* - * This class constructs the edge base representation of a graph from a given node based edge list - */ +// This class constructs the edge-expanded routing graph #ifndef EDGEBASEDGRAPHFACTORY_H_ #define EDGEBASEDGRAPHFACTORY_H_ @@ -31,14 +29,11 @@ #include "../Extractor/ExtractorStructs.h" #include "../DataStructures/HashTable.h" #include "../DataStructures/ImportEdge.h" -#include "../DataStructures/MercatorUtil.h" #include "../DataStructures/QueryEdge.h" #include "../DataStructures/Percent.h" #include "../DataStructures/TurnInstructions.h" -#include "../Util/BaseConfiguration.h" #include "../Util/LuaUtil.h" - -#include +#include "../Util/SimpleLogger.h" #include #include @@ -47,9 +42,8 @@ #include #include -#include - #include +#include #include #include @@ -67,6 +61,7 @@ public: weight(UINT_MAX >> 1), ignoreInGrid(false) { } + bool operator<(const EdgeBasedNode & other) const { return other.id < id; } @@ -75,8 +70,8 @@ public: return id == other.id; } - inline _Coordinate Centroid() const { - _Coordinate centroid; + inline FixedPointCoordinate Centroid() const { + FixedPointCoordinate centroid; //The coordinates of the midpoint are given by: //x = (x1 + x2) /2 and y = (y1 + y2) /2. centroid.lon = (std::min(lon1, lon2) + std::max(lon1, lon2))/2; @@ -87,6 +82,7 @@ public: inline bool isIgnored() const { return ignoreInGrid; } + NodeID id; int lat1; int lat2; @@ -99,14 +95,47 @@ public: }; 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 uTurnPenalty; bool has_turn_penalty_function; - } speedProfile; + } speed_profile; + + explicit EdgeBasedGraphFactory( + int number_of_nodes, + std::vector & input_edge_list, + std::vector & barrier_node_list, + std::vector & traffic_light_node_list, + std::vector & input_restrictions_list, + std::vector & 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); + 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: - struct _NodeBasedEdgeData { + struct NodeBasedEdgeData { int distance; unsigned edgeBasedNodeID; unsigned nameID; @@ -129,45 +158,46 @@ private: TurnInstruction turnInstruction; }; - typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; - typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge; - std::vector inputNodeInfoList; - unsigned numberOfTurnRestrictions; + unsigned m_turn_restrictions_count; - boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph; - boost::unordered_set _barrierNodes; - boost::unordered_set _trafficLights; - - typedef std::pair RestrictionSource; - typedef std::pair RestrictionTarget; - typedef std::vector EmanatingRestrictionsVector; + typedef DynamicGraph NodeBasedDynamicGraph; + typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge; + typedef NodeBasedDynamicGraph::NodeIterator NodeIterator; + typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator; + typedef NodeBasedDynamicGraph::EdgeData EdgeData; + typedef std::pair RestrictionSource; + typedef std::pair RestrictionTarget; + typedef std::vector EmanatingRestrictionsVector; typedef boost::unordered_map RestrictionMap; - std::vector _restrictionBucketVector; - RestrictionMap _restrictionMap; - DeallocatingVector edgeBasedEdges; - std::vector edgeBasedNodes; + std::vector m_node_info_list; + std::vector m_restriction_bucket_list; + std::vector m_edge_based_node_list; + DeallocatingVector m_edge_based_edge_list; + + boost::shared_ptr m_node_based_graph; + boost::unordered_set m_barrier_nodes; + boost::unordered_set 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( - _NodeBasedDynamicGraph::EdgeIterator e1, - _NodeBasedDynamicGraph::NodeIterator u, - _NodeBasedDynamicGraph::NodeIterator v, + NodeBasedDynamicGraph::EdgeIterator e1, + NodeBasedDynamicGraph::NodeIterator u, + NodeBasedDynamicGraph::NodeIterator v, bool belongsToTinyComponent); - template - double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const; - -public: - template< class InputEdgeT > - explicit EdgeBasedGraphFactory(int nodes, std::vector & inputEdges, std::vector & _bollardNodes, std::vector & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector & 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_ */ diff --git a/Contractor/TemporaryStorage.cpp b/Contractor/TemporaryStorage.cpp index dbd86e3e5..6c32ba176 100644 --- a/Contractor/TemporaryStorage.cpp +++ b/Contractor/TemporaryStorage.cpp @@ -21,11 +21,7 @@ #include "TemporaryStorage.h" TemporaryStorage::TemporaryStorage() { - try { - tempDirectory = boost::filesystem::temp_directory_path(); - } catch(boost::filesystem::filesystem_error & e) { - ERR("could not retrieve location of temporary path: " << e.what()); - } + tempDirectory = boost::filesystem::temp_directory_path(); } TemporaryStorage & TemporaryStorage::GetInstance(){ @@ -39,12 +35,8 @@ TemporaryStorage::~TemporaryStorage() { void TemporaryStorage::removeAll() { boost::mutex::scoped_lock lock(mutex); - try { - for(unsigned slotID = 0; slotID < vectorOfStreamDatas.size(); ++slotID) - deallocateSlot(slotID); - - } catch(boost::filesystem::filesystem_error & e) { - ERR("could not retrieve location of temporary path: " << e.what()); + for(unsigned slot_id = 0; slot_id < vectorOfStreamDatas.size(); ++slot_id) { + deallocateSlot(slot_id); } vectorOfStreamDatas.clear(); } @@ -53,7 +45,7 @@ int TemporaryStorage::allocateSlot() { boost::mutex::scoped_lock lock(mutex); try { 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) { abort(e); } @@ -64,13 +56,13 @@ void TemporaryStorage::deallocateSlot(int slotID) { try { StreamData & data = vectorOfStreamDatas[slotID]; boost::mutex::scoped_lock lock(*data.readWriteMutex); - if(!boost::filesystem::exists(data.pathToTemporaryFile)) { + if(!boost::filesystem::exists(data.pathToTemporaryFile)) { return; } - if(data.streamToTemporaryFile->is_open()) + if(data.streamToTemporaryFile->is_open()) { data.streamToTemporaryFile->close(); + } - //INFO("deallocating slot " << slotID << " and its file: " << data.pathToTemporaryFile); boost::filesystem::remove(data.pathToTemporaryFile); } catch(boost::filesystem::filesystem_error & e) { abort(e); @@ -81,8 +73,10 @@ void TemporaryStorage::writeToSlot(int slotID, char * pointer, std::streamsize s try { StreamData & data = vectorOfStreamDatas[slotID]; boost::mutex::scoped_lock lock(*data.readWriteMutex); - if(!data.writeMode) - ERR("Writing after first read is not allowed"); + BOOST_ASSERT_MSG( + data.writeMode, + "Writing after first read is not allowed" + ); data.streamToTemporaryFile->write(pointer, size); } catch(boost::filesystem::filesystem_error & e) { abort(e); @@ -121,13 +115,11 @@ boost::filesystem::fstream::pos_type TemporaryStorage::tell(int slotID) { } catch(boost::filesystem::filesystem_error & e) { abort(e); } -// INFO("telling position: " << position); return position; } void TemporaryStorage::abort(boost::filesystem::filesystem_error& ) { removeAll(); -// ERR("I/O Error occured: " << e.what()); } 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]; boost::mutex::scoped_lock lock(*data.readWriteMutex); data.streamToTemporaryFile->seekg(position); -// INFO("seeking to position: " << position); } catch(boost::filesystem::filesystem_error & e) { abort(e); } diff --git a/Contractor/TemporaryStorage.h b/Contractor/TemporaryStorage.h index 84004c71c..feebc3552 100644 --- a/Contractor/TemporaryStorage.h +++ b/Contractor/TemporaryStorage.h @@ -24,12 +24,15 @@ #include #include +#include #include #include #include #include #include +#include "../Util/OSRMException.h" +#include "../Util/SimpleLogger.h" #include "../typedefs.h" //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)), readWriteMutex(new boost::mutex) { - if(streamToTemporaryFile->fail()) - ERR("Aborting, because temporary file at " << pathToTemporaryFile << " could not be created"); + if(streamToTemporaryFile->fail()) { + throw OSRMException("temporary file could not be created"); + } } }; //vector of file streams that is used to store temporary data diff --git a/DataStructures/BinaryHeap.h b/DataStructures/BinaryHeap.h index 6b9bd10c4..b1e838b8f 100644 --- a/DataStructures/BinaryHeap.h +++ b/DataStructures/BinaryHeap.h @@ -147,13 +147,13 @@ public: return insertedNodes[index].weight; } - bool WasRemoved( NodeID node ) { + bool WasRemoved( const NodeID node ) { assert( WasInserted( node ) ); const Key index = nodeIndex[node]; return insertedNodes[index].key == 0; } - bool WasInserted( NodeID node ) { + bool WasInserted( const NodeID node ) { const Key index = nodeIndex[node]; if ( index >= static_cast (insertedNodes.size()) ) return false; diff --git a/DataStructures/Coordinate.h b/DataStructures/Coordinate.h index 68219d5a1..bf0d3eaad 100644 --- a/DataStructures/Coordinate.h +++ b/DataStructures/Coordinate.h @@ -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. */ -#ifndef COORDINATE_H_ -#define COORDINATE_H_ +#ifndef FIXED_POINT_COORDINATE_H_ +#define FIXED_POINT_COORDINATE_H_ +#include "../DataStructures/MercatorUtil.h" #include "../Util/StringUtil.h" #include @@ -29,11 +30,13 @@ or see http://www.gnu.org/licenses/agpl.txt. #include -struct _Coordinate { +static const double COORDINATE_PRECISION = 1000000.; + +struct FixedPointCoordinate { int lat; int lon; - _Coordinate () : lat(INT_MIN), lon(INT_MIN) {} - explicit _Coordinate (int t, int n) : lat(t) , lon(n) {} + FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {} + explicit FixedPointCoordinate (int lat, int lon) : lat(lat) , lon(lon) {} void Reset() { lat = INT_MIN; @@ -43,17 +46,22 @@ struct _Coordinate { return (INT_MIN != lat) && (INT_MIN != lon); } 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 true; } - bool operator==(const _Coordinate & other) const { + bool operator==(const FixedPointCoordinate & other) const { 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 << ")"; return out; } @@ -64,10 +72,10 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat assert(lat2 != INT_MIN); assert(lon2 != INT_MIN); double RAD = 0.017453292519943295769236907684886; - double lt1 = lat1/100000.; - double ln1 = lon1/100000.; - double lt2 = lat2/100000.; - double ln2 = lon2/100000.; + double lt1 = lat1/COORDINATE_PRECISION; + double ln1 = lon1/COORDINATE_PRECISION; + double lt2 = lat2/COORDINATE_PRECISION; + double ln2 = lon2/COORDINATE_PRECISION; double dlat1=lt1*(RAD); double dlong1=ln1*(RAD); @@ -86,20 +94,20 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat 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 ); } -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.lon != INT_MIN); assert(c2.lat != INT_MIN); assert(c2.lon != INT_MIN); const double RAD = 0.017453292519943295769236907684886; - const double lat1 = (c1.lat/100000.)*RAD; - const double lon1 = (c1.lon/100000.)*RAD; - const double lat2 = (c2.lat/100000.)*RAD; - const double lon2 = (c2.lon/100000.)*RAD; + const double lat1 = (c1.lat/COORDINATE_PRECISION)*RAD; + const double lon1 = (c1.lon/COORDINATE_PRECISION)*RAD; + const double lat2 = (c2.lat/COORDINATE_PRECISION)*RAD; + const double lon2 = (c2.lon/COORDINATE_PRECISION)*RAD; const double x = (lon2-lon1) * cos((lat1+lat2)/2.); 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) { char buffer[100]; buffer[10] = 0; // Nullterminierung - char* string = printInt< 10, 5 >( buffer, value ); + char* string = printInt< 10, 6 >( buffer, value ); 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; convertInternalLatLonToString(coord.lon, tmp); output = tmp; @@ -124,7 +132,7 @@ static inline void convertInternalCoordinateToString(const _Coordinate & coord, output += tmp; output += " "; } -static inline void convertInternalReversedCoordinateToString(const _Coordinate & coord, std::string & output) { +static inline void convertInternalReversedCoordinateToString(const FixedPointCoordinate & coord, std::string & output) { std::string tmp; convertInternalLatLonToString(coord.lat, tmp); output = tmp; @@ -134,4 +142,22 @@ static inline void convertInternalReversedCoordinateToString(const _Coordinate & output += " "; } -#endif /* COORDINATE_H_ */ + +/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/ +template +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_ */ diff --git a/DataStructures/DynamicGraph.h b/DataStructures/DynamicGraph.h index 67db0650a..89baee882 100644 --- a/DataStructures/DynamicGraph.h +++ b/DataStructures/DynamicGraph.h @@ -194,7 +194,7 @@ class DynamicGraph { //searches for a specific edge EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const { 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; } } diff --git a/DataStructures/HashTable.h b/DataStructures/HashTable.h index 57c2dde9f..465caca0e 100644 --- a/DataStructures/HashTable.h +++ b/DataStructures/HashTable.h @@ -24,56 +24,35 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef HASHTABLE_H_ #define HASHTABLE_H_ +#include #include template -class HashTable { - typedef boost::unordered_map MyHashTable; +class HashTable : public boost::unordered_map { +private: + typedef boost::unordered_map super; public: - typedef typename boost::unordered_map::const_iterator MyIterator; - typedef MyIterator iterator; - HashTable() { } - HashTable(const unsigned size) { - table.resize(size); - } + HashTable() : super() { } + + HashTable(const unsigned size) : super(size) { } + inline void Add(const keyT& key, const valueT& value){ - table[key] = value; - } - inline void Set(const keyT& key, const valueT& value){ - table[key] = value; + super::insert(std::make_pair(key, value)); } + inline valueT Find(const keyT& key) const { - if(table.find(key) == table.end()) + if(super::find(key) == super::end()) { return valueT(); - return table.find(key)->second; + } + return boost::ref(super::find(key)->second); } inline bool Holds(const keyT& key) const { - if(table.find(key) == table.end()) + if(super::find(key) == super::end()) { return false; + } 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_ */ diff --git a/DataStructures/HilbertValue.h b/DataStructures/HilbertValue.h index 05e2bb15f..f73396928 100644 --- a/DataStructures/HilbertValue.h +++ b/DataStructures/HilbertValue.h @@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef HILBERTVALUE_H_ #define HILBERTVALUE_H_ +#include "Coordinate.h" + #include #include @@ -29,10 +31,11 @@ or see http://www.gnu.org/licenses/agpl.txt. class HilbertCode : boost::noncopyable { public: static uint64_t GetHilbertNumberForCoordinate( - const _Coordinate & current_coordinate) { + const FixedPointCoordinate & current_coordinate + ) { unsigned location[2]; - location[0] = current_coordinate.lat+( 90*100000); - location[1] = current_coordinate.lon+(180*100000); + location[0] = current_coordinate.lat+( 90*COORDINATE_PRECISION); + location[1] = current_coordinate.lon+(180*COORDINATE_PRECISION); TransposeCoordinate(location); const uint64_t result = BitInterleaving(location[0], location[1]); diff --git a/DataStructures/ImportEdge.h b/DataStructures/ImportEdge.h index 714560ccc..5da516b15 100644 --- a/DataStructures/ImportEdge.h +++ b/DataStructures/ImportEdge.h @@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef EDGE_H #define EDGE_H + +#include "../Util/OSRMException.h" #include class NodeBasedEdge { @@ -40,8 +42,34 @@ public: 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) : - _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);}; } + explicit NodeBasedEdge( + 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 source() const {return _source; } diff --git a/DataStructures/ImportNode.h b/DataStructures/ImportNode.h index b9c27beff..d1eb1dd28 100644 --- a/DataStructures/ImportNode.h +++ b/DataStructures/ImportNode.h @@ -21,7 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef IMPORTNODE_H_ #define IMPORTNODE_H_ -#include "NodeCoords.h" +#include "QueryNode.h" #include "../DataStructures/HashTable.h" @@ -44,9 +44,9 @@ struct _Node : NodeInfo{ struct ImportNode : public _Node { HashTable keyVals; - + inline void Clear() { - keyVals.EraseAll(); + keyVals.clear(); lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false; } }; diff --git a/DataStructures/NodeInformationHelpDesk.h b/DataStructures/NodeInformationHelpDesk.h index 48bad7879..7d638be3b 100644 --- a/DataStructures/NodeInformationHelpDesk.h +++ b/DataStructures/NodeInformationHelpDesk.h @@ -21,23 +21,25 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef NODEINFORMATIONHELPDESK_H_ #define NODEINFORMATIONHELPDESK_H_ -#include "NodeCoords.h" +#include "QueryNode.h" #include "PhantomNodes.h" #include "StaticRTree.h" #include "../Contractor/EdgeBasedGraphFactory.h" +#include "../Util/OSRMException.h" #include "../typedefs.h" #include +#include +#include #include #include -#include #include #include typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf; -class NodeInformationHelpDesk : boost::noncopyable{ +class NodeInformationHelpDesk : boost::noncopyable { public: NodeInformationHelpDesk( const std::string & ramIndexInput, @@ -46,8 +48,21 @@ public: const std::string & edges_filename, const unsigned number_of_nodes, 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( ramIndexInput, fileIndexInput @@ -92,8 +107,8 @@ public: } inline bool FindNearestNodeCoordForLatLon( - const _Coordinate& input_coordinate, - _Coordinate& result, + const FixedPointCoordinate& input_coordinate, + FixedPointCoordinate& result, const unsigned zoom_level = 18 ) const { PhantomNode resulting_phantom_node; @@ -106,7 +121,7 @@ public: } inline bool FindPhantomNodeForCoordinate( - const _Coordinate & input_coordinate, + const FixedPointCoordinate & input_coordinate, PhantomNode & resulting_phantom_node, const unsigned zoom_level ) const { @@ -123,24 +138,38 @@ public: private: void LoadNodesAndEdges( - const std::string & nodes_file, - const std::string & edges_file + const std::string & nodes_filename, + const std::string & edges_filename ) { - std::ifstream nodes_input_stream(nodes_file.c_str(), std::ios::binary); - if(!nodes_input_stream) { ERR(nodes_file << " not found"); } - std::ifstream edges_input_stream(edges_file.c_str(), std::ios::binary); - if(!edges_input_stream) { ERR(edges_file << " not found"); } + boost::filesystem::path nodes_file(nodes_filename); + if ( !boost::filesystem::exists( nodes_file ) ) { + throw OSRMException("nodes file does not exist"); + } + 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; while(!nodes_input_stream.eof()) { 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(coordinateVector).swap(coordinateVector); nodes_input_stream.close(); - DEBUG("Loading edge data"); + SimpleLogger().Write(logDEBUG) << "Loading edge data"; unsigned numberOfOrigEdges(0); edges_input_stream.read((char*)&numberOfOrigEdges, sizeof(unsigned)); origEdgeData_viaNode.resize(numberOfOrigEdges); @@ -158,11 +187,11 @@ private: origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction; } edges_input_stream.close(); - DEBUG("Loaded " << numberOfOrigEdges << " orig edges"); - DEBUG("Opening NN indices"); + SimpleLogger().Write(logDEBUG) << "Loaded " << numberOfOrigEdges << " orig edges"; + SimpleLogger().Write(logDEBUG) << "Opening NN indices"; } - std::vector<_Coordinate> coordinateVector; + std::vector coordinateVector; std::vector origEdgeData_viaNode; std::vector origEdgeData_nameID; std::vector origEdgeData_turnInstruction; diff --git a/DataStructures/PhantomNodes.h b/DataStructures/PhantomNodes.h index 2827d7a91..d48d61797 100644 --- a/DataStructures/PhantomNodes.h +++ b/DataStructures/PhantomNodes.h @@ -24,13 +24,20 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "Coordinate.h" 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; unsigned nodeBasedEdgeNameID; int weight1; int weight2; double ratio; - _Coordinate location; + FixedPointCoordinate location; void Reset() { edgeBasedNode = UINT_MAX; nodeBasedEdgeNameID = UINT_MAX; @@ -88,7 +95,7 @@ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){ struct NodesOfEdge { NodeID edgeBasedNode; double ratio; - _Coordinate projectedPoint; + FixedPointCoordinate projectedPoint; }; #endif /* PHANTOMNODES_H_ */ diff --git a/DataStructures/QueryEdge.h b/DataStructures/QueryEdge.h index 3a2aecb82..1a7c39223 100644 --- a/DataStructures/QueryEdge.h +++ b/DataStructures/QueryEdge.h @@ -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. */ - - #ifndef QUERYEDGE_H_ #define QUERYEDGE_H_ @@ -29,7 +27,11 @@ or see http://www.gnu.org/licenses/agpl.txt. #include 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) {} NodeID viaNode; unsigned nameID; @@ -46,23 +48,12 @@ struct QueryEdge { bool forward:1; bool backward:1; } 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 - static bool CompareBySource( const QueryEdge& left, const QueryEdge& 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 QueryEdge& right ) const { + if ( source != right.source ) { + return source < right.source; + } + return target < right.target; } bool operator== ( const QueryEdge& right ) const { diff --git a/DataStructures/NodeCoords.h b/DataStructures/QueryNode.h similarity index 62% rename from DataStructures/NodeCoords.h rename to DataStructures/QueryNode.h index 80fda42b8..6e9386efb 100644 --- a/DataStructures/NodeCoords.h +++ b/DataStructures/QueryNode.h @@ -21,33 +21,43 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef _NODE_COORDS_H #define _NODE_COORDS_H +#include "Coordinate.h" #include "../typedefs.h" -#include +#include + #include #include #include -template -struct NodeCoords { - typedef unsigned key_type; //type of NodeID +struct NodeInfo { + typedef NodeID key_type; //type of NodeID typedef int value_type; //type of lat,lons - NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {} - NodeCoords() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {} + NodeInfo(int _lat, int _lon, NodeID _id) : lat(_lat), lon(_lon), id(_id) {} + NodeInfo() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {} int lat; int lon; - NodeT id; + NodeID id; - static NodeCoords min_value() { - return NodeCoords(-90*100000,-180*100000,std::numeric_limits::min()); - } - static NodeCoords max_value() { - return NodeCoords(90*100000, 180*100000, std::numeric_limits::max()); + static NodeInfo min_value() { + return NodeInfo( + -90*COORDINATE_PRECISION, + -180*COORDINATE_PRECISION, + std::numeric_limits::min() + ); } - value_type operator[](std::size_t n) const { + static NodeInfo max_value() { + return NodeInfo( + 90*COORDINATE_PRECISION, + 180*COORDINATE_PRECISION, + std::numeric_limits::max() + ); + } + + value_type operator[](const std::size_t n) const { switch(n) { case 1: return lat; @@ -56,15 +66,13 @@ struct NodeCoords { return lon; break; default: - assert(false); + BOOST_ASSERT_MSG(false, "should not happen"); return UINT_MAX; break; } - assert(false); + BOOST_ASSERT_MSG(false, "should not happen"); return UINT_MAX; } }; -typedef NodeCoords NodeInfo; - #endif //_NODE_COORDS_H diff --git a/Plugins/RawRouteData.h b/DataStructures/RawRouteData.h similarity index 90% rename from Plugins/RawRouteData.h rename to DataStructures/RawRouteData.h index f0c105486..7607e3300 100644 --- a/Plugins/RawRouteData.h +++ b/DataStructures/RawRouteData.h @@ -21,8 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef RAWROUTEDATA_H_ #define RAWROUTEDATA_H_ +#include "../DataStructures/Coordinate.h" +#include "../DataStructures/PhantomNodes.h" #include "../typedefs.h" +#include + struct _PathData { _PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { } NodeID node; @@ -35,7 +39,7 @@ struct RawRouteData { std::vector< _PathData > computedShortestPath; std::vector< _PathData > computedAlternativePath; std::vector< PhantomNodes > segmentEndCoordinates; - std::vector< _Coordinate > rawViaNodeCoordinates; + std::vector< FixedPointCoordinate > rawViaNodeCoordinates; unsigned checkSum; int lengthOfShortestPath; int lengthOfAlternativePath; diff --git a/DataStructures/Restriction.h b/DataStructures/Restriction.h index fc40fb0ba..2693700e7 100644 --- a/DataStructures/Restriction.h +++ b/DataStructures/Restriction.h @@ -23,14 +23,16 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef RESTRICTION_H_ #define RESTRICTION_H_ +#include "../typedefs.h" #include -struct _Restriction { +struct TurnRestriction { NodeID viaNode; NodeID fromNode; NodeID toNode; struct Bits { //mostly unused - Bits() : + Bits() + : isOnly(false), unused1(false), unused2(false), @@ -38,9 +40,8 @@ struct _Restriction { unused4(false), unused5(false), unused6(false), - unused7(false) { - - } + unused7(false) + { } bool isOnly:1; bool unused1:1; @@ -52,14 +53,14 @@ struct _Restriction { bool unused7:1; } flags; - _Restriction(NodeID vn) : - viaNode(vn), + TurnRestriction(NodeID viaNode) : + viaNode(viaNode), fromNode(UINT_MAX), toNode(UINT_MAX) { } - _Restriction(const bool isOnly = false) : + TurnRestriction(const bool isOnly = false) : viaNode(UINT_MAX), fromNode(UINT_MAX), toNode(UINT_MAX) { @@ -68,13 +69,32 @@ struct _Restriction { }; struct _RawRestrictionContainer { - _Restriction restriction; + TurnRestriction restriction; EdgeID fromWay; EdgeID toWay; unsigned viaNode; - _RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaNode(vw) { restriction.viaNode = vn;} - _RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaNode(UINT_MAX) { restriction.flags.isOnly = isOnly;} + _RawRestrictionContainer( + 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() { return _RawRestrictionContainer(0, 0, 0, 0); diff --git a/DataStructures/SearchEngine.cpp b/DataStructures/SearchEngine.cpp index 2a538a7ac..f3e79aa63 100644 --- a/DataStructures/SearchEngine.cpp +++ b/DataStructures/SearchEngine.cpp @@ -33,14 +33,14 @@ SearchEngine::SearchEngine( void SearchEngine::GetCoordinatesForNodeID( NodeID id, - _Coordinate& result + FixedPointCoordinate& result ) const { result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id); result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id); } void SearchEngine::FindPhantomNodeForCoordinate( - const _Coordinate & location, + const FixedPointCoordinate & location, PhantomNode & result, const unsigned zoomLevel ) const { diff --git a/DataStructures/SearchEngine.h b/DataStructures/SearchEngine.h index 64d273bb0..14cbd975e 100644 --- a/DataStructures/SearchEngine.h +++ b/DataStructures/SearchEngine.h @@ -45,17 +45,17 @@ public: AlternativeRouting alternativePaths; SearchEngine( - QueryGraph * g, - NodeInformationHelpDesk * nh, + QueryGraph * g, + NodeInformationHelpDesk * nh, std::vector & n ); ~SearchEngine(); - void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const; + void GetCoordinatesForNodeID(NodeID id, FixedPointCoordinate& result) const; void FindPhantomNodeForCoordinate( - const _Coordinate & location, - PhantomNode & result, + const FixedPointCoordinate & location, + PhantomNode & result, unsigned zoomLevel ) const; diff --git a/DataStructures/SegmentInformation.h b/DataStructures/SegmentInformation.h index 8f65eda72..20e5e05d8 100644 --- a/DataStructures/SegmentInformation.h +++ b/DataStructures/SegmentInformation.h @@ -27,16 +27,16 @@ or see http://www.gnu.org/licenses/agpl.txt. #include struct SegmentInformation { - _Coordinate location; + FixedPointCoordinate location; NodeID nameID; double length; unsigned duration; double bearing; TurnInstruction turnInstruction; 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) {} - 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) {} }; diff --git a/DataStructures/StaticGraph.h b/DataStructures/StaticGraph.h index 7504cbaa9..4e95c1630 100644 --- a/DataStructures/StaticGraph.h +++ b/DataStructures/StaticGraph.h @@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef STATICGRAPH_H_INCLUDED #define STATICGRAPH_H_INCLUDED +#include "../Util/SimpleLogger.h" #include "../typedefs.h" #include @@ -99,12 +100,17 @@ public: if(data.shortcut) { unsigned eid2 = FindEdgeInEitherDirection(u, data.id); 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; } eid2 = FindEdgeInEitherDirection(data.id, v); 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; } } diff --git a/DataStructures/StaticRTree.h b/DataStructures/StaticRTree.h index 3e598f3e4..603e7b3d4 100644 --- a/DataStructures/StaticRTree.h +++ b/DataStructures/StaticRTree.h @@ -22,16 +22,20 @@ or see http://www.gnu.org/licenses/agpl.txt. #define STATICRTREE_H_ #include "MercatorUtil.h" -#include "TimingUtil.h" #include "Coordinate.h" #include "PhantomNodes.h" #include "DeallocatingVector.h" #include "HilbertValue.h" +#include "../Util/OSRMException.h" +#include "../Util/SimpleLogger.h" +#include "../Util/TimingUtil.h" #include "../typedefs.h" #include #include #include +#include +#include #include #include #include @@ -43,7 +47,6 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include -#include #include #include #include @@ -54,7 +57,7 @@ const static uint32_t RTREE_LEAF_NODE_SIZE = 1170; // Implements a static, i.e. packed, R-tree -static boost::thread_specific_ptr thread_local_rtree_stream; +static boost::thread_specific_ptr thread_local_rtree_stream; template class StaticRTree : boost::noncopyable { @@ -97,8 +100,8 @@ private: max_lat = std::max(max_lat, other.max_lat); } - inline _Coordinate Centroid() const { - _Coordinate centroid; + inline FixedPointCoordinate Centroid() const { + FixedPointCoordinate centroid; //The coordinates of the midpoints are given by: //x = (x1 + x2) /2 and y = (y1 + y2) /2. centroid.lon = (min_lon + max_lon)/2; @@ -107,10 +110,10 @@ private: } inline bool Intersects(const RectangleInt2D & other) const { - _Coordinate upper_left (other.max_lat, other.min_lon); - _Coordinate upper_right(other.max_lat, other.max_lon); - _Coordinate lower_right(other.min_lat, other.max_lon); - _Coordinate lower_left (other.min_lat, other.min_lon); + FixedPointCoordinate upper_left (other.max_lat, other.min_lon); + FixedPointCoordinate upper_right(other.max_lat, other.max_lon); + FixedPointCoordinate lower_right(other.min_lat, other.max_lon); + FixedPointCoordinate lower_left (other.min_lat, other.min_lon); return ( 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); if (is_contained) { return 0.0; @@ -166,13 +169,13 @@ private: return min_dist; } - inline double GetMinMaxDist(const _Coordinate & location) const { + inline double GetMinMaxDist(const FixedPointCoordinate & location) const { double min_max_dist = DBL_MAX; //Get minmax distance to each of the four sides - _Coordinate upper_left (max_lat, min_lon); - _Coordinate upper_right(max_lat, max_lon); - _Coordinate lower_right(min_lat, max_lon); - _Coordinate lower_left (min_lat, min_lon); + FixedPointCoordinate upper_left (max_lat, min_lon); + FixedPointCoordinate upper_right(max_lat, max_lon); + FixedPointCoordinate lower_right(min_lat, max_lon); + FixedPointCoordinate lower_left (min_lat, min_lon); min_max_dist = std::min( min_max_dist, @@ -208,7 +211,7 @@ private: return min_max_dist; } - inline bool Contains(const _Coordinate & location) const { + inline bool Contains(const FixedPointCoordinate & location) const { bool lats_contained = (location.lat > min_lat) && (location.lat < max_lat); bool lons_contained = @@ -220,10 +223,10 @@ private: std::ostream & out, const RectangleInt2D & rect ) { - out << rect.min_lat/100000. << "," - << rect.min_lon/100000. << " " - << rect.max_lat/100000. << "," - << rect.max_lon/100000.; + out << rect.min_lat/COORDINATE_PRECISION << "," + << rect.min_lon/COORDINATE_PRECISION << " " + << rect.max_lat/COORDINATE_PRECISION << "," + << rect.max_lon/COORDINATE_PRECISION; return out; } }; @@ -287,7 +290,10 @@ public: : m_element_count(input_data_vector.size()), 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(); std::vector input_wrapper_vector(m_element_count); @@ -297,15 +303,15 @@ public: input_wrapper_vector[element_counter].m_array_index = element_counter; //Get Hilbert-Value for centroid in mercartor projection DataT & current_element = input_data_vector[element_counter]; - _Coordinate current_centroid = current_element.Centroid(); - current_centroid.lat = 100000*lat2y(current_centroid.lat/100000.); + FixedPointCoordinate current_centroid = current_element.Centroid(); + current_centroid.lat = COORDINATE_PRECISION*lat2y(current_centroid.lat/COORDINATE_PRECISION); uint64_t current_hilbert_value = HilbertCode::GetHilbertNumberForCoordinate(current_centroid); input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value; } //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)); //sort the hilbert-value representatives @@ -386,7 +392,11 @@ public: } //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(); BOOST_ASSERT_MSG(0 < size_of_tree, "tree empty"); tree_node_file.write((char *)&size_of_tree, sizeof(uint32_t)); @@ -394,7 +404,8 @@ public: //close tree node file. tree_node_file.close(); 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 @@ -403,25 +414,42 @@ public: const std::string & leaf_filename ) : m_leaf_node_filename(leaf_filename) { //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; 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); tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size); tree_node_file.close(); //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.close(); - //INFO( tree_size << " nodes in search tree"); - //INFO( m_element_count << " elements in leafs"); + //SimpleLogger().Write() << tree_size << " nodes in search tree"; + //SimpleLogger().Write() << m_element_count << " elements in leafs"; } /* inline void FindKNearestPhantomNodesForCoordinate( - const _Coordinate & location, + const FixedPointCoordinate & location, const unsigned zoom_level, const unsigned candidate_count, std::vector > & result_vector @@ -432,12 +460,12 @@ public: uint32_t io_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_max_dist = DBL_MAX; 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 std::priority_queue traversal_queue; @@ -465,8 +493,8 @@ public: double current_ratio = 0.; double current_perpendicular_distance = ComputePerpendicularDistance( input_coordinate, - _Coordinate(current_edge.lat1, current_edge.lon1), - _Coordinate(current_edge.lat2, current_edge.lon2), + FixedPointCoordinate(current_edge.lat1, current_edge.lon1), + FixedPointCoordinate(current_edge.lat2, current_edge.lon2), nearest, ¤t_ratio ); @@ -495,11 +523,11 @@ public: 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) && CoordinatesAreEquivalent( current_start_coordinate, - _Coordinate( + FixedPointCoordinate( current_edge.lat1, current_edge.lon1 ), - _Coordinate( + FixedPointCoordinate( current_edge.lat2, current_edge.lon2 ), @@ -535,14 +563,14 @@ public: const double distance_to_edge = ApproximateDistance ( - _Coordinate(nearest_edge.lat1, nearest_edge.lon1), + FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1), result_phantom_node.location ); const double length_of_edge = ApproximateDistance( - _Coordinate(nearest_edge.lat1, nearest_edge.lon1), - _Coordinate(nearest_edge.lat2, nearest_edge.lon2) + FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1), + FixedPointCoordinate(nearest_edge.lat2, nearest_edge.lon2) ); const double ratio = (found_a_nearest_edge ? @@ -561,14 +589,14 @@ public: 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; } */ bool FindPhantomNodeForCoordinate( - const _Coordinate & input_coordinate, + const FixedPointCoordinate & input_coordinate, PhantomNode & result_phantom_node, const unsigned zoom_level ) { @@ -578,12 +606,12 @@ public: uint32_t io_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_max_dist = DBL_MAX; 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 std::priority_queue traversal_queue; @@ -609,7 +637,7 @@ public: LeafNode current_leaf_node; LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node); ++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) { DataT & current_edge = current_leaf_node.objects[i]; if(ignore_tiny_components && current_edge.belongsToTinyComponent) { @@ -622,8 +650,8 @@ public: double current_ratio = 0.; double current_perpendicular_distance = ComputePerpendicularDistance( input_coordinate, - _Coordinate(current_edge.lat1, current_edge.lon1), - _Coordinate(current_edge.lat2, current_edge.lon2), + FixedPointCoordinate(current_edge.lat1, current_edge.lon1), + FixedPointCoordinate(current_edge.lat2, current_edge.lon2), nearest, ¤t_ratio ); @@ -652,11 +680,11 @@ public: 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) && CoordinatesAreEquivalent( current_start_coordinate, - _Coordinate( + FixedPointCoordinate( current_edge.lat1, current_edge.lon1 ), - _Coordinate( + FixedPointCoordinate( current_edge.lat2, current_edge.lon2 ), @@ -664,15 +692,15 @@ public: ) ) { 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; if(current_edge.id < result_phantom_node.edgeBasedNode) { result_phantom_node.edgeBasedNode = current_edge.id; std::swap(result_phantom_node.weight1, result_phantom_node.weight2); 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 { @@ -724,15 +752,15 @@ private: inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode& result_node) { if(!thread_local_rtree_stream.get() || !thread_local_rtree_stream->is_open()) { thread_local_rtree_stream.reset( - new std::ifstream( - m_leaf_node_filename.c_str(), + new boost::filesystem::ifstream( + m_leaf_node_filename, std::ios::in | std::ios::binary ) ); } if(!thread_local_rtree_stream->good()) { 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); thread_local_rtree_stream->seekg(seek_pos); @@ -740,10 +768,10 @@ private: } inline double ComputePerpendicularDistance( - const _Coordinate& inputPoint, - const _Coordinate& source, - const _Coordinate& target, - _Coordinate& nearest, double *r) const { + const FixedPointCoordinate& inputPoint, + const FixedPointCoordinate& source, + const FixedPointCoordinate& target, + FixedPointCoordinate& nearest, double *r) const { const double x = static_cast(inputPoint.lat); const double y = static_cast(inputPoint.lon); const double a = static_cast(source.lat); @@ -787,7 +815,7 @@ private: 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); } diff --git a/Descriptors/BaseDescriptor.h b/Descriptors/BaseDescriptor.h index 64d776cb3..0d1359a10 100644 --- a/Descriptors/BaseDescriptor.h +++ b/Descriptors/BaseDescriptor.h @@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../DataStructures/HashTable.h" #include "../DataStructures/PhantomNodes.h" +#include "../DataStructures/RawRouteData.h" #include "../DataStructures/SearchEngine.h" -#include "../Plugins/RawRouteData.h" +#include "../Server/BasicDatastructures.h" #include "../Util/StringUtil.h" #include "../typedefs.h" diff --git a/Descriptors/DescriptionFactory.cpp b/Descriptors/DescriptionFactory.cpp index 63e8883eb..1acf83a66 100644 --- a/Descriptors/DescriptionFactory.cpp +++ b/Descriptors/DescriptionFactory.cpp @@ -32,11 +32,14 @@ inline double DescriptionFactory::RadianToDegree(const double radian) const { return radian * (180/M_PI); } -double DescriptionFactory::GetBearing(const _Coordinate& A, const _Coordinate& B) const { - double deltaLong = DegreeToRadian(B.lon/100000. - A.lon/100000.); +double DescriptionFactory::GetBearing( + 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 lat2 = DegreeToRadian(B.lat/100000.); + double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION); + double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION); double y = sin(deltaLong) * cos(lat2); 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) ); } -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) { pathDescription.back().nameID = data.nameID; } 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) // ){ -// INFO("->next correct: " << string0 << " contains " << string1); +// SimpleLogger().Write() << "->next correct: " << string0 << " contains " << string1; // for(; lastTurn != i; ++lastTurn) // pathDescription[lastTurn].nameID = pathDescription[i].nameID; // 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) // ){ -// INFO("->prev correct: " << string1 << " contains " << string0); +// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " << string0; // pathDescription[i].nameID = pathDescription[i-1].nameID; // pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; // } @@ -153,24 +156,24 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev 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); lengthOfSegment = 0; durationOfSegment = 0; indexOfSegmentBegin = i; } } - // INFO("#segs: " << pathDescription.size()); + // SimpleLogger().Write() << "#segs: " << pathDescription.size(); //Post-processing to remove empty or nearly empty path segments 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){ pathDescription.pop_back(); pathDescription.back().necessary = true; pathDescription.back().turnInstruction = TurnInstructions.NoTurn; targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID; - // INFO("Deleting last turn instruction"); + // SimpleLogger().Write() << "Deleting last turn instruction"; } } else { 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].necessary = true; 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 { pathDescription[0].duration *= startPhantom.ratio; diff --git a/Descriptors/DescriptionFactory.h b/Descriptors/DescriptionFactory.h index e54752d16..68182a881 100644 --- a/Descriptors/DescriptionFactory.h +++ b/Descriptors/DescriptionFactory.h @@ -27,6 +27,7 @@ #include "../DataStructures/SearchEngine.h" #include "../DataStructures/SegmentInformation.h" #include "../DataStructures/TurnInstructions.h" +#include "../Util/SimpleLogger.h" #include "../typedefs.h" #include @@ -62,10 +63,10 @@ public: std::vector pathDescription; 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 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 SetStartSegment(const PhantomNode & startPhantom); void SetEndSegment(const PhantomNode & startPhantom); diff --git a/Descriptors/GPXDescriptor.h b/Descriptors/GPXDescriptor.h index f4a8190c5..9c3caa77b 100644 --- a/Descriptors/GPXDescriptor.h +++ b/Descriptors/GPXDescriptor.h @@ -28,7 +28,7 @@ or see http://www.gnu.org/licenses/agpl.txt. class GPXDescriptor : public BaseDescriptor{ private: _DescriptorConfig config; - _Coordinate current; + FixedPointCoordinate current; std::string tmp; public: diff --git a/Descriptors/JSONDescriptor.h b/Descriptors/JSONDescriptor.h index da7afcbb8..a45d478ed 100644 --- a/Descriptors/JSONDescriptor.h +++ b/Descriptors/JSONDescriptor.h @@ -39,7 +39,7 @@ private: _DescriptorConfig config; DescriptionFactory descriptionFactory; DescriptionFactory alternateDescriptionFactory; - _Coordinate current; + FixedPointCoordinate current; unsigned numberOfEnteredRestrictedAreas; struct RoundAbout{ RoundAbout() : diff --git a/Extractor/BaseParser.cpp b/Extractor/BaseParser.cpp index 6981e9570..cf5530a4d 100644 --- a/Extractor/BaseParser.cpp +++ b/Extractor/BaseParser.cpp @@ -29,38 +29,34 @@ extractor_callbacks(ec), scriptingEnvironment(se), luaState(NULL), use_turn_rest void BaseParser::ReadUseRestrictionsSetting() { 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) ) { use_turn_restrictions = lua_toboolean(luaState, -1); } if( use_turn_restrictions ) { - INFO("Using turn restrictions" ); + SimpleLogger().Write() << "Using turn restrictions"; } else { - INFO("Ignoring turn restrictions" ); + SimpleLogger().Write() << "Ignoring turn restrictions"; } } void BaseParser::ReadRestrictionExceptions() { if(lua_function_exists(luaState, "get_exceptions" )) { //get list of turn restriction exceptions - try { - luabind::call_function( - luaState, - "get_exceptions", - boost::ref(restriction_exceptions) - ); - INFO("Found " << restriction_exceptions.size() << " exceptions to turn restriction"); - BOOST_FOREACH(std::string & str, restriction_exceptions) { - INFO(" " << str); - } - } catch (const luabind::error &er) { - lua_State* Ler=er.state(); - report_errors(Ler, -1); - ERR(er.what()); + luabind::call_function( + luaState, + "get_exceptions", + boost::ref(restriction_exceptions) + ); + SimpleLogger().Write() << "Found " << restriction_exceptions.size() << " exceptions to turn restriction"; + BOOST_FOREACH(const std::string & str, restriction_exceptions) { + SimpleLogger().Write() << " " << str; } } 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) { - try { - luabind::call_function( localLuaState, "node_function", boost::ref(n) ); - } catch (const luabind::error &er) { - lua_State* Ler=er.state(); - report_errors(Ler, -1); - ERR(er.what()); - } + luabind::call_function( localLuaState, "node_function", boost::ref(n) ); } void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) { if(2 > w.path.size()) { return; } - try { - luabind::call_function( localLuaState, "way_function", boost::ref(w) ); - } catch (const luabind::error &er) { - lua_State* Ler=er.state(); - report_errors(Ler, -1); - ERR(er.what()); - } + luabind::call_function( localLuaState, "way_function", boost::ref(w) ); } bool BaseParser::ShouldIgnoreRestriction(const std::string& except_tag_string) const { //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 //b) the lua profile defines a hierachy of modes, ex: [access, vehicle, bicycle] - + if( "" == except_tag_string ) { return false; } - + //Be warned, this is quadratic work here, but we assume that //only a few exceptions are actually defined. std::vector exceptions; diff --git a/Extractor/BaseParser.h b/Extractor/BaseParser.h index 690f8a247..64228b53d 100644 --- a/Extractor/BaseParser.h +++ b/Extractor/BaseParser.h @@ -23,6 +23,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "ExtractorCallbacks.h" #include "ScriptingEnvironment.h" +#include "../Util/OSRMException.h" +#include "../Util/SimpleLogger.h" extern "C" { #include diff --git a/Extractor/ExtractionContainers.cpp b/Extractor/ExtractionContainers.cpp index 292e994cf..515c78b84 100644 --- a/Extractor/ExtractionContainers.cpp +++ b/Extractor/ExtractionContainers.cpp @@ -117,7 +117,7 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con ++restrictionsIT; } std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; - INFO("usable restrictions: " << usableRestrictionsCounter ); + SimpleLogger().Write() << "usable restrictions: " << usableRestrictionsCounter; //serialize restrictions std::ofstream restrictionsOutstream; 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)); for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) { 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(); @@ -298,7 +298,7 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con // addressOutFile.close(); // 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 ) { diff --git a/Extractor/ExtractionContainers.h b/Extractor/ExtractionContainers.h index 78c1b2a62..96b8ba357 100644 --- a/Extractor/ExtractionContainers.h +++ b/Extractor/ExtractionContainers.h @@ -22,7 +22,8 @@ #define EXTRACTIONCONTAINERS_H_ #include "ExtractorStructs.h" -#include "../DataStructures/TimingUtil.h" +#include "../Util/SimpleLogger.h" +#include "../Util/TimingUtil.h" #include "../Util/UUID.h" #include @@ -39,14 +40,10 @@ public: ExtractionContainers() { //Check if another instance of stxxl is already running or if there is a general problem - try { - stxxl::vector testForRunningInstance; - } catch(std::exception & e) { - ERR("Could not instantiate STXXL layer." << std::endl << e.what()); - } - + stxxl::vector testForRunningInstance; nameVector.push_back(""); } + virtual ~ExtractionContainers() { usedNodeIDs.clear(); allNodes.clear(); diff --git a/Extractor/ExtractorCallbacks.cpp b/Extractor/ExtractorCallbacks.cpp index db8e8f8f9..f2f53a02b 100644 --- a/Extractor/ExtractorCallbacks.cpp +++ b/Extractor/ExtractorCallbacks.cpp @@ -31,7 +31,7 @@ ExtractorCallbacks::~ExtractorCallbacks() { } /** warning: caller needs to take care of synchronization! */ 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); } } @@ -45,7 +45,9 @@ bool ExtractorCallbacks::restrictionFunction(const _RawRestrictionContainer &r) 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(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; } @@ -55,7 +57,8 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) { } 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; } diff --git a/Extractor/ExtractorCallbacks.h b/Extractor/ExtractorCallbacks.h index 3e9fcddf5..b175f76fa 100644 --- a/Extractor/ExtractorCallbacks.h +++ b/Extractor/ExtractorCallbacks.h @@ -21,8 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef EXTRACTORCALLBACKS_H_ #define EXTRACTORCALLBACKS_H_ -#include -#include +#include "ExtractionContainers.h" +#include "ExtractionHelperFunctions.h" +#include "ExtractorStructs.h" + +#include "../DataStructures/Coordinate.h" #include @@ -30,9 +33,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include -#include "ExtractionContainers.h" -#include "ExtractionHelperFunctions.h" -#include "ExtractorStructs.h" +#include +#include class ExtractorCallbacks{ private: diff --git a/Extractor/ExtractorStructs.h b/Extractor/ExtractorStructs.h index b481469f6..778778ed0 100644 --- a/Extractor/ExtractorStructs.h +++ b/Extractor/ExtractorStructs.h @@ -21,13 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef EXTRACTORSTRUCTS_H_ #define EXTRACTORSTRUCTS_H_ - #include "../DataStructures/Coordinate.h" #include "../DataStructures/HashTable.h" #include "../DataStructures/ImportNode.h" -#include "../DataStructures/NodeCoords.h" +#include "../DataStructures/QueryNode.h" #include "../DataStructures/Restriction.h" -#include "../DataStructures/TimingUtil.h" #include "../typedefs.h" #include @@ -50,7 +48,7 @@ struct ExtractionWay { id = UINT_MAX; nameID = UINT_MAX; path.clear(); - keyVals.EraseAll(); + keyVals.clear(); direction = ExtractionWay::notSure; speed = -1; backward_speed = -1; @@ -111,8 +109,8 @@ struct InternalExtractorEdge { bool isAccessRestricted; bool isContraFlow; - _Coordinate startCoord; - _Coordinate targetCoord; + FixedPointCoordinate startCoord; + FixedPointCoordinate targetCoord; static InternalExtractorEdge min_value() { return InternalExtractorEdge(0,0); diff --git a/Extractor/PBFParser.cpp b/Extractor/PBFParser.cpp index 51b099f98..413217cc8 100644 --- a/Extractor/PBFParser.cpp +++ b/Extractor/PBFParser.cpp @@ -28,7 +28,7 @@ PBFParser::PBFParser(const char * fileName, ExtractorCallbacks* ec, ScriptingEnv input.open(fileName, std::ios::in | std::ios::binary); if (!input) { - std::cerr << fileName << ": File not found." << std::endl; + throw OSRMException("pbf file not found."); } #ifndef NDEBUG @@ -50,7 +50,10 @@ PBFParser::~PBFParser() { google::protobuf::ShutdownProtobufLibrary(); #ifndef NDEBUG - DEBUG("parsed " << blockCount << " blocks from pbf with " << groupCount << " groups"); + SimpleLogger().Write(logDEBUG) << + "parsed " << blockCount << + " blocks from pbf with " << groupCount << + " groups"; #endif } @@ -108,7 +111,7 @@ inline void PBFParser::ParseData() { _ThreadData *threadData; threadDataQueue->wait_and_pop(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 break; } @@ -166,8 +169,8 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) { m_lastDenseLatitude += dense.lat( i ); m_lastDenseLongitude += dense.lon( i ); 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].lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_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 = COORDINATE_PRECISION*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO; while (denseTagIndex < dense.keys_vals_size()) { const int tagValue = dense.keys_vals( denseTagIndex ); if( 0==tagValue ) { @@ -177,7 +180,7 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) { const int keyValue = dense.keys_vals ( denseTagIndex+1 ); const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).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; } } @@ -194,7 +197,9 @@ inline void PBFParser::parseDenseNode(_ThreadData * 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) { @@ -304,7 +309,7 @@ inline void PBFParser::parseWay(_ThreadData * threadData) { for(int j = 0; j < number_of_keys; ++j) { const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(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() ) ) { - ERR("failed to parse PrimitiveBlock"); + std::cerr << "failed to parse PrimitiveBlock" << std::endl; return false; } return true; diff --git a/Extractor/PBFParser.h b/Extractor/PBFParser.h index a1606bb6f..ec5035f3d 100644 --- a/Extractor/PBFParser.h +++ b/Extractor/PBFParser.h @@ -23,10 +23,13 @@ #include "BaseParser.h" +#include "../DataStructures/Coordinate.h" #include "../DataStructures/HashTable.h" #include "../DataStructures/ConcurrentQueue.h" #include "../Util/MachineInfo.h" #include "../Util/OpenMPWrapper.h" +#include "../Util/OSRMException.h" +#include "../Util/SimpleLogger.h" #include "../typedefs.h" #include diff --git a/Extractor/ScriptingEnvironment.cpp b/Extractor/ScriptingEnvironment.cpp index 6bab21c5f..fba59f89d 100644 --- a/Extractor/ScriptingEnvironment.cpp +++ b/Extractor/ScriptingEnvironment.cpp @@ -22,11 +22,12 @@ ScriptingEnvironment::ScriptingEnvironment() {} ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { - INFO("Using script " << fileName); + SimpleLogger().Write() << "Using script " << fileName; // 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()); + } // Connect LuaBind to this lua state for all threads #pragma omp parallel @@ -40,59 +41,59 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { // Add our function to the state's global scope luabind::module(myLuaState) [ - luabind::def("print", LUA_print), - luabind::def("parseMaxspeed", parseMaxspeed), - luabind::def("durationIsValid", durationIsValid), - luabind::def("parseDuration", parseDuration) + luabind::def("print", LUA_print), + luabind::def("parseMaxspeed", parseMaxspeed), + luabind::def("durationIsValid", durationIsValid), + luabind::def("parseDuration", parseDuration) ]; luabind::module(myLuaState) [ - luabind::class_ >("keyVals") - .def("Add", &HashTable::Add) - .def("Find", &HashTable::Find) - .def("Holds", &HashTable::Holds) - ]; + luabind::class_ >("keyVals") + .def("Add", &HashTable::Add) + .def("Find", &HashTable::Find) + .def("Holds", &HashTable::Holds) + ]; luabind::module(myLuaState) [ - luabind::class_("Node") - .def(luabind::constructor<>()) - .def_readwrite("lat", &ImportNode::lat) - .def_readwrite("lon", &ImportNode::lon) - .def_readwrite("id", &ImportNode::id) - .def_readwrite("bollard", &ImportNode::bollard) - .def_readwrite("traffic_light", &ImportNode::trafficLight) - .def_readwrite("tags", &ImportNode::keyVals) - ]; + luabind::class_("Node") + .def(luabind::constructor<>()) + .def_readwrite("lat", &ImportNode::lat) + .def_readwrite("lon", &ImportNode::lon) + .def_readwrite("id", &ImportNode::id) + .def_readwrite("bollard", &ImportNode::bollard) + .def_readwrite("traffic_light", &ImportNode::trafficLight) + .def_readwrite("tags", &ImportNode::keyVals) + ]; luabind::module(myLuaState) [ - luabind::class_("Way") - .def(luabind::constructor<>()) - .def_readwrite("name", &ExtractionWay::name) - .def_readwrite("speed", &ExtractionWay::speed) - .def_readwrite("backward_speed", &ExtractionWay::backward_speed) - .def_readwrite("duration", &ExtractionWay::duration) - .def_readwrite("type", &ExtractionWay::type) - .def_readwrite("access", &ExtractionWay::access) - .def_readwrite("roundabout", &ExtractionWay::roundabout) - .def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted) - .def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid) - .def_readwrite("tags", &ExtractionWay::keyVals) - .def_readwrite("direction", &ExtractionWay::direction) - .enum_("constants") - [ - luabind::value("notSure", 0), - luabind::value("oneway", 1), - luabind::value("bidirectional", 2), - luabind::value("opposite", 3) - ] - ]; + luabind::class_("Way") + .def(luabind::constructor<>()) + .def_readwrite("name", &ExtractionWay::name) + .def_readwrite("speed", &ExtractionWay::speed) + .def_readwrite("backward_speed", &ExtractionWay::backward_speed) + .def_readwrite("duration", &ExtractionWay::duration) + .def_readwrite("type", &ExtractionWay::type) + .def_readwrite("access", &ExtractionWay::access) + .def_readwrite("roundabout", &ExtractionWay::roundabout) + .def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted) + .def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid) + .def_readwrite("tags", &ExtractionWay::keyVals) + .def_readwrite("direction", &ExtractionWay::direction) + .enum_("constants") [ + luabind::value("notSure", 0), + luabind::value("oneway", 1), + luabind::value("bidirectional", 2), + luabind::value("opposite", 3) + ] + ]; + luabind::module(myLuaState) [ - luabind::class_ >("vector") - .def("Add", &std::vector::push_back) - ]; + luabind::class_ >("vector") + .def("Add", &std::vector::push_back) + ]; if(0 != luaL_dofile(myLuaState, fileName) ) { - ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block"); + throw OSRMException("ERROR occured in scripting block"); } } } diff --git a/Extractor/ScriptingEnvironment.h b/Extractor/ScriptingEnvironment.h index efb128100..fc4b97e1a 100644 --- a/Extractor/ScriptingEnvironment.h +++ b/Extractor/ScriptingEnvironment.h @@ -26,6 +26,8 @@ #include "../DataStructures/ImportNode.h" #include "../Util/LuaUtil.h" #include "../Util/OpenMPWrapper.h" +#include "../Util/OSRMException.h" +#include "../Util/SimpleLogger.h" #include "../typedefs.h" #include diff --git a/Extractor/XMLParser.cpp b/Extractor/XMLParser.cpp index 90590e5e9..2ab6e7335 100644 --- a/Extractor/XMLParser.cpp +++ b/Extractor/XMLParser.cpp @@ -27,7 +27,9 @@ #include 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); } @@ -217,12 +219,12 @@ ImportNode XMLParser::_ReadXMLNode() { xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" ); if ( attribute != NULL ) { - node.lat = static_cast(100000.*atof(( const char* ) attribute ) ); + node.lat = static_cast(COORDINATE_PRECISION*atof(( const char* ) attribute ) ); xmlFree( attribute ); } attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" ); if ( attribute != NULL ) { - node.lon = static_cast(100000.*atof(( const char* ) attribute )); + node.lon = static_cast(COORDINATE_PRECISION*atof(( const char* ) attribute )); xmlFree( attribute ); } attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); diff --git a/Extractor/XMLParser.h b/Extractor/XMLParser.h index d17230dfe..51b7b1b1e 100644 --- a/Extractor/XMLParser.h +++ b/Extractor/XMLParser.h @@ -22,6 +22,8 @@ #define XMLPARSER_H_ #include "BaseParser.h" +#include "../DataStructures/Coordinate.h" +#include "../Util/SimpleLogger.h" #include "../Util/StringUtil.h" #include "../typedefs.h" diff --git a/Library/OSRM.cpp b/Library/OSRM.cpp index e656a605c..1a0c8f5e9 100644 --- a/Library/OSRM.cpp +++ b/Library/OSRM.cpp @@ -22,18 +22,71 @@ or see http://www.gnu.org/licenses/agpl.txt. OSRM::OSRM(const char * 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( - serverConfig.GetParameter("hsgrData"), - serverConfig.GetParameter("ramIndex"), - serverConfig.GetParameter("fileIndex"), - serverConfig.GetParameter("nodesData"), - serverConfig.GetParameter("edgesData"), - serverConfig.GetParameter("namesData"), - serverConfig.GetParameter("timestamp") + hsgr_path.string(), + ram_index_path.string(), + file_index_path.string(), + node_data_path.string(), + edge_data_path.string(), + name_data_path.string(), + timestamp_path.string() ); RegisterPlugin(new HelloWorldPlugin()); @@ -51,8 +104,11 @@ OSRM::~OSRM() { } void OSRM::RegisterPlugin(BasePlugin * plugin) { - std::cout << "[plugin] " << plugin->GetDescriptor() << std::endl; - pluginMap[plugin->GetDescriptor()] = plugin; + SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor(); + 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) { diff --git a/Library/OSRM.h b/Library/OSRM.h index 9a4c601d5..bb3caa7d9 100644 --- a/Library/OSRM.h +++ b/Library/OSRM.h @@ -29,28 +29,20 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../Plugins/NearestPlugin.h" #include "../Plugins/TimestampPlugin.h" #include "../Plugins/ViaRoutePlugin.h" -#include "../Plugins/RouteParameters.h" -#include "../Util/BaseConfiguration.h" +#include "../Server/DataStructures/RouteParameters.h" +#include "../Util/IniFile.h" #include "../Util/InputFileUtil.h" +#include "../Util/OSRMException.h" +#include "../Util/SimpleLogger.h" #include "../Server/BasicDatastructures.h" #include +#include #include #include -#include #include -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 { typedef boost::unordered_map PluginMap; QueryObjectsStorage * objects; @@ -63,4 +55,4 @@ private: PluginMap pluginMap; }; -#endif //OSRM_H \ No newline at end of file +#endif //OSRM_H diff --git a/Plugins/BasePlugin.h b/Plugins/BasePlugin.h index 954edbf8b..f359942af 100644 --- a/Plugins/BasePlugin.h +++ b/Plugins/BasePlugin.h @@ -21,8 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef BASEPLUGIN_H_ #define BASEPLUGIN_H_ -#include "RouteParameters.h" +#include "../DataStructures/Coordinate.h" #include "../Server/BasicDatastructures.h" +#include "../Server/DataStructures/RouteParameters.h" #include #include @@ -32,9 +33,20 @@ public: BasePlugin() { } //Maybe someone can explain the pure virtual destructor thing to me (dennis) virtual ~BasePlugin() { } - virtual std::string GetDescriptor() const = 0; - virtual std::string GetVersionString() const = 0 ; + virtual const std::string & GetDescriptor() const = 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_ */ diff --git a/Plugins/HelloWorldPlugin.h b/Plugins/HelloWorldPlugin.h index 6315dad8c..7c2987ecf 100644 --- a/Plugins/HelloWorldPlugin.h +++ b/Plugins/HelloWorldPlugin.h @@ -1,24 +1,35 @@ /* - * LocatePlugin.h - * - * Created on: 01.01.2011 - * Author: dennis + 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 HELLOWORLDPLUGIN_H_ #define HELLOWORLDPLUGIN_H_ #include "BasePlugin.h" -#include "RouteParameters.h" #include class HelloWorldPlugin : public BasePlugin { public: - HelloWorldPlugin() {} + HelloWorldPlugin() : descriptor_string("hello"){} virtual ~HelloWorldPlugin() { } - std::string GetDescriptor() const { return std::string("hello"); } - std::string GetVersionString() const { return std::string("0.1a"); } + const std::string & GetDescriptor() const { return descriptor_string; } void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { reply.status = http::Reply::ok; @@ -35,7 +46,7 @@ public: content << "language: " << routeParameters.language << "
"; content << "Number of locations: " << routeParameters.coordinates.size() << "\n"; 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"; for(unsigned i = 0; i < routeParameters.hints.size(); ++i) { @@ -45,6 +56,8 @@ public: reply.content.append(content.str()); reply.content.append(""); } +private: + std::string descriptor_string; }; #endif /* HELLOWORLDPLUGIN_H_ */ diff --git a/Plugins/LocatePlugin.h b/Plugins/LocatePlugin.h index f1c7d60ac..c1c69c009 100644 --- a/Plugins/LocatePlugin.h +++ b/Plugins/LocatePlugin.h @@ -22,23 +22,19 @@ or see http://www.gnu.org/licenses/agpl.txt. #define LOCATEPLUGIN_H_ #include "BasePlugin.h" -#include "RouteParameters.h" #include "../DataStructures/NodeInformationHelpDesk.h" #include "../Server/DataStructures/QueryObjectsStorage.h" #include "../Util/StringUtil.h" -#include - /* * This Plugin locates the nearest node in the road network for a given coordinate. */ class LocatePlugin : public BasePlugin { public: - LocatePlugin(QueryObjectsStorage * objects) { + LocatePlugin(QueryObjectsStorage * objects) : descriptor_string("locate") { nodeHelpDesk = objects->nodeHelpDesk; } - std::string GetDescriptor() const { return std::string("locate"); } - 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) { //check number of parameters if(!routeParameters.coordinates.size()) { @@ -51,7 +47,7 @@ public: } //query to helpdesk - _Coordinate result; + FixedPointCoordinate result; std::string tmp; //json @@ -99,15 +95,10 @@ public: reply.headers[0].value = tmp; 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; + std::string descriptor_string; }; #endif /* LOCATEPLUGIN_H_ */ diff --git a/Plugins/NearestPlugin.h b/Plugins/NearestPlugin.h index 0b60225ef..89bbc86e5 100644 --- a/Plugins/NearestPlugin.h +++ b/Plugins/NearestPlugin.h @@ -22,27 +22,27 @@ or see http://www.gnu.org/licenses/agpl.txt. #define NearestPlugin_H_ #include "BasePlugin.h" -#include "RouteParameters.h" #include "../DataStructures/NodeInformationHelpDesk.h" #include "../Server/DataStructures/QueryObjectsStorage.h" #include "../Util/StringUtil.h" -#include - /* * This Plugin locates the nearest point on a street in the road network for a given coordinate. */ class NearestPlugin : public BasePlugin { public: - NearestPlugin(QueryObjectsStorage * objects) : names(objects->names) { + NearestPlugin(QueryObjectsStorage * objects ) + : + names(objects->names), + descriptor_string("nearest") + { nodeHelpDesk = objects->nodeHelpDesk; - descriptorTable.Set("", 0); //default descriptor - descriptorTable.Set("json", 1); + descriptorTable.insert(std::make_pair("" , 0)); //default descriptor + descriptorTable.insert(std::make_pair("json", 1)); } - std::string GetDescriptor() const { return std::string("nearest"); } - 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) { //check number of parameters if(!routeParameters.coordinates.size()) { @@ -107,17 +107,12 @@ public: intToString(reply.content.size(), 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; HashTable descriptorTable; std::vector & names; + std::string descriptor_string; }; #endif /* NearestPlugin_H_ */ diff --git a/Plugins/TimestampPlugin.h b/Plugins/TimestampPlugin.h index 6a245e116..ba0510c3e 100644 --- a/Plugins/TimestampPlugin.h +++ b/Plugins/TimestampPlugin.h @@ -22,16 +22,13 @@ or see http://www.gnu.org/licenses/agpl.txt. #define TIMESTAMPPLUGIN_H_ #include "BasePlugin.h" -#include "RouteParameters.h" - -#include class TimestampPlugin : public BasePlugin { public: - TimestampPlugin(QueryObjectsStorage * o) : objects(o) { - } - std::string GetDescriptor() const { return std::string("timestamp"); } - std::string GetVersionString() const { return std::string("0.3 (DL)"); } + TimestampPlugin(QueryObjectsStorage * o) + : objects(o), descriptor_string("timestamp") + { } + const std::string & GetDescriptor() const { return descriptor_string; } void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { std::string tmp; @@ -70,6 +67,7 @@ public: } private: QueryObjectsStorage * objects; + std::string descriptor_string; }; #endif /* TIMESTAMPPLUGIN_H_ */ diff --git a/Plugins/ViaRoutePlugin.h b/Plugins/ViaRoutePlugin.h index 1bd924ece..847a32a9f 100644 --- a/Plugins/ViaRoutePlugin.h +++ b/Plugins/ViaRoutePlugin.h @@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt. #define VIAROUTEPLUGIN_H_ #include "BasePlugin.h" -#include "RouteParameters.h" #include "../Algorithms/ObjectToBase64.h" #include "../DataStructures/HashTable.h" @@ -33,12 +32,11 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../Descriptors/GPXDescriptor.h" #include "../Descriptors/JSONDescriptor.h" #include "../Server/DataStructures/QueryObjectsStorage.h" +#include "../Util/SimpleLogger.h" #include "../Util/StringUtil.h" #include -#include -#include #include #include @@ -48,27 +46,30 @@ private: std::vector & names; StaticGraph * graph; HashTable descriptorTable; - std::string pluginDescriptorString; SearchEngine * searchEnginePtr; 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; graph = objects->graph; searchEnginePtr = new SearchEngine(graph, nodeHelpDesk, names); - descriptorTable.Set("", 0); //default descriptor - descriptorTable.Set("json", 0); - descriptorTable.Set("gpx", 1); + descriptorTable.insert(std::make_pair("" , 0)); + descriptorTable.insert(std::make_pair("json", 0)); + descriptorTable.insert(std::make_pair("gpx" , 1)); } virtual ~ViaRoutePlugin() { delete searchEnginePtr; } - std::string GetDescriptor() const { return pluginDescriptorString; } - 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) { //check number of parameters if( 2 > routeParameters.coordinates.size() ) { @@ -90,14 +91,14 @@ public: std::vector phantomNodeVector(rawRoute.rawViaNodeCoordinates.size()); for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++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]); if(phantomNodeVector[i].isValid(nodeHelpDesk->getNumberOfNodes())) { -// INFO("Decoded hint " << i << " successfully"); +// SimpleLogger().Write() << "Decoded hint " << i << " successfully"; 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); } @@ -108,7 +109,7 @@ public: rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes); } if( ( routeParameters.alternateRoute ) && (1 == rawRoute.segmentEndCoordinates.size()) ) { -// INFO("Checking for alternative paths"); +// SimpleLogger().Write() << "Checking for alternative paths"; searchEnginePtr->alternativePaths(rawRoute.segmentEndCoordinates[0], rawRoute); } else { @@ -117,7 +118,7 @@ public: 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; @@ -152,10 +153,10 @@ public: PhantomNodes phantomNodes; 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; -// INFO("TargetLocation: " << phantomNodes.targetPhantom.location); -// INFO("Number of segments: " << rawRoute.segmentEndCoordinates.size()); +// SimpleLogger().Write() << "TargetLocation: " << phantomNodes.targetPhantom.location; +// SimpleLogger().Write() << "Number of segments: " << rawRoute.segmentEndCoordinates.size(); desc->SetConfig(descriptorConfig); desc->Run(reply, rawRoute, phantomNodes, *searchEnginePtr); @@ -201,7 +202,6 @@ public: reply.headers[2].name = "Content-Disposition"; reply.headers[2].value = "attachment; filename=\"route.json\""; } - break; } @@ -209,12 +209,7 @@ public: 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; - } + std::string descriptor_string; }; diff --git a/README.md b/README.md new file mode 100644 index 000000000..1c77f7202 --- /dev/null +++ b/README.md @@ -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) | diff --git a/RoutingAlgorithms/AlternativePathRouting.h b/RoutingAlgorithms/AlternativePathRouting.h index 8c3e53ef3..8b54a3de5 100644 --- a/RoutingAlgorithms/AlternativePathRouting.h +++ b/RoutingAlgorithms/AlternativePathRouting.h @@ -307,7 +307,7 @@ private: int aindex = 0; //compute forward sharing 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]); sharing += search_graph->GetEdgeData(edgeID).distance; ++aindex; diff --git a/RoutingAlgorithms/BasicRoutingInterface.h b/RoutingAlgorithms/BasicRoutingInterface.h index caef97a96..cb956b504 100644 --- a/RoutingAlgorithms/BasicRoutingInterface.h +++ b/RoutingAlgorithms/BasicRoutingInterface.h @@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef BASICROUTINGINTERFACE_H_ #define BASICROUTINGINTERFACE_H_ -#include "../Plugins/RawRouteData.h" +#include "../DataStructures/RawRouteData.h" #include "../Util/ContainerUtils.h" +#include "../Util/SimpleLogger.h" #include @@ -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 { const NodeID node = _forwardHeap.DeleteMin(); 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) ){ const int newDistance = _backwardHeap.GetKey(node) + distance; if(newDistance < *_upperbound ){ diff --git a/Server/DataStructures/QueryObjectsStorage.cpp b/Server/DataStructures/QueryObjectsStorage.cpp index 69142434c..27a906312 100644 --- a/Server/DataStructures/QueryObjectsStorage.cpp +++ b/Server/DataStructures/QueryObjectsStorage.cpp @@ -20,7 +20,6 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "QueryObjectsStorage.h" -#include "../../Util/GraphLoader.h" QueryObjectsStorage::QueryObjectsStorage( const std::string & hsgrPath, @@ -31,29 +30,47 @@ QueryObjectsStorage::QueryObjectsStorage( const std::string & namesPath, const std::string & timestampPath ) { - INFO("loading graph data"); - std::ifstream hsgrInStream(hsgrPath.c_str(), std::ios::binary); - if(!hsgrInStream) { ERR(hsgrPath << " not found"); } + if( hsgrPath.empty() ) { + throw OSRMException("no hsgr file given in ini file"); + } + 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 std::vector< QueryGraph::_StrNode> nodeList; std::vector< QueryGraph::_StrEdge> edgeList; const int n = readHSGRFromStream( - hsgrInStream, + hsgrPath, nodeList, edgeList, &checkSum ); - hsgrInStream.close(); - INFO("Data checksum is " << checkSum); + SimpleLogger().Write() << "Data checksum is " << checkSum; graph = new QueryGraph(nodeList, edgeList); assert(0 == nodeList.size()); assert(0 == edgeList.size()); if(timestampPath.length()) { - INFO("Loading Timestamp"); + SimpleLogger().Write() << "Loading Timestamp"; std::ifstream timestampInStream(timestampPath.c_str()); - if(!timestampInStream) { WARN(timestampPath << " not found"); } + if(!timestampInStream) { + SimpleLogger().Write(logWARNING) << timestampPath << " not found"; + } getline(timestampInStream, timestamp); timestampInStream.close(); @@ -65,7 +82,7 @@ QueryObjectsStorage::QueryObjectsStorage( timestamp.resize(25); } - INFO("Loading auxiliary information"); + SimpleLogger().Write() << "Loading auxiliary information"; //Init nearest neighbor data structure nodeHelpDesk = new NodeInformationHelpDesk( ramIndexPath, @@ -77,23 +94,33 @@ QueryObjectsStorage::QueryObjectsStorage( ); //deserialize street name list - INFO("Loading names index"); - std::ifstream namesInStream(namesPath.c_str(), std::ios::binary); - if(!namesInStream) { ERR(namesPath << " not found"); } - unsigned size(0); - namesInStream.read((char *)&size, sizeof(unsigned)); + SimpleLogger().Write() << "Loading names index"; + boost::filesystem::path names_file(namesPath); + + if ( !boost::filesystem::exists( names_file ) ) { + 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]; - for(unsigned i = 0; i < size; ++i) { - unsigned sizeOfString = 0; - namesInStream.read((char *)&sizeOfString, sizeof(unsigned)); - buf[sizeOfString] = '\0'; // instead of memset - namesInStream.read(buf, sizeOfString); + for( unsigned i = 0; i < size; ++i ) { + unsigned size_of_string = 0; + name_stream.read((char *)&size_of_string, sizeof(unsigned)); + buf[size_of_string] = '\0'; // instead of memset + name_stream.read(buf, size_of_string); names.push_back(buf); } std::vector(names).swap(names); - namesInStream.close(); - INFO("All query data structures loaded"); + BOOST_ASSERT_MSG(0 != names.size(), "could not load any names"); + name_stream.close(); + SimpleLogger().Write() << "All query data structures loaded"; } QueryObjectsStorage::~QueryObjectsStorage() { diff --git a/Server/DataStructures/QueryObjectsStorage.h b/Server/DataStructures/QueryObjectsStorage.h index cd1b63b63..0f7ba2a6d 100644 --- a/Server/DataStructures/QueryObjectsStorage.h +++ b/Server/DataStructures/QueryObjectsStorage.h @@ -22,13 +22,21 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef QUERYOBJECTSSTORAGE_H_ #define QUERYOBJECTSSTORAGE_H_ -#include -#include - +#include "../../Util/GraphLoader.h" +#include "../../Util/OSRMException.h" +#include "../../Util/SimpleLogger.h" #include "../../DataStructures/NodeInformationHelpDesk.h" #include "../../DataStructures/QueryEdge.h" #include "../../DataStructures/StaticGraph.h" +#include +#include +#include + +#include +#include + + struct QueryObjectsStorage { typedef StaticGraph QueryGraph; typedef QueryGraph::InputEdge InputEdge; diff --git a/Plugins/RouteParameters.h b/Server/DataStructures/RouteParameters.h similarity index 82% rename from Plugins/RouteParameters.h rename to Server/DataStructures/RouteParameters.h index 88fd1c260..f46a20a10 100644 --- a/Plugins/RouteParameters.h +++ b/Server/DataStructures/RouteParameters.h @@ -21,8 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef ROUTE_PARAMETERS_H #define ROUTE_PARAMETERS_H -#include "../DataStructures/Coordinate.h" -#include "../DataStructures/HashTable.h" +#include "../../DataStructures/Coordinate.h" +#include "../../DataStructures/HashTable.h" #include #include @@ -52,12 +52,13 @@ struct RouteParameters { std::string jsonpParameter; std::string language; std::vector hints; - std::vector<_Coordinate> coordinates; - typedef HashTable::MyIterator OptionsIterator; + std::vector coordinates; + typedef HashTable::const_iterator OptionsIterator; void setZoomLevel(const short i) { - if (18 > i && 0 < i) + if (18 > i && 0 < i) { zoomLevel = i; + } } void setAlternateRouteFlag(const bool b) { @@ -105,13 +106,11 @@ struct RouteParameters { compression = b; } - void addCoordinate(boost::fusion::vector < double, double > arg_) { - int lat = 100000.*boost::fusion::at_c < 0 > (arg_); - int lon = 100000.*boost::fusion::at_c < 1 > (arg_); - _Coordinate myCoordinate(lat, lon); - coordinates.push_back(_Coordinate(lat, lon)); + void addCoordinate(const boost::fusion::vector < double, double > & arg_) { + int lat = COORDINATE_PRECISION*boost::fusion::at_c < 0 > (arg_); + int lon = COORDINATE_PRECISION*boost::fusion::at_c < 1 > (arg_); + coordinates.push_back(FixedPointCoordinate(lat, lon)); } }; - #endif /*ROUTE_PARAMETERS_H*/ diff --git a/Server/RequestHandler.h b/Server/RequestHandler.h index 0f91601ab..af2217f7b 100644 --- a/Server/RequestHandler.h +++ b/Server/RequestHandler.h @@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "APIGrammar.h" #include "BasicDatastructures.h" +#include "DataStructures/RouteParameters.h" #include "../Library/OSRM.h" -#include "../Plugins/RouteParameters.h" +#include "../Util/SimpleLogger.h" #include "../Util/StringUtil.h" #include "../typedefs.h" @@ -46,25 +47,35 @@ public: try { std::string request(req.uri); - { //This block logs the current request to std out. should be moved to a logging component - time_t ltime; - struct tm *Tm; + time_t ltime; + struct tm *Tm; - ltime=time(NULL); - Tm=localtime(<ime); + ltime=time(NULL); + Tm=localtime(<ime); - 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 << " " << - req.endpoint.to_string() << " " << req.referrer << ( 0 == req.referrer.length() ? "- " :" ") << req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri ); - } + SimpleLogger().Write() << + (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; APIGrammarParser apiParser(&routeParameters); std::string::iterator it = request.begin(); - bool result = boost::spirit::qi::parse(it, request.end(), apiParser); - if (!result || (it != request.end()) ) { + const bool result = boost::spirit::qi::parse( + it, + request.end(), + apiParser + ); + + if ( !result || (it != request.end()) ) { 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; intToString(position, tmp_position_string); rep.content += "Input seems to be malformed close to position "; @@ -72,7 +83,7 @@ public: rep.content += request; rep.content += tmp_position_string; rep.content += "
"; - unsigned end = std::distance(request.begin(), it); + const unsigned end = std::distance(request.begin(), it); for(unsigned i = 0; i < end; ++i) { rep.content += " "; } @@ -84,7 +95,8 @@ public: } } catch(std::exception& e) { 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; } }; diff --git a/Server/RequestParser.h b/Server/RequestParser.h index 7e33f9e09..54829de0a 100644 --- a/Server/RequestParser.h +++ b/Server/RequestParser.h @@ -21,9 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef REQUEST_PARSER_H #define REQUEST_PARSER_H +#include "BasicDatastructures.h" + #include #include -#include "BasicDatastructures.h" namespace http { diff --git a/Server/ServerFactory.h b/Server/ServerFactory.h index 160e5ac10..60502e257 100644 --- a/Server/ServerFactory.h +++ b/Server/ServerFactory.h @@ -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 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or see http://www.gnu.org/licenses/agpl.txt. - - Created on: 26.11.2010 - Author: dennis - */ #ifndef SERVERFACTORY_H_ #define SERVERFACTORY_H_ #include "Server.h" - -#include "../Util/BaseConfiguration.h" -#include "../Util/InputFileUtil.h" -#include "../Util/OpenMPWrapper.h" +#include "../Util/IniFile.h" +#include "../Util/SimpleLogger.h" #include "../Util/StringUtil.h" -#include "../typedefs.h" - #include -struct ServerFactory { - 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"); - } +#include +struct ServerFactory : boost::noncopyable { + static Server * CreateServer( IniFile & serverConfig ) { int threads = omp_get_num_procs(); - if(serverConfig.GetParameter("IP") == "") + if( serverConfig.GetParameter("IP").empty() ) { serverConfig.SetParameter("IP", "0.0.0.0"); - if(serverConfig.GetParameter("Port") == "") + } + + if( serverConfig.GetParameter("Port").empty() ) { 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") ); + } - std::cout << "[server] http 1.1 compression handled by zlib version " << zlibVersion() << std::endl; - Server * server = new Server(serverConfig.GetParameter("IP"), serverConfig.GetParameter("Port"), threads); + SimpleLogger().Write() << + "http 1.1 compression handled by zlib version " << zlibVersion(); + + Server * server = new Server( + serverConfig.GetParameter("IP"), + serverConfig.GetParameter("Port"), + threads + ); return server; } static Server * CreateServer(const char * iniFile) { - BaseConfiguration serverConfig(iniFile); + IniFile serverConfig(iniFile); return CreateServer(serverConfig); } }; diff --git a/Tools/componentAnalysis.cpp b/Tools/componentAnalysis.cpp index 664c58954..12d0a1d64 100644 --- a/Tools/componentAnalysis.cpp +++ b/Tools/componentAnalysis.cpp @@ -25,9 +25,11 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../DataStructures/DynamicGraph.h" #include "../DataStructures/QueryEdge.h" #include "../DataStructures/TurnInstructions.h" -#include "../Util/BaseConfiguration.h" -#include "../Util/InputFileUtil.h" #include "../Util/GraphLoader.h" +#include "../Util/IniFile.h" +#include "../Util/InputFileUtil.h" +#include "../Util/OSRMException.h" +#include "../Util/SimpleLogger.h" #include #include @@ -39,22 +41,25 @@ or see http://www.gnu.org/licenses/agpl.txt. typedef QueryEdge::EdgeData EdgeData; typedef DynamicGraph::InputEdge InputEdge; -typedef BaseConfiguration ContractorConfiguration; std::vector internal_to_external_node_map; -std::vector<_Restriction> restrictions_vector; +std::vector restrictions_vector; std::vector bollard_node_IDs_vector; std::vector traffic_light_node_IDs_vector; -int main (int argument_count, char *argument_values[]) { - if(argument_count < 3) { - ERR("usage:\n" << argument_values[0] << " "); +int main (int argc, char * argv[]) { + LogPolicy::GetInstance().Unmute(); + if(argc < 3) { + SimpleLogger().Write(logWARNING) << + "usage:\n" << argv[0] << " "; + return -1; } - INFO("Using restrictions from file: " << argument_values[2]); - std::ifstream restriction_ifstream(argument_values[2], std::ios::binary); + SimpleLogger().Write() << + "Using restrictions from file: " << argv[2]; + std::ifstream restriction_ifstream(argv[2], std::ios::binary); if(!restriction_ifstream.good()) { - ERR("Could not access files"); + throw OSRMException("Could not access files"); } uint32_t usable_restriction_count = 0; restriction_ifstream.read( @@ -65,18 +70,15 @@ int main (int argument_count, char *argument_values[]) { restriction_ifstream.read( (char *)&(restrictions_vector[0]), - usable_restriction_count*sizeof(_Restriction) + usable_restriction_count*sizeof(TurnRestriction) ); restriction_ifstream.close(); std::ifstream input_stream; - input_stream.open( - argument_values[1], - std::ifstream::in | std::ifstream::binary - ); + input_stream.open( argv[1], std::ifstream::in | std::ifstream::binary ); if (!input_stream.is_open()) { - ERR("Cannot open " << argument_values[1]); + throw OSRMException("Cannot open osrm file"); } std::vector edge_list; @@ -90,17 +92,16 @@ int main (int argument_count, char *argument_values[]) { ); input_stream.close(); - INFO( + SimpleLogger().Write() << restrictions_vector.size() << " restrictions, " << 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 */ - INFO("Starting SCC graph traversal"); + SimpleLogger().Write() << "Starting SCC graph traversal"; TarjanSCC * tarjan = new TarjanSCC ( node_based_node_count, edge_list, @@ -113,9 +114,9 @@ int main (int argument_count, char *argument_values[]) { tarjan->Run(); - std::vector<_Restriction>().swap(restrictions_vector); + std::vector().swap(restrictions_vector); std::vector().swap(bollard_node_IDs_vector); std::vector().swap(traffic_light_node_IDs_vector); - INFO("finished component analysis"); + SimpleLogger().Write() << "finished component analysis"; return 0; } diff --git a/Tools/simpleclient.cpp b/Tools/simpleclient.cpp index 32dc07a76..a4588a5db 100644 --- a/Tools/simpleclient.cpp +++ b/Tools/simpleclient.cpp @@ -20,6 +20,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../Library/OSRM.h" +#include "../Util/SimpleLogger.h" #include #include @@ -44,43 +45,49 @@ void print_tree(boost::property_tree::ptree const& pt, const unsigned recursion_ int main (int argc, char * argv[]) { - std::cout << "\n starting up engines, compile at " - << __DATE__ << ", " __TIME__ << std::endl; - BaseConfiguration serverConfig((argc > 1 ? argv[1] : "server.ini")); - OSRM routing_machine((argc > 1 ? argv[1] : "server.ini")); + LogPolicy::GetInstance().Unmute(); + try { + std::cout << "\n starting up engines, compile at " + << __DATE__ << ", " __TIME__ << std::endl; + IniFile serverConfig((argc > 1 ? argv[1] : "server.ini")); + OSRM routing_machine((argc > 1 ? argv[1] : "server.ini")); - RouteParameters route_parameters; - route_parameters.zoomLevel = 18; //no generalization - route_parameters.printInstructions = true; //turn by turn instructions - route_parameters.alternateRoute = true; //get an alternate route, too - route_parameters.geometry = true; //retrieve geometry of route - route_parameters.compression = true; //polyline encoding - route_parameters.checkSum = UINT_MAX; //see wiki - route_parameters.service = "viaroute"; //that's routing - route_parameters.outputFormat = "json"; - route_parameters.jsonpParameter = ""; //set for jsonp wrapping - route_parameters.language = ""; //unused atm - //route_parameters.hints.push_back(); // see wiki, saves I/O if done properly + RouteParameters route_parameters; + route_parameters.zoomLevel = 18; //no generalization + route_parameters.printInstructions = true; //turn by turn instructions + route_parameters.alternateRoute = true; //get an alternate route, too + route_parameters.geometry = true; //retrieve geometry of route + route_parameters.compression = true; //polyline encoding + route_parameters.checkSum = UINT_MAX; //see wiki + route_parameters.service = "viaroute"; //that's routing + route_parameters.outputFormat = "json"; + route_parameters.jsonpParameter = ""; //set for jsonp wrapping + route_parameters.language = ""; //unused atm + //route_parameters.hints.push_back(); // see wiki, saves I/O if done properly - _Coordinate start_coordinate(52.519930*100000,13.438640*100000); - _Coordinate target_coordinate(52.513191*100000,13.415852*100000); - route_parameters.coordinates.push_back(start_coordinate); - route_parameters.coordinates.push_back(target_coordinate); + FixedPointCoordinate start_coordinate(52.519930*COORDINATE_PRECISION,13.438640*COORDINATE_PRECISION); + FixedPointCoordinate target_coordinate(52.513191*COORDINATE_PRECISION,13.415852*COORDINATE_PRECISION); + route_parameters.coordinates.push_back(start_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; - ss << osrm_reply.content; + std::stringstream ss; + ss << osrm_reply.content; - boost::property_tree::ptree pt; - boost::property_tree::read_json(ss, pt); + boost::property_tree::ptree 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; } diff --git a/Util/GraphLoader.h b/Util/GraphLoader.h index cd3e0cf7d..7a674da01 100644 --- a/Util/GraphLoader.h +++ b/Util/GraphLoader.h @@ -21,14 +21,18 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef GRAPHLOADER_H #define GRAPHLOADER_H +#include "OSRMException.h" #include "../DataStructures/ImportNode.h" #include "../DataStructures/ImportEdge.h" -#include "../DataStructures/NodeCoords.h" +#include "../DataStructures/QueryNode.h" #include "../DataStructures/Restriction.h" +#include "../Util/SimpleLogger.h" #include "../Util/UUID.h" #include "../typedefs.h" #include +#include +#include #include #include @@ -56,17 +60,16 @@ NodeID readBinaryOSRMGraphFromStream( std::vector &bollardNodes, std::vector &trafficLightNodes, std::vector * int2ExtNodeMap, - std::vector<_Restriction> & inputRestrictions + std::vector & inputRestrictions ) { const UUID uuid_orig; UUID uuid_loaded; in.read((char *) &uuid_loaded, sizeof(UUID)); if( !uuid_loaded.TestGraphUtil(uuid_orig) ) { - WARN( + SimpleLogger().Write(logWARNING) << ".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; @@ -74,16 +77,18 @@ NodeID readBinaryOSRMGraphFromStream( short dir;// direction (0 = open, 1 = forward, 2+ = open) ExternalNodeMap ext2IntNodeMap; in.read((char*)&n, sizeof(NodeID)); - INFO("Importing n = " << n << " nodes "); + SimpleLogger().Write() << "Importing n = " << n << " nodes "; _Node node; for (NodeID i=0; ipush_back(NodeInfo(node.lat, node.lon, node.id)); ext2IntNodeMap.insert(std::make_pair(node.id, i)); - if(node.bollard) + if(node.bollard) { bollardNodes.push_back(i); - if(node.trafficLight) + } + if(node.trafficLight) { trafficLightNodes.push_back(i); + } } //tighten vector sizes @@ -91,11 +96,11 @@ NodeID readBinaryOSRMGraphFromStream( std::vector(trafficLightNodes).swap(trafficLightNodes); in.read((char*)&m, sizeof(unsigned)); - INFO(" and " << m << " edges "); + SimpleLogger().Write() << " and " << m << " edges "; for(unsigned i = 0; i < inputRestrictions.size(); ++i) { ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode); if( intNodeID == ext2IntNodeMap.end()) { - DEBUG("Unmapped from Node of restriction"); + SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction"; continue; } @@ -103,14 +108,14 @@ NodeID readBinaryOSRMGraphFromStream( intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode); if( intNodeID == ext2IntNodeMap.end()) { - DEBUG("Unmapped via node of restriction"); + SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction"; continue; } inputRestrictions[i].viaNode = intNodeID->second; intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode); if( intNodeID == ext2IntNodeMap.end()) { - DEBUG("Unmapped to node of restriction"); + SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction"; continue; } inputRestrictions[i].toNode = intNodeID->second; @@ -151,7 +156,8 @@ NodeID readBinaryOSRMGraphFromStream( ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source); if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) { #ifndef NDEBUG - WARN(" unresolved source NodeID: " << source ); + SimpleLogger().Write(logWARNING) << + " unresolved source NodeID: " << source; #endif continue; } @@ -159,7 +165,8 @@ NodeID readBinaryOSRMGraphFromStream( intNodeID = ext2IntNodeMap.find(target); if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) { #ifndef NDEBUG - WARN("unresolved target NodeID : " << target ); + SimpleLogger().Write(logWARNING) << + "unresolved target NodeID : " << target; #endif continue; } @@ -210,7 +217,7 @@ NodeID readBinaryOSRMGraphFromStream( typename std::vector::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover()); ext2IntNodeMap.clear(); std::vector(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; } template @@ -220,14 +227,14 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector& edgeList, s int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open) ExternalNodeMap ext2IntNodeMap; in >> n; - DEBUG("Importing n = " << n << " nodes "); + SimpleLogger().Write(logDEBUG) << "Importing n = " << n << " nodes "; for (NodeID i=0; i> id >> ycoord >> xcoord; int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id)); ext2IntNodeMap.insert(std::make_pair(id, i)); } in >> m; - DEBUG(" and " << m << " edges"); + SimpleLogger().Write(logDEBUG) << " and " << m << " edges"; edgeList.reserve(m); for (EdgeID i=0; i& edgeList, s } assert(length > 0); assert(weight > 0); - if(dir <0 || dir > 2) - WARN("direction bogus: " << dir); + if(dir <0 || dir > 2) { + SimpleLogger().Write(logWARNING) << "direction bogus: " << dir; + } assert(0<=dir && dir<=2); bool forward = true; @@ -308,19 +316,25 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector& edgeList, s 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 ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source); 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; 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; - 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 ); edgeList.push_back(inputEdge); @@ -342,17 +356,19 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector& edgeList, s in >> d; in >> n; in >> m; -#ifndef DEBUG - std::cout << "expecting " << n << " nodes and " << m << " edges ..." << flush; -#endif + + SimpleLogger().Write(logDEBUG) << + "expecting " << n << " nodes and " << m << " edges ..."; + edgeList.reserve(m); for (EdgeID i=0; i> source >> target >> weight >> dir; assert(weight > 0); - if(dir <0 || dir > 3) - ERR( "[error] direction bogus: " << dir ); + if(dir <0 || dir > 3) { + throw OSRMException( "[error] direction bogus"); + } assert(0<=dir && dir<=3); bool forward = true; @@ -361,7 +377,9 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector& edgeList, s if (dir == 2) forward = false; 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()) { nodeMap.insert(std::make_pair(source, numberOfNodes )); @@ -384,41 +402,51 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector& edgeList, s template unsigned readHSGRFromStream( - std::istream &hsgr_input_stream, + const std::string & hsgr_filename, std::vector & node_list, std::vector & edge_list, 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; hsgr_input_stream.read((char *)&uuid_loaded, sizeof(UUID)); if( !uuid_loaded.TestGraphUtil(uuid_orig) ) { - WARN( - ".hsgr was prepared with different build.\n" - "Reprocess to get rid of this warning." - ) + SimpleLogger().Write(logWARNING) << + ".hsgr was prepared with different build. " + "Reprocess to get rid of this warning."; } unsigned number_of_nodes = 0; hsgr_input_stream.read((char*) check_sum, 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); hsgr_input_stream.read( (char*) &(node_list[0]), number_of_nodes*sizeof(NodeT) ); - unsigned number_of_edges = 0; hsgr_input_stream.read( (char*) &number_of_edges, sizeof(unsigned) ); + BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero"); edge_list.resize(number_of_edges); hsgr_input_stream.read( (char*) &(edge_list[0]), number_of_edges*sizeof(EdgeT) ); - + hsgr_input_stream.close(); return number_of_nodes; } diff --git a/Util/BaseConfiguration.h b/Util/IniFile.h similarity index 52% rename from Util/BaseConfiguration.h rename to Util/IniFile.h index a998c6189..582cc273c 100644 --- a/Util/BaseConfiguration.h +++ b/Util/IniFile.h @@ -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. */ -#ifndef BASECONFIGURATION_H_ -#define BASECONFIGURATION_H_ +#ifndef INI_FILE_H_ +#define INI_FILE_H_ +#include "OSRMException.h" #include "../DataStructures/HashTable.h" +#include +#include +#include + #include -#include #include #include -class BaseConfiguration { +class IniFile { public: - BaseConfiguration(const char * configFile) { - std::ifstream config( configFile ); - if(!config) { - std::cerr << "[config] .ini not found" << std::endl; - return; + IniFile(const char * config_filename) { + boost::filesystem::path config_file(config_filename); + if ( !boost::filesystem::exists( config_file ) ) { + std::string error = std::string(config_filename) + " not found"; + 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; - try { - if (config.is_open()) { - while ( config.good() ) { - getline (config,line); - std::vector tokens; - Tokenize(line, tokens); - if(2 == tokens.size() ) - parameters.Add(tokens[0], tokens[1]); + if (config.is_open()) { + while ( config.good() ) { + getline (config,line); + std::vector tokens; + Tokenize(line, tokens); + if(2 == tokens.size() ) { + parameters.insert(std::make_pair(tokens[0], tokens[1])); } - config.close(); } - } catch(std::exception& e) { - ERR("[config] " << configFile << " not found -> Exception: " < parameters; }; -#endif /* BASECONFIGURATION_H_ */ +#endif /* INI_FILE_H_ */ diff --git a/Util/InputFileUtil.h b/Util/InputFileUtil.h index b130d2136..31a98947b 100644 --- a/Util/InputFileUtil.h +++ b/Util/InputFileUtil.h @@ -29,7 +29,9 @@ or see http://www.gnu.org/licenses/agpl.txt. inline bool testDataFile(const std::string & filename){ boost::filesystem::path fileToTest(filename); 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 true; diff --git a/Util/OSRMException.h b/Util/OSRMException.h new file mode 100644 index 000000000..804255a3c --- /dev/null +++ b/Util/OSRMException.h @@ -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 +#include + +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 */ diff --git a/Util/SimpleLogger.h b/Util/SimpleLogger.h new file mode 100644 index 000000000..8bbc6e4fe --- /dev/null +++ b/Util/SimpleLogger.h @@ -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 +#include +#include + +#include +#include + +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_ */ diff --git a/Util/StringUtil.h b/Util/StringUtil.h index 6945575f4..29b125578 100644 --- a/Util/StringUtil.h +++ b/Util/StringUtil.h @@ -23,13 +23,13 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../typedefs.h" -#include #include #include #include #include +#include // precision: position after decimal point // 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); } -// 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_ */ diff --git a/DataStructures/TimingUtil.h b/Util/TimingUtil.h similarity index 67% rename from DataStructures/TimingUtil.h rename to Util/TimingUtil.h index 6e980e26f..cd32f4093 100644 --- a/DataStructures/TimingUtil.h +++ b/Util/TimingUtil.h @@ -21,30 +21,13 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef TIMINGUTIL_H_ #define TIMINGUTIL_H_ -#include -#include +#include - -#ifdef _WIN32 - #include - #include - #include - 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 -#endif +static boost::timer my_timer; /** Returns a timestamp (now) in seconds (incl. a fractional part). */ static inline double get_timestamp() { - struct timeval tp; - gettimeofday(&tp, NULL); - return double(tp.tv_sec) + tp.tv_usec / 1000000.; + return my_timer.elapsed(); } - #endif /* TIMINGUTIL_H_ */ diff --git a/Util/UUID.cpp.in b/Util/UUID.cpp.in index 36726c4ae..9ba29dc15 100644 --- a/Util/UUID.cpp.in +++ b/Util/UUID.cpp.in @@ -55,41 +55,41 @@ const boost::uuids::uuid & UUID::GetUUID() const { return named_uuid; } -const bool UUID::IsMagicNumberOK() const { +bool UUID::IsMagicNumberOK() const { return 1297240911 == magic_number; } -const bool UUID::TestGraphUtil(const UUID & other) const { +bool UUID::TestGraphUtil(const UUID & other) const { 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); } -const bool UUID::TestPrepare(const UUID & other) const { +bool UUID::TestPrepare(const UUID & other) const { 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); } -const bool UUID::TestRTree(const UUID & other) const { +bool UUID::TestRTree(const UUID & other) const { 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); } -const bool UUID::TestNodeInfo(const UUID & other) const { +bool UUID::TestNodeInfo(const UUID & other) const { 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); } -const bool UUID::TestQueryObjects(const UUID & other) const { +bool UUID::TestQueryObjects(const UUID & other) const { 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); } diff --git a/Util/UUID.h b/Util/UUID.h index 188ab26a1..d609d4592 100644 --- a/Util/UUID.h +++ b/Util/UUID.h @@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef UUID_H #define UUID_H +#include "OSRMException.h" #include "../typedefs.h" #include @@ -40,12 +41,12 @@ public: UUID(); ~UUID(); const boost::uuids::uuid & GetUUID() const; - const bool IsMagicNumberOK() const; - const bool TestGraphUtil(const UUID & other) const; - const bool TestPrepare(const UUID & other) const; - const bool TestRTree(const UUID & other) const; - const bool TestNodeInfo(const UUID & other) const; - const bool TestQueryObjects(const UUID & other) const; + bool IsMagicNumberOK() const; + bool TestGraphUtil(const UUID & other) const; + bool TestPrepare(const UUID & other) const; + bool TestRTree(const UUID & other) const; + bool TestNodeInfo(const UUID & other) const; + bool TestQueryObjects(const UUID & other) const; private: const unsigned magic_number; char md5_prepare[33]; @@ -59,4 +60,4 @@ private: bool has_64_bits; }; -#endif /* UUID_H */ \ No newline at end of file +#endif /* UUID_H */ diff --git a/cmake/cmake_options_script.py b/cmake/cmake_options_script.py new file mode 100644 index 000000000..52e943e79 --- /dev/null +++ b/cmake/cmake_options_script.py @@ -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 diff --git a/createHierarchy.cpp b/createHierarchy.cpp index 85cfea942..a3c6ceb20 100644 --- a/createHierarchy.cpp +++ b/createHierarchy.cpp @@ -26,11 +26,13 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "DataStructures/QueryEdge.h" #include "DataStructures/StaticGraph.h" #include "DataStructures/StaticRTree.h" -#include "Util/BaseConfiguration.h" +#include "Util/IniFile.h" #include "Util/GraphLoader.h" #include "Util/InputFileUtil.h" #include "Util/LuaUtil.h" #include "Util/OpenMPWrapper.h" +#include "Util/OSRMException.h" +#include "Util/SimpleLogger.h" #include "Util/StringUtil.h" #include "typedefs.h" @@ -48,18 +50,22 @@ or see http://www.gnu.org/licenses/agpl.txt. typedef QueryEdge::EdgeData EdgeData; typedef DynamicGraph::InputEdge InputEdge; typedef StaticGraph::InputEdge StaticEdge; -typedef BaseConfiguration ContractorConfiguration; +typedef IniFile ContractorConfiguration; std::vector internalToExternalNodeMapping; -std::vector<_Restriction> inputRestrictions; +std::vector inputRestrictions; std::vector bollardNodes; std::vector trafficLightNodes; std::vector edgeList; int main (int argc, char *argv[]) { try { + LogPolicy::GetInstance().Unmute(); if(argc < 3) { - ERR("usage: " << std::endl << argv[0] << " []"); + SimpleLogger().Write(logWARNING) << + "usage: \n" << + argv[0] << " []"; + return -1; } double startupTime = get_timestamp(); @@ -71,32 +77,39 @@ int main (int argc, char *argv[]) { number_of_threads = rawNumber; } omp_set_num_threads(number_of_threads); - - INFO("Using restrictions from file: " << argv[2]); + LogPolicy::GetInstance().Unmute(); + SimpleLogger().Write() << "Using restrictions from file: " << argv[2]; std::ifstream restrictionsInstream(argv[2], std::ios::binary); if(!restrictionsInstream.good()) { - ERR("Could not access files"); + std::cerr << + "Could not access files" << std::endl; + } - _Restriction restriction; + TurnRestriction restriction; UUID uuid_loaded, uuid_orig; unsigned usableRestrictionsCounter(0); restrictionsInstream.read((char*)&uuid_loaded, sizeof(UUID)); if( !uuid_loaded.TestPrepare(uuid_orig) ) { - WARN( - ".restrictions was prepared with different build.\n" - "Reprocess to get rid of this warning." - ) + SimpleLogger().Write(logWARNING) << + ".restrictions was prepared with different build.\n" + "Reprocess to get rid of this warning."; } - restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned)); + restrictionsInstream.read( + (char*)&usableRestrictionsCounter, + sizeof(unsigned) + ); inputRestrictions.resize(usableRestrictionsCounter); - restrictionsInstream.read((char *)&(inputRestrictions[0]), usableRestrictionsCounter*sizeof(_Restriction)); + restrictionsInstream.read( + (char *)&(inputRestrictions[0]), + usableRestrictionsCounter*sizeof(TurnRestriction) + ); restrictionsInstream.close(); std::ifstream in; in.open (argv[1], std::ifstream::in | std::ifstream::binary); if (!in.is_open()) { - ERR("Cannot open " << argv[1]); + throw OSRMException("Cannot open osrm input file"); } std::string nodeOut(argv[1]); nodeOut += ".nodes"; @@ -107,7 +120,7 @@ int main (int argc, char *argv[]) { /*** Setup Scripting Environment ***/ 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 @@ -123,20 +136,34 @@ int main (int argc, char *argv[]) { luaAddScriptFolderToLoadPath( myLuaState, (argc > 3 ? argv[3] : "profile.lua") ); // 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") )) { - ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block"); + std::cerr << + lua_tostring(myLuaState,-1) << + " occured in scripting block" << + std::endl; } EdgeBasedGraphFactory::SpeedProfileProperties speedProfile; 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); 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); @@ -145,20 +172,31 @@ int main (int argc, char *argv[]) { std::vector edgeList; NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions); in.close(); - INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights"); - if(0 == edgeList.size()) - ERR("The input data is broken. It is impossible to do any turns in this graph"); + SimpleLogger().Write() << + inputRestrictions.size() << + " 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 */ - INFO("Generating edge-expanded graph representation"); + SimpleLogger().Write() << "Generating edge-expanded graph representation"; EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile); std::vector().swap(edgeList); edgeBasedGraphFactory->Run(edgeOut.c_str(), myLuaState); - std::vector<_Restriction>().swap(inputRestrictions); + std::vector().swap(inputRestrictions); std::vector().swap(bollardNodes); std::vector().swap(trafficLightNodes); NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes(); @@ -172,7 +210,7 @@ int main (int argc, char *argv[]) { * 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); mapOutFile.write((char *)&(internalToExternalNodeMapping[0]), internalToExternalNodeMapping.size()*sizeof(NodeInfo)); mapOutFile.close(); @@ -184,7 +222,7 @@ int main (int argc, char *argv[]) { * Building grid-like nearest-neighbor data structure */ - INFO("building r-tree ..."); + SimpleLogger().Write() << "building r-tree ..."; StaticRTree * rtree = new StaticRTree( nodeBasedEdgeList, @@ -195,17 +233,21 @@ int main (int argc, char *argv[]) { IteratorbasedCRC32 > crc32; unsigned crc32OfNodeBasedEdgeList = crc32(nodeBasedEdgeList.begin(), nodeBasedEdgeList.end() ); nodeBasedEdgeList.clear(); - INFO("CRC32 based checksum is " << crc32OfNodeBasedEdgeList); + SimpleLogger().Write() << "CRC32: " << crc32OfNodeBasedEdgeList; /*** * Contracting the edge-expanded graph */ - INFO("initializing contractor"); + SimpleLogger().Write() << "initializing contractor"; Contractor* contractor = new Contractor( edgeBasedNodeNumber, edgeBasedEdgeList ); double contractionStartedTimestamp(get_timestamp()); 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; 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. */ - INFO("Building Node Array"); + SimpleLogger().Write() << "Building Node Array"; std::sort(contractedEdgeList.begin(), contractedEdgeList.end()); unsigned numberOfNodes = 0; 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); hsgr_output_stream.write((char*)&uuid_orig, sizeof(UUID) ); BOOST_FOREACH(const QueryEdge & edge, contractedEdgeList) { @@ -261,8 +307,16 @@ int main (int argc, char *argv[]) { currentEdge.target = contractedEdgeList[edge].target; currentEdge.data = contractedEdgeList[edge].data; if(currentEdge.data.distance <= 0) { - INFO("Edge: " << i << ",source: " << contractedEdgeList[edge].source << ", target: " << contractedEdgeList[edge].target << ", dist: " << currentEdge.data.distance); - ERR("Failed at edges of node " << node << " of " << numberOfNodes); + SimpleLogger().Write(logWARNING) << + "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 hsgr_output_stream.write((char*) ¤tEdge, sizeof(StaticGraph::_StrEdge)); @@ -270,16 +324,24 @@ int main (int argc, char *argv[]) { ++usedEdgeCounter; } } - double endTime = (get_timestamp() - startupTime); - INFO("Expansion : " << (nodeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< (edgeBasedNodeNumber/expansionHasFinishedTime) << " edges/sec"); - INFO("Contraction: " << (edgeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< usedEdgeCounter/endTime << " edges/sec"); + SimpleLogger().Write() << "Preprocessing : " << + (get_timestamp() - startupTime) << " seconds"; + 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(); //cleanedEdgeList.clear(); _nodes.clear(); - INFO("finished preprocessing"); - } catch (std::exception &e) { - ERR("Exception occured: " << e.what()); + SimpleLogger().Write() << "finished preprocessing"; + } catch ( const std::exception &e ) { + SimpleLogger().Write(logWARNING) << + "Exception occured: " << e.what() << std::endl; + return -1; } return 0; } diff --git a/extractor.cpp b/extractor.cpp index 5e580d8e7..d39c00ab6 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -23,10 +23,12 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "Extractor/ScriptingEnvironment.h" #include "Extractor/PBFParser.h" #include "Extractor/XMLParser.h" -#include "Util/BaseConfiguration.h" +#include "Util/IniFile.h" #include "Util/InputFileUtil.h" #include "Util/MachineInfo.h" #include "Util/OpenMPWrapper.h" +#include "Util/OSRMException.h" +#include "Util/SimpleLogger.h" #include "Util/StringUtil.h" #include "Util/UUID.h" #include "typedefs.h" @@ -42,18 +44,23 @@ UUID uuid; int main (int argc, char *argv[]) { try { + LogPolicy::GetInstance().Unmute(); double startup_time = get_timestamp(); - if(argc < 2) { - ERR("usage: \n" << argv[0] << " []"); + SimpleLogger().Write(logWARNING) << + "usage: \n" << + argv[0] << + " []"; + return -1; } /*** Setup Scripting Environment ***/ ScriptingEnvironment scriptingEnvironment((argc > 2 ? argv[2] : "profile.lua")); unsigned number_of_threads = omp_get_num_procs(); + if(testDataFile("extractor.ini")) { - BaseConfiguration extractorConfig("extractor.ini"); + IniFile extractorConfig("extractor.ini"); unsigned rawNumber = stringToInt(extractorConfig.GetParameter("Threads")); if( rawNumber != 0 && rawNumber <= number_of_threads) { number_of_threads = rawNumber; @@ -61,7 +68,7 @@ int main (int argc, char *argv[]) { } 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); std::string output_file_name(argv[1]); std::string restrictionsFileName(argv[1]); @@ -95,7 +102,7 @@ int main (int argc, char *argv[]) { unsigned amountOfRAM = 1; unsigned installedRAM = GetPhysicalmemory(); if(installedRAM < 2048264) { - WARN("Machine has less than 2GB RAM."); + SimpleLogger().Write(logWARNING) << "Machine has less than 2GB RAM."; } StringMap stringMap; @@ -111,28 +118,32 @@ int main (int argc, char *argv[]) { } 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(); parser->Parse(); - INFO("Parsing finished after " << + SimpleLogger().Write() << "Parsing finished after " << (get_timestamp() - parsing_start_time) << - " seconds" - ); + " seconds"; externalMemory.PrepareData(output_file_name, restrictionsFileName, amountOfRAM); delete parser; 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" - << "./osrm-prepare " << output_file_name << " " << restrictionsFileName - << std::endl; - return 0; + SimpleLogger().Write() << "\nRun:\n./osrm-prepare " << + output_file_name << + " " << + restrictionsFileName << + std::endl; } catch(std::exception & e) { - WARN("unhandled exception: " << e.what()); + SimpleLogger().Write(logWARNING) << "unhandled exception: " << e.what(); + return -1; } + return 0; } diff --git a/features/bicycle/maxspeed.feature b/features/bicycle/maxspeed.feature index 9924f5596..fa741685d 100644 --- a/features/bicycle/maxspeed.feature +++ b/features/bicycle/maxspeed.feature @@ -15,7 +15,7 @@ Feature: Bike - Max speed restrictions | highway | maxspeed | bothw | | residential | | 49s ~10% | | residential | 80 | 49s ~10% | - + @todo Scenario: Bicycle - Maxspeed formats Then routability should be @@ -68,3 +68,20 @@ Feature: Bike - Max speed restrictions | 1 | 10 | | run | snail | | 1 | | 10 | snail | 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 | | diff --git a/features/car/maxspeed.feature b/features/car/maxspeed.feature index 3e09a0ad3..42bac96ce 100644 --- a/features/car/maxspeed.feature +++ b/features/car/maxspeed.feature @@ -52,3 +52,20 @@ Feature: Car - Max speed restrictions | 1 | 10 | | run | snail | | 1 | | 10 | snail | 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 | | \ No newline at end of file diff --git a/features/investigate/weird.feature b/features/investigate/weird.feature index f84a07592..33c2d6108 100644 --- a/features/investigate/weird.feature +++ b/features/investigate/weird.feature @@ -1,9 +1,9 @@ -@routing @weird +@routing @weird @todo Feature: Weird routings discovered - + Background: Given the profile "testbot" - + Scenario: Routing on a oneway roundabout Given the node map | | d | c | | @@ -39,4 +39,41 @@ Feature: Weird routings discovered | 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 | \ No newline at end of file + | 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 | diff --git a/features/support/env.rb b/features/support/env.rb index 13a0b0c5e..a6a99b9f5 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -4,7 +4,7 @@ DEFAULT_PORT = 5000 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" end diff --git a/features/support/hash.rb b/features/support/hash.rb index e37a6f2df..7639364fb 100644 --- a/features/support/hash.rb +++ b/features/support/hash.rb @@ -1,5 +1,8 @@ require 'digest/sha1' +bin_extract_hash = nil +profile_hashes = nil + def hash_of_files paths paths = [paths] unless paths.is_a? Array hash = Digest::SHA1.new @@ -16,8 +19,8 @@ end def profile_hash - @@profile_hashes ||= {} - @@profile_hashes[@profile] ||= hash_of_files "#{PROFILES_PATH}/#{@profile}.lua" + profile_hashes ||= {} + profile_hashes[@profile] ||= hash_of_files "#{PROFILES_PATH}/#{@profile}.lua" end def osm_hash @@ -29,15 +32,15 @@ def lua_lib_hash end 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 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 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 #combine state of data, profile and binaries into a hash that identifies the exact test scenario diff --git a/features/support/osm_parser.rb b/features/support/osm_parser.rb index ea4e9bd16..3331a70bc 100644 --- a/features/support/osm_parser.rb +++ b/features/support/osm_parser.rb @@ -1,23 +1,25 @@ require 'OSM/StreamParser' +locations = nil + class OSMTestParserCallbacks < OSM::Callbacks - @@locations = nil + locations = nil def self.locations - if @@locations - @@locations + if locations + locations else #parse the test file, so we can later reference nodes and ways by name in tests - @@locations = {} + locations = {} file = 'test/data/test.osm' callbacks = OSMTestParserCallbacks.new parser = OSM::StreamParser.new(:filename => file, :callbacks => callbacks) parser.parse - puts @@locations + puts locations end end def node(node) - @@locations[node.name] = [node.lat,node.lon] + locations[node.name] = [node.lat,node.lon] end end \ No newline at end of file diff --git a/features/testbot/basic.feature b/features/testbot/basic.feature index aabdcaa00..9ab579f0f 100644 --- a/features/testbot/basic.feature +++ b/features/testbot/basic.feature @@ -1,27 +1,27 @@ @routing @basic Feature: Basic Routing - + Background: Given the profile "testbot" - + @smallest Scenario: A single way with two nodes Given the node map | a | b | - + And the ways | nodes | | ab | - + When I route I should get | from | to | route | | a | b | ab | | b | a | ab | - + Scenario: Routing in between two nodes of way Given the node map | a | b | 1 | 2 | c | d | - + And the ways | nodes | | abcd | @@ -57,12 +57,12 @@ Feature: Basic Routing Scenario: Two ways connected in a straight line Given the node map | a | b | c | - + And the ways | nodes | | ab | | bc | - + When I route I should get | from | to | route | | a | c | ab,bc | @@ -71,17 +71,17 @@ Feature: Basic Routing | b | a | ab | | b | c | bc | | c | b | bc | - + Scenario: 2 unconnected parallel ways Given the node map | a | b | c | | d | e | f | - + And the ways | nodes | | abc | | def | - + When I route I should get | from | to | route | | a | b | abc | @@ -122,7 +122,7 @@ Feature: Basic Routing | ab | | bc | | ca | - + When I route I should get | from | to | route | | a | b | ab | @@ -154,7 +154,7 @@ Feature: Basic Routing | cv | | vw | | wc | - + When I route I should get | from | to | route | | a | b | ab | @@ -183,7 +183,7 @@ Feature: Basic Routing | c | a | abc | | c | e | cde | | e | c | cde | - + Scenario: Grid city center Given the node map | a | b | c | d | @@ -233,40 +233,3 @@ Feature: Basic Routing | d | a | abcd | | a | m | 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 | diff --git a/features/testbot/duration.feature b/features/testbot/duration.feature index ab6571ce5..e653ae9cf 100644 --- a/features/testbot/duration.feature +++ b/features/testbot/duration.feature @@ -3,13 +3,13 @@ Feature: Durations Background: Given the profile "testbot" - + Scenario: Duration of ways Given the node map | a | b | | | | f | | | | | e | | | | | c | | | d | | - + And the ways | nodes | highway | duration | | ab | primary | 0:01 | @@ -23,9 +23,9 @@ Feature: Durations | a | b | ab | 100m +-1 | 60s +-1 | | b | c | bc | 200m +-1 | 600s +-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 | - + @todo Scenario: Partial duration of ways Given the node map diff --git a/features/testbot/opposite.feature b/features/testbot/opposite.feature index c242c97b1..ee34b786f 100644 --- a/features/testbot/opposite.feature +++ b/features/testbot/opposite.feature @@ -1,18 +1,18 @@ @routing @testbot @opposite Feature: Separate settings for forward/backward direction - + Background: Given the profile "testbot" - + Scenario: Testbot - Going against the flow Given the node map | a | b | c | d | - + And the ways | nodes | highway | | abcd | river | - + When I route I should get | from | to | route | distance | time | - | a | d | abcd | 300 +- 1m | 30s | + | a | d | abcd | 300 +- 1m | 31s | | d | a | abcd | 300 +- 1m | 68s | \ No newline at end of file diff --git a/profiles/bicycle.lua b/profiles/bicycle.lua index 063ad50bc..5fd680239 100644 --- a/profiles/bicycle.lua +++ b/profiles/bicycle.lua @@ -14,7 +14,7 @@ default_speed = 15 walking_speed = 6 -bicycle_speeds = { +bicycle_speeds = { ["cycleway"] = default_speed, ["primary"] = default_speed, ["primary_link"] = default_speed, @@ -33,13 +33,13 @@ bicycle_speeds = { --["pedestrian"] = 12, } -pedestrian_speeds = { +pedestrian_speeds = { ["footway"] = walking_speed, ["pedestrian"] = walking_speed, ["steps"] = 2 } -railway_speeds = { +railway_speeds = { ["train"] = 10, ["railway"] = 10, ["subway"] = 10, @@ -48,24 +48,24 @@ railway_speeds = { ["tram"] = 10 } -platform_speeds = { +platform_speeds = { ["platform"] = walking_speed } -amenity_speeds = { +amenity_speeds = { ["parking"] = 10, ["parking_entrance"] = 10 } -man_made_speeds = { +man_made_speeds = { ["pier"] = walking_speed } -route_speeds = { +route_speeds = { ["ferry"] = 5 } -surface_speeds = { +surface_speeds = { ["cobblestone:flattened"] = 10, ["paving_stones"] = 10, ["compacted"] = 10, @@ -80,7 +80,7 @@ surface_speeds = { ["earth"] = 6, ["grass"] = 6, ["mud"] = 3, - ["sand"] = 3 + ["sand"] = 3 } take_minimum_of_speeds = true @@ -96,7 +96,7 @@ turn_bias = 1.4 -- End of globals 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) end end @@ -105,12 +105,12 @@ function node_function (node) local barrier = node.tags:Find ("barrier") local access = Access.find_access_tag(node, access_tags_hierachy) 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 node.traffic_light = true end - + -- parse access and barrier tags if access and access ~= "" then if access_tag_blacklist[access] then @@ -125,7 +125,7 @@ function node_function (node) node.bollard = true end end - + return 1 end @@ -137,21 +137,21 @@ function way_function (way) local railway = way.tags:Find("railway") local amenity = way.tags:Find("amenity") local public_transport = way.tags:Find("public_transport") - if (not highway or highway == '') and - (not route or route == '') and - (not railway or railway=='') and + if (not highway or highway == '') and + (not route or route == '') and + (not railway or railway=='') and (not amenity or amenity=='') and (not man_made or man_made=='') and (not public_transport or public_transport=='') then return 0 end - + -- don't route on ways or railways that are still under construction if highway=='construction' or railway=='construction' then return 0 end - + -- access local access = Access.find_access_tag(way, access_tags_hierachy) if access_tag_blacklist[access] then @@ -178,7 +178,7 @@ function way_function (way) local foot = way.tags:Find("foot") local surface = way.tags:Find("surface") - -- name + -- name if "" ~= ref and "" ~= name then way.name = name .. ' / ' .. ref elseif "" ~= ref then @@ -214,7 +214,7 @@ function way_function (way) elseif railway and railway_speeds[railway] then -- railways if access and access_tag_whitelist[access] then - way.speed = railway_speeds[railway] + way.speed = railway_speeds[railway] way.direction = Way.bidirectional end elseif amenity and amenity_speeds[amenity] then @@ -242,7 +242,7 @@ function way_function (way) end end end - + -- direction way.direction = Way.bidirectional local impliedOneway = false @@ -250,7 +250,7 @@ function way_function (way) way.direction = Way.oneway impliedOneway = true end - + if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then way.direction = Way.oneway 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 way.direction = Way.oneway end - + -- pushing bikes if bicycle_speeds[highway] or pedestrian_speeds[highway] then if foot ~= 'no' then @@ -303,7 +303,7 @@ function way_function (way) end end - + -- cycleways if cycleway and cycleway_tags[cycleway] then way.speed = bicycle_speeds["cycleway"] @@ -312,7 +312,7 @@ function way_function (way) elseif cycleway_right and cycleway_tags[cycleway_right] then way.speed = bicycle_speeds["cycleway"] end - + -- surfaces if surface then surface_speed = surface_speeds[surface] @@ -331,7 +331,7 @@ function way_function (way) end -- 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 way.backward_speed = way.speed end @@ -342,7 +342,7 @@ function way_function (way) end - + way.type = 1 return 1 end diff --git a/profiles/car.lua b/profiles/car.lua index da6e6cedc..9ecbc81c2 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -197,7 +197,7 @@ function way_function (way) end -- 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 way.backward_speed = way.speed end @@ -211,7 +211,6 @@ function way_function (way) if ignore_in_grid[highway] ~= nil and ignore_in_grid[highway] then way.ignore_in_grid = true end - way.type = 1 return 1 end diff --git a/routed.cpp b/routed.cpp index 1f4e43550..b4b6b0c0e 100644 --- a/routed.cpp +++ b/routed.cpp @@ -23,9 +23,10 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "Server/ServerFactory.h" -#include "Util/BaseConfiguration.h" +#include "Util/IniFile.h" #include "Util/InputFileUtil.h" #include "Util/OpenMPWrapper.h" +#include "Util/SimpleLogger.h" #include "Util/UUID.h" #ifdef __linux__ @@ -61,9 +62,12 @@ BOOL WINAPI console_ctrl_handler(DWORD ctrl_type) #endif int main (int argc, char * argv[]) { + try { + LogPolicy::GetInstance().Unmute(); #ifdef __linux__ - if(!mlockall(MCL_CURRENT | MCL_FUTURE)) - WARN("Process " << argv[0] << "could not be locked to RAM"); + if(!mlockall(MCL_CURRENT | MCL_FUTURE)) { + SimpleLogger().Write(logWARNING) << "Process " << argv[0] << "could not be locked to RAM"; + } #endif #ifdef __linux__ @@ -77,11 +81,10 @@ int main (int argc, char * argv[]) { //exit(-1); //} - try { //std::cout << "fingerprint: " << UUID::GetInstance().GetUUID() << std::endl; - std::cout << "starting up engines, compiled at " << - __DATE__ << ", " __TIME__ << std::endl; + SimpleLogger().Write() << + "starting up engines, compiled at " << __DATE__ << ", " __TIME__; #ifndef _WIN32 int sig = 0; @@ -91,7 +94,7 @@ int main (int argc, char * argv[]) { pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); #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")); Server * s = ServerFactory::CreateServer(serverConfig); @@ -122,7 +125,7 @@ int main (int argc, char * argv[]) { std::cout << "[server] stopping threads" << std::endl; 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; diff --git a/typedefs.h b/typedefs.h index 180e47ca0..2592f422b 100644 --- a/typedefs.h +++ b/typedefs.h @@ -33,30 +33,20 @@ or see http://www.gnu.org/licenses/agpl.txt. #endif #include +#include -#define INFO(x) do {std::cout << "[i " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0); -#define ERR(x) do {std::cerr << "[! " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl; std::exit(-1);} while(0); -#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 - +// Necessary workaround for Windows as VS doesn't implement C99 +#ifdef _MSC_VER #ifndef M_PI #define M_PI 3.14159265358979323846 #endif -// Necessary workaround for Windows as VS doesn't implement C99 -#ifdef _MSC_VER template digitT round(digitT x) { return std::floor(x + 0.5); } #endif - typedef unsigned int NodeID; typedef unsigned int EdgeID; typedef unsigned int EdgeWeight;