diff --git a/Algorithms/StronglyConnectedComponents.h b/Algorithms/StronglyConnectedComponents.h index f9790568b..148e35613 100644 --- a/Algorithms/StronglyConnectedComponents.h +++ b/Algorithms/StronglyConnectedComponents.h @@ -41,7 +41,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../DataStructures/NodeCoords.h" #include "../DataStructures/Percent.h" #include "../DataStructures/Restriction.h" - +#include "../DataStructures/TurnInstructions.h" // Strongly connected components using Tarjan's Algorithm @@ -66,7 +66,7 @@ private: unsigned nameID; bool forward; bool backward; - short turnInstruction; + TurnInstruction turnInstruction; }; typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; diff --git a/Contractor/ContractionCleanup.h b/Contractor/ContractionCleanup.h index c1f08b081..e42dad3a7 100644 --- a/Contractor/ContractionCleanup.h +++ b/Contractor/ContractionCleanup.h @@ -60,7 +60,7 @@ public: NodeID via; unsigned nameID; int distance; - short turnInstruction; + TurnInstruction turnInstruction; bool shortcut:1; bool forward:1; bool backward:1; diff --git a/Contractor/Contractor.h b/Contractor/Contractor.h index 04b4a4097..aad4123ac 100644 --- a/Contractor/Contractor.h +++ b/Contractor/Contractor.h @@ -122,8 +122,7 @@ public: assert( newEdge.data.distance > 0 ); #ifndef NDEBUG if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) { - std::cout << "Edge Weight too large -> May lead to invalid CH" << std::endl; - continue; + WARN("Edge weight large -> " << newEdge.data.distance); } #endif edges.push_back( newEdge ); diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index 82ab09f11..994c4cc07 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -95,8 +95,6 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector& outputEdgeList ) { GUARANTEE(0 == outputEdgeList.size(), "Vector passed to EdgeBasedGraphFactory::GetEdgeBasedEdges(..) is not empty"); - GUARANTEE(0 != edgeBasedEdges.size(), "No edges in edge based graph"); - edgeBasedEdges.swap(outputEdgeList); } @@ -280,7 +278,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) { if(_trafficLights.find(v) != _trafficLights.end()) { distance += speedProfile.trafficSignalPenalty; } - short turnInstruction = AnalyzeTurn(u, v, w); + TurnInstruction turnInstruction = AnalyzeTurn(u, v, w); if(turnInstruction == TurnInstructions.UTurn) distance += speedProfile.uTurnPenalty; // if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) { @@ -297,7 +295,6 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) { } OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction); EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false ); - assert(u != w); originalEdgeData.push_back(oed); if(originalEdgeData.size() > 100000) { originalEdgeDataOutFile.write((char*)&(originalEdgeData[0]), originalEdgeData.size()*sizeof(OriginalEdgeData)); @@ -334,7 +331,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) { INFO("Generated " << edgeBasedNodes.size() << " edge based nodes"); } -short EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const { +TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const { if(u == w) { return TurnInstructions.UTurn; } diff --git a/Contractor/EdgeBasedGraphFactory.h b/Contractor/EdgeBasedGraphFactory.h index 0fa0bb252..62a119e81 100644 --- a/Contractor/EdgeBasedGraphFactory.h +++ b/Contractor/EdgeBasedGraphFactory.h @@ -69,7 +69,7 @@ private: unsigned nameID; bool forward; bool backward; - short turnInstruction; + TurnInstruction turnInstruction; }; typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; @@ -138,7 +138,7 @@ public: void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges ); void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes); void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData); - short AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const; + TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const; unsigned GetNumberOfNodes() const; }; diff --git a/DataStructures/Coordinate.h b/DataStructures/Coordinate.h index 748faff70..c1d9c4167 100644 --- a/DataStructures/Coordinate.h +++ b/DataStructures/Coordinate.h @@ -57,23 +57,7 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat assert(lon1 != INT_MIN); assert(lat2 != INT_MIN); assert(lon2 != INT_MIN); -// static const double DEG_TO_RAD = 0.017453292519943295769236907684886; -// //Earth's quatratic mean radius for WGS-84 -// static const double EARTH_RADIUS_IN_METERS = 6372797.560856; -// double latitudeArc = ( lat1/100000. - lat2/100000. ) * DEG_TO_RAD; -// double longitudeArc = ( lon1/100000. - lon2/100000. ) * DEG_TO_RAD; -// double latitudeH = sin( latitudeArc * 0.5 ); -// latitudeH *= latitudeH; -// double lontitudeH = sin( longitudeArc * 0.5 ); -// lontitudeH *= lontitudeH; -// double tmp = cos( lat1/100000. * DEG_TO_RAD ) * cos( lat2/100000. * DEG_TO_RAD ); -// double distanceArc = 2.0 * asin( sqrt( latitudeH + tmp * lontitudeH ) ); -// return EARTH_RADIUS_IN_METERS * distanceArc; - - //double PI = 3.14159265358979323846;//4.0*atan(1.0); double RAD = 0.017453292519943295769236907684886; - //std::cout << "RAD: " << RAD << std::endl; - //main code inside the class double lt1 = lat1/100000.; double ln1 = lon1/100000.; double lt2 = lat2/100000.; @@ -94,12 +78,29 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat const double earth=6372797.560856;//I am doing miles, just change this to radius in kilometers to get distances in km double distance=earth*cHarv; return distance; - - } inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) { return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon ); } +inline double ApproximateDistanceByEuclid(const _Coordinate &c1, const _Coordinate &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 x = (lon2-lon1) * cos((lat1+lat2)/2.); + const double y = (lat2-lat1); + const double earthRadius = 6372797.560856; + const double d = sqrt(x*x + y*y) * earthRadius; + return d; +} + + #endif /* COORDINATE_H_ */ diff --git a/DataStructures/NodeInformationHelpDesk.h b/DataStructures/NodeInformationHelpDesk.h index cddfede98..abf05b71a 100644 --- a/DataStructures/NodeInformationHelpDesk.h +++ b/DataStructures/NodeInformationHelpDesk.h @@ -85,7 +85,7 @@ public: return origEdgeData.at(id).nameID; } - inline short getTurnInstructionFromEdgeID(const unsigned id) const { + inline TurnInstruction getTurnInstructionFromEdgeID(const unsigned id) const { return origEdgeData.at(id).turnInstruction; } diff --git a/DataStructures/QueryEdge.h b/DataStructures/QueryEdge.h index aab61f9c7..72cbf0f07 100644 --- a/DataStructures/QueryEdge.h +++ b/DataStructures/QueryEdge.h @@ -23,16 +23,17 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef QUERYEDGE_H_ #define QUERYEDGE_H_ -#include - +#include "TurnInstructions.h" #include "../typedefs.h" +#include + struct OriginalEdgeData{ - explicit OriginalEdgeData(NodeID v, unsigned n, short t) : viaNode(v), nameID(n), turnInstruction(t) {} - OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(SHRT_MAX) {} + explicit OriginalEdgeData(NodeID v, unsigned n, TurnInstruction t) : viaNode(v), nameID(n), turnInstruction(t) {} + OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {} NodeID viaNode; unsigned nameID; - short turnInstruction; + TurnInstruction turnInstruction; }; struct QueryEdge { diff --git a/DataStructures/SegmentInformation.h b/DataStructures/SegmentInformation.h index 943fd831a..cbe4b81cc 100644 --- a/DataStructures/SegmentInformation.h +++ b/DataStructures/SegmentInformation.h @@ -23,17 +23,19 @@ or see http://www.gnu.org/licenses/agpl.txt. #include +#include "TurnInstructions.h" + struct SegmentInformation { _Coordinate location; NodeID nameID; double length; unsigned duration; double bearing; - short turnInstruction; + TurnInstruction turnInstruction; bool necessary; - SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const short tInstr, const bool nec) : + SegmentInformation(const _Coordinate & 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 short tInstr) : + SegmentInformation(const _Coordinate & 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/TurnInstructions.h b/DataStructures/TurnInstructions.h index 624a8db4c..2e709831d 100644 --- a/DataStructures/TurnInstructions.h +++ b/DataStructures/TurnInstructions.h @@ -23,30 +23,32 @@ #include +typedef unsigned char TurnInstruction; + //This is a hack until c++0x is available enough to use scoped enums struct TurnInstructionsClass { - const static short NoTurn = 0; //Give no instruction at all - const static short GoStraight = 1; //Tell user to go straight! - const static short TurnSlightRight = 2; - const static short TurnRight = 3; - const static short TurnSharpRight = 4; - const static short UTurn = 5; - const static short TurnSharpLeft = 6; - const static short TurnLeft = 7; - const static short TurnSlightLeft = 8; - const static short ReachViaPoint = 9; - const static short HeadOn = 10; - const static short EnterRoundAbout = 11; - const static short LeaveRoundAbout = 12; - const static short StayOnRoundAbout = 13; - const static short StartAtEndOfStreet = 14; - const static short ReachedYourDestination = 15; + const static TurnInstruction NoTurn = 0; //Give no instruction at all + const static TurnInstruction GoStraight = 1; //Tell user to go straight! + const static TurnInstruction TurnSlightRight = 2; + const static TurnInstruction TurnRight = 3; + const static TurnInstruction TurnSharpRight = 4; + const static TurnInstruction UTurn = 5; + const static TurnInstruction TurnSharpLeft = 6; + const static TurnInstruction TurnLeft = 7; + const static TurnInstruction TurnSlightLeft = 8; + const static TurnInstruction ReachViaPoint = 9; + const static TurnInstruction HeadOn = 10; + const static TurnInstruction EnterRoundAbout = 11; + const static TurnInstruction LeaveRoundAbout = 12; + const static TurnInstruction StayOnRoundAbout = 13; + const static TurnInstruction StartAtEndOfStreet = 14; + const static TurnInstruction ReachedYourDestination = 15; - const static short AccessRestrictionFlag = (1<<14); - const static short InverseAccessRestrictionFlag = ~(1<<14); + const static TurnInstruction AccessRestrictionFlag = 128; + const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning. - const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag + const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag // std::string TurnStrings[16]; // std::string Ordinals[12]; @@ -84,7 +86,7 @@ struct TurnInstructionsClass { // Ordinals[11] = "one of the too many"; // }; - static inline double GetTurnDirectionOfInstruction( const double angle ) { + static inline TurnInstruction GetTurnDirectionOfInstruction( const double angle ) { if(angle >= 23 && angle < 67) { return TurnSharpRight; } diff --git a/Descriptors/DescriptionFactory.cpp b/Descriptors/DescriptionFactory.cpp index 2db1706a7..46a1d5b82 100644 --- a/Descriptors/DescriptionFactory.cpp +++ b/Descriptors/DescriptionFactory.cpp @@ -91,7 +91,7 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe /** starts at index 1 */ pathDescription[0].length = 0; for(unsigned i = 1; i < pathDescription.size(); ++i) { - pathDescription[i].length = ApproximateDistance(pathDescription[i-1].location, pathDescription[i].location); + pathDescription[i].length = ApproximateDistanceByEuclid(pathDescription[i-1].location, pathDescription[i].location); } double lengthOfSegment = 0; @@ -111,32 +111,37 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe becomes: 10. Turn left on B 36 for 35 km */ - unsigned lastTurn = 0; - for(unsigned i = 1; i < pathDescription.size(); ++i) { - string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].nameID); - if(TurnInstructionsClass::GoStraight == pathDescription[i].turnInstruction) { - if(std::string::npos != string0.find(string1+";") || - std::string::npos != string0.find(";"+string1) || - std::string::npos != string0.find(string1+" ;") || - std::string::npos != string0.find("; "+string1)){ +//TODO: rework to check only end and start of string. +// stl string is way to expensive + +// unsigned lastTurn = 0; +// for(unsigned i = 1; i < pathDescription.size(); ++i) { +// string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].nameID); +// if(TurnInstructionsClass::GoStraight == pathDescription[i].turnInstruction) { +// if(std::string::npos != string0.find(string1+";") +// || std::string::npos != string0.find(";"+string1) +// || std::string::npos != string0.find(string1+" ;") +// || std::string::npos != string0.find("; "+string1) +// ){ // INFO("->next correct: " << string0 << " contains " << string1); - for(; lastTurn != i; ++lastTurn) - pathDescription[lastTurn].nameID = pathDescription[i].nameID; - pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; - } else if(std::string::npos != string1.find(string0+";") || - std::string::npos != string1.find(";"+string0) || - std::string::npos != string1.find(string0+" ;")|| - std::string::npos != string1.find("; "+string0)) { +// for(; lastTurn != i; ++lastTurn) +// pathDescription[lastTurn].nameID = pathDescription[i].nameID; +// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; +// } else if(std::string::npos != string1.find(string0+";") +// || std::string::npos != string1.find(";"+string0) +// || std::string::npos != string1.find(string0+" ;") +// || std::string::npos != string1.find("; "+string0) +// ){ // INFO("->prev correct: " << string1 << " contains " << string0); - pathDescription[i].nameID = pathDescription[i-1].nameID; - pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; - } - } - if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) { - lastTurn = i; - } - string0 = string1; - } +// pathDescription[i].nameID = pathDescription[i-1].nameID; +// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; +// } +// } +// if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) { +// lastTurn = i; +// } +// string0 = string1; +// } for(unsigned i = 1; i < pathDescription.size(); ++i) { diff --git a/Descriptors/JSONDescriptor.h b/Descriptors/JSONDescriptor.h index 967c72640..140cde9fe 100644 --- a/Descriptors/JSONDescriptor.h +++ b/Descriptors/JSONDescriptor.h @@ -69,7 +69,9 @@ public: void SetConfig(const _DescriptorConfig & c) { config = c; } void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) { + WriteHeaderToOutput(reply.content); + if(rawRoute.lengthOfShortestPath != INT_MAX) { descriptionFactory.SetStartSegment(phantomNodes.startPhantom); reply.content += "0," @@ -102,7 +104,7 @@ public: BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine, shortestSegments); } else { BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) { - short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; + TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction); } } @@ -155,7 +157,7 @@ public: BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine, alternativeSegments); } else { BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) { - short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; + TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction); } } @@ -242,7 +244,6 @@ public: reply.content += "},"; reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\""; reply.content += "}"; - } void GetRouteNames(std::vector & shortestSegments, std::vector & alternativeSegments, SearchEngineT &sEngine, RouteNames & routeNames) { @@ -312,7 +313,7 @@ public: std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction; //Fetch data from Factory and generate a string from it. BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) { - short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; + TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction); if(TurnInstructions.TurnIsNecessary( currentInstruction) ) { if(TurnInstructions.EnterRoundAbout == currentInstruction) { @@ -384,7 +385,6 @@ public: reply.content += "0.0"; reply.content += "]"; } - } }; diff --git a/Extractor/ScriptingEnvironment.cpp b/Extractor/ScriptingEnvironment.cpp index ffba75a65..01f183166 100644 --- a/Extractor/ScriptingEnvironment.cpp +++ b/Extractor/ScriptingEnvironment.cpp @@ -24,8 +24,6 @@ extern "C" { #include } -#include - #include "ScriptingEnvironment.h" #include "../typedefs.h" #include "../Util/OpenMPWrapper.h" diff --git a/Plugins/RouteParameters.h b/Plugins/RouteParameters.h index 3ecbc10ea..a718f9630 100644 --- a/Plugins/RouteParameters.h +++ b/Plugins/RouteParameters.h @@ -36,7 +36,7 @@ struct RouteParameters { bool geometry; bool compression; bool deprecatedAPI; - int checkSum; + unsigned checkSum; std::string service; std::string outputFormat; std::string jsonpParameter; @@ -58,7 +58,7 @@ struct RouteParameters { deprecatedAPI = true; } - void setChecksum(const int c) { + void setChecksum(const unsigned c) { checkSum = c; } diff --git a/Plugins/TimestampPlugin.h b/Plugins/TimestampPlugin.h index f2e8a4c2d..33c606e44 100644 --- a/Plugins/TimestampPlugin.h +++ b/Plugins/TimestampPlugin.h @@ -34,7 +34,6 @@ public: std::string GetVersionString() const { return std::string("0.3 (DL)"); } void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { std::string tmp; - std::string JSONParameter; //json if("" != routeParameters.jsonpParameter) { @@ -53,7 +52,7 @@ public: reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON timestamp (v0.3)\""; reply.content += ("}"); reply.headers.resize(3); - if("" != JSONParameter) { + if("" != routeParameters.jsonpParameter) { reply.content += ")"; reply.headers[1].name = "Content-Type"; reply.headers[1].value = "text/javascript"; diff --git a/Rakefile b/Rakefile index 7419e8cb1..727412797 100644 --- a/Rakefile +++ b/Rakefile @@ -6,6 +6,7 @@ require 'sys/proctable' DATA_FOLDER = 'sandbox' PROFILE = 'bicycle' +OSRM_PORT = 5000 Cucumber::Rake::Task.new do |t| t.cucumber_opts = %w{--format pretty} @@ -32,7 +33,7 @@ task osm_data_area_name.to_sym {} #define empty task to prevent rake from whin def each_process name, &block Sys::ProcTable.ps do |process| - if process.comm.strip == name.strip + if process.comm.strip == name.strip && process.state != 'zombie' yield process.pid.to_i, process.state.strip end end @@ -60,7 +61,7 @@ def write_server_ini osm_file s=<<-EOF Threads = 1 IP = 0.0.0.0 - Port = 5000 + Port = #{OSRM_PORT} hsgrData=#{osm_file}.osrm.hsgr nodesData=#{osm_file}.osrm.nodes @@ -68,6 +69,7 @@ def write_server_ini osm_file ramIndex=#{osm_file}.osrm.ramIndex fileIndex=#{osm_file}.osrm.fileIndex namesData=#{osm_file}.osrm.names + timestamp=#{osm_file}.osrm.timestamp EOF File.open( 'server.ini', 'w') {|f| f.write( s ) } end @@ -150,7 +152,7 @@ task :up => :setup do timeout = 5 (timeout*10).times do begin - socket = TCPSocket.new('localhost', 5000) + socket = TCPSocket.new('localhost', OSRM_PORT) socket.puts 'ping' rescue Errno::ECONNREFUSED sleep 0.1 diff --git a/RoutingAlgorithms/AlternativePathRouting.h b/RoutingAlgorithms/AlternativePathRouting.h index 2f07f33ad..b55d1a9aa 100644 --- a/RoutingAlgorithms/AlternativePathRouting.h +++ b/RoutingAlgorithms/AlternativePathRouting.h @@ -59,7 +59,7 @@ public: std::vector alternativePath; std::vector viaNodeCandidates; - std::deque packedShortestPath; + std::vector packedShortestPath; std::vector nodesThatPassPreselection; HeapPtr & forwardHeap = super::_queryData.forwardHeap; @@ -161,7 +161,7 @@ private: inline void retrievePackedViaPath(const HeapPtr & _forwardHeap1, const HeapPtr & _backwardHeap1, const HeapPtr & _forwardHeap2, const HeapPtr & _backwardHeap2, const NodeID s_v_middle, const NodeID v_t_middle, std::vector<_PathData> & unpackedPath) { //unpack [s,v) - std::deque packed_s_v_path, packed_v_t_path; + std::vector packed_s_v_path, packed_v_t_path; super::RetrievePackedPathFromHeap(_forwardHeap1, _backwardHeap2, s_v_middle, packed_s_v_path); packed_s_v_path.resize(packed_s_v_path.size()-1); //unpack [v,t] @@ -171,7 +171,7 @@ private: } inline void computeLengthAndSharingOfViaPath(const PreselectedNode& node, int *lengthOfViaPath, int *sharingOfViaPath, - const int offset, const std::deque & packedShortestPath) { + const int offset, const std::vector & packedShortestPath) { //compute and unpack and by exploring search spaces from v and intersecting against queues //only half-searches have to be done at this stage super::_queryData.InitializeOrClearSecondThreadLocalStorage(); @@ -181,8 +181,8 @@ private: HeapPtr & newForwardHeap = super::_queryData.forwardHeap2; HeapPtr & newBackwardHeap = super::_queryData.backwardHeap2; - std::deque < NodeID > packed_s_v_path; - std::deque < NodeID > packed_v_t_path; + std::vector < NodeID > packed_s_v_path; + std::vector < NodeID > packed_v_t_path; std::vector partiallyUnpackedShortestPath; std::vector partiallyUnpackedViaPath; @@ -258,8 +258,8 @@ private: //finished partial unpacking spree! Amount of sharing is stored to appropriate poiner variable } - inline int approximateAmountOfSharing(const NodeID middleNodeIDOfAlternativePath, HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const std::deque & packedShortestPath) { - std::deque packedAlternativePath; + inline int approximateAmountOfSharing(const NodeID middleNodeIDOfAlternativePath, HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const std::vector & packedShortestPath) { + std::vector packedAlternativePath; super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfAlternativePath, packedAlternativePath); if(packedShortestPath.size() < 2 || packedAlternativePath.size() < 2) @@ -336,8 +336,8 @@ private: //conduct T-Test inline bool viaNodeCandidatePasses_T_Test( HeapPtr& existingForwardHeap, HeapPtr& existingBackwardHeap, HeapPtr& newForwardHeap, HeapPtr& newBackwardHeap, const RankedCandidateNode& candidate, const int offset, const int lengthOfShortestPath, int * lengthOfViaPath, NodeID * s_v_middle, NodeID * v_t_middle) { - std::deque < NodeID > packed_s_v_path; - std::deque < NodeID > packed_v_t_path; + std::vector < NodeID > packed_s_v_path; + std::vector < NodeID > packed_v_t_path; super::_queryData.InitializeOrClearSecondThreadLocalStorage(); *s_v_middle = UINT_MAX; diff --git a/RoutingAlgorithms/BasicRoutingInterface.h b/RoutingAlgorithms/BasicRoutingInterface.h index 01066b524..bbe0474e4 100644 --- a/RoutingAlgorithms/BasicRoutingInterface.h +++ b/RoutingAlgorithms/BasicRoutingInterface.h @@ -104,7 +104,7 @@ public: } } - inline void UnpackPath(std::deque & packedPath, std::vector<_PathData> & unpackedPath) const { + inline void UnpackPath(std::vector & packedPath, std::vector<_PathData> & unpackedPath) const { const unsigned sizeOfPackedPath = packedPath.size(); std::stack > recursionStack; @@ -204,13 +204,15 @@ public: unpackedPath.push_back(t); } - inline void RetrievePackedPathFromHeap(const typename QueryDataT::HeapPtr & _fHeap, const typename QueryDataT::HeapPtr & _bHeap, const NodeID middle, std::deque& packedPath) { + inline void RetrievePackedPathFromHeap(const typename QueryDataT::HeapPtr & _fHeap, const typename QueryDataT::HeapPtr & _bHeap, const NodeID middle, std::vector& packedPath) { NodeID pathNode = middle; while(pathNode != _fHeap->GetData(pathNode).parent) { pathNode = _fHeap->GetData(pathNode).parent; - packedPath.push_front(pathNode); + packedPath.push_back(pathNode); } + std::reverse(packedPath.begin(), packedPath.end()); + packedPath.push_back(middle); pathNode = middle; while (pathNode != _bHeap->GetData(pathNode).parent){ diff --git a/RoutingAlgorithms/ShortestPathRouting.h b/RoutingAlgorithms/ShortestPathRouting.h index da553f616..6fc4c5996 100644 --- a/RoutingAlgorithms/ShortestPathRouting.h +++ b/RoutingAlgorithms/ShortestPathRouting.h @@ -47,8 +47,8 @@ public: bool searchFrom2ndStartNode(true); NodeID middle1 = ( NodeID ) UINT_MAX; NodeID middle2 = ( NodeID ) UINT_MAX; - std::deque packedPath1; - std::deque packedPath2; + std::vector packedPath1; + std::vector packedPath2; typename QueryDataT::HeapPtr & forwardHeap = super::_queryData.forwardHeap; typename QueryDataT::HeapPtr & backwardHeap = super::_queryData.backwardHeap; @@ -141,8 +141,8 @@ public: // INFO("middle1: " << middle1); //Unpack paths if they exist - std::deque temporaryPackedPath1; - std::deque temporaryPackedPath2; + std::vector temporaryPackedPath1; + std::vector temporaryPackedPath2; if(INT_MAX != _localUpperbound1) { super::RetrievePackedPathFromHeap(forwardHeap, backwardHeap, middle1, temporaryPackedPath1); // INFO("temporaryPackedPath1 ends with " << *(temporaryPackedPath1.end()-1) ); diff --git a/Server/APIGrammar.h b/Server/APIGrammar.h index 70c275fe0..b24a1b206 100644 --- a/Server/APIGrammar.h +++ b/Server/APIGrammar.h @@ -32,8 +32,8 @@ namespace qi = boost::spirit::qi; template struct APIGrammar : qi::grammar { APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h) { - api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> ('?') >> query; - query = (*(zoom | output | jsonp | checksum | location | hint | compressed_geometry | language | instruction | alt_route | old_API) ) ; + api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query); + query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | cmp | language | instruction | alt_route | old_API) ) ; zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)]; output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)]; @@ -53,7 +53,7 @@ struct APIGrammar : qi::grammar { } qi::rule api_call, query; qi::rule service, zoom, output, string, jsonp, checksum, location, hint, - compressed_geometry, stringwithDot, language, instruction, geometry, + stringwithDot, language, instruction, geometry, cmp, alt_route, old_API; HandlerT * handler; diff --git a/Server/DataStructures/QueryObjectsStorage.cpp b/Server/DataStructures/QueryObjectsStorage.cpp index 7efe9fde9..325cdb97d 100644 --- a/Server/DataStructures/QueryObjectsStorage.cpp +++ b/Server/DataStructures/QueryObjectsStorage.cpp @@ -46,8 +46,8 @@ QueryObjectsStorage::QueryObjectsStorage(std::string hsgrPath, std::string ramIn } if(!timestamp.length()) timestamp = "n/a"; - if(15 < timestamp.length()) - timestamp.resize(15); + if(25 < timestamp.length()) + timestamp.resize(25); INFO("Loading auxiliary information"); //Init nearest neighbor data structure diff --git a/Server/ServerFactory.h b/Server/ServerFactory.h index 3a740569a..966dc920f 100644 --- a/Server/ServerFactory.h +++ b/Server/ServerFactory.h @@ -61,7 +61,7 @@ struct ServerFactory { ERR("file index file not found"); } - unsigned threads = omp_get_num_procs(); + int threads = omp_get_num_procs(); if(serverConfig.GetParameter("IP") == "") serverConfig.SetParameter("IP", "0.0.0.0"); if(serverConfig.GetParameter("Port") == "") diff --git a/Tools/componentAnalysis.cpp b/Tools/componentAnalysis.cpp index f1abd8ed2..64790aa87 100644 --- a/Tools/componentAnalysis.cpp +++ b/Tools/componentAnalysis.cpp @@ -41,6 +41,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../DataStructures/DeallocatingVector.h" #include "../DataStructures/DynamicGraph.h" #include "../DataStructures/QueryEdge.h" +#include "../DataStructures/TurnInstructions.h" #include "../Util/BaseConfiguration.h" #include "../Util/InputFileUtil.h" #include "../Util/GraphLoader.h" diff --git a/Util/SRTMLookup.h b/Util/SRTMLookup.h deleted file mode 100644 index 92146cdcf..000000000 --- a/Util/SRTMLookup.h +++ /dev/null @@ -1,87 +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. - - ** Interface to the GridSquares. Template parameter determines which kind of - * raw data is used (NASA, or reduced). GridSquare data is globally cached, so - * that many queries can be answered without having to constantly mmap & unmmap - * the data files. - * - * Typical usage: - * - * Grid g(); - * cout << g.height(lng,lat) << endl; - * - */ - -#ifndef SRTMLOOKUP_H -#define SRTMLOOKUP_H - -#include -#include - -#include "NASAGridSquare.h" -#include "../DataStructures/LRUCache.h" - -class SRTMLookup { -public: - - SRTMLookup(std::string & _rp) : cache(MAX_CACHE_SIZE), ROOT_PATH(_rp) { - // Double check that this compiler truncates towards zero. - assert(-1 == int(float(-1.9))); - } - - /** Returns the height above sea level for the given lat/lng. */ - short height(const float longitude, const float latitude) { - if(0 == ROOT_PATH.size()) - return 0; - int lng,lat; - float lng_fraction,lat_fraction; - split(longitude,lng,lng_fraction); - split(latitude ,lat,lat_fraction); - - int k = key(lng,lat); - if(!cache.Holds(k)) { - cache.Insert(k , new NasaGridSquare(lng,lat, ROOT_PATH)); - } - NasaGridSquare * result; - cache.Fetch(k, result); - return result->getHeight(lng_fraction,lat_fraction); - } - -private: - /** Split a floating point number (num) into integer (i) & fraction (f) - * components. */ - inline void split(float num, int& i, float& f) const { - if(num>=0.0) - i=int(num); - else - i=int(num)-1; - f=num-float(i); - } - - /** Formula for grid squares' unique keys. */ - int key(int lng, int lat) { - return 1000*lat + lng; - } - LRUCache cache; - static const int MAX_CACHE_SIZE = 250; - std::string ROOT_PATH; -}; - -#endif // SRTMLOOKUP_H diff --git a/config/cucumber.yml b/config/cucumber.yml index 34690412f..5a9fa4eaa 100644 --- a/config/cucumber.yml +++ b/config/cucumber.yml @@ -1,4 +1,5 @@ # config/cucumber.yml ##YAML Template --- -default: --require features \ No newline at end of file +default: --require features +verify: --require features --tags ~@todo --tag ~@stress -f progress \ No newline at end of file diff --git a/createHierarchy.cpp b/createHierarchy.cpp index 44df57953..5d7f13d32 100644 --- a/createHierarchy.cpp +++ b/createHierarchy.cpp @@ -18,14 +18,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or see http://www.gnu.org/licenses/agpl.txt. */ -#define VERBOSE(x) x -#define VERBOSE2(x) - -#ifdef NDEBUG -#undef VERBOSE -#undef VERBOSE2 -#endif - extern "C" { #include #include @@ -139,7 +131,6 @@ int main (int argc, char *argv[]) { speedProfile.uTurnPenalty = 10*lua_tointeger(myLuaState, -1); - std::vector edgeList; NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions); in.close(); diff --git a/features/bicycle/access.feature b/features/bicycle/access.feature index 6ea15b9ec..149a2743c 100644 --- a/features/bicycle/access.feature +++ b/features/bicycle/access.feature @@ -3,7 +3,7 @@ Feature: Bike - Restricted access Reference: http://wiki.openstreetmap.org/wiki/Key:access Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Access tag hierachy on ways Then routability should be diff --git a/features/bicycle/area.feature b/features/bicycle/area.feature index 267e57539..0be8235d8 100644 --- a/features/bicycle/area.feature +++ b/features/bicycle/area.feature @@ -2,7 +2,7 @@ Feature: Bike - Squares and other areas Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" @square Scenario: Bike - Route along edge of a squares diff --git a/features/bicycle/barrier.feature b/features/bicycle/barrier.feature index dd75dd2b6..ed387c13f 100644 --- a/features/bicycle/barrier.feature +++ b/features/bicycle/barrier.feature @@ -2,7 +2,7 @@ Feature: Barriers Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Barriers Then routability should be @@ -10,6 +10,7 @@ Feature: Barriers | | x | | bollard | x | | gate | x | + | cycle_barrier | x | | cattle_grid | x | | border_control | x | | toll_booth | x | diff --git a/features/bicycle/cycleway.feature b/features/bicycle/cycleway.feature index 89aceb85e..bf42563ff 100644 --- a/features/bicycle/cycleway.feature +++ b/features/bicycle/cycleway.feature @@ -3,7 +3,7 @@ Feature: Bike - Cycle tracks/lanes Reference: http://wiki.openstreetmap.org/wiki/Key:cycleway Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Cycle tracks/lanes should enable biking Then routability should be diff --git a/features/bicycle/destination.feature b/features/bicycle/destination.feature index 7d3220f64..b3f8b5b37 100644 --- a/features/bicycle/destination.feature +++ b/features/bicycle/destination.feature @@ -2,7 +2,7 @@ Feature: Bike - Destination only, no passing through Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Destination only street Given the node map diff --git a/features/bicycle/ferry.feature b/features/bicycle/ferry.feature index 378a3a656..762774cf1 100644 --- a/features/bicycle/ferry.feature +++ b/features/bicycle/ferry.feature @@ -2,7 +2,7 @@ Feature: Bike - Handle ferry routes Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Ferry route Given the node map @@ -113,7 +113,8 @@ Feature: Bike - Handle ferry routes | from | to | route | time | | a | g | abcdefg | 23400s +-1 | | g | a | abcdefg | 23400s +-1 | - + + @todo Scenario: Bike - Ferry duration, individual parts Given the node map | x | y | | z | | | v | diff --git a/features/bicycle/maxspeed.feature b/features/bicycle/maxspeed.feature index 801c7c9c4..30d82b7e8 100644 --- a/features/bicycle/maxspeed.feature +++ b/features/bicycle/maxspeed.feature @@ -2,7 +2,7 @@ Feature: Bike - Max speed restrictions Background: Use specific speeds - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Respect maxspeeds when lower that way type speed Given the node map diff --git a/features/bicycle/names.feature b/features/bicycle/names.feature index 9bc8dad2d..d1912472f 100644 --- a/features/bicycle/names.feature +++ b/features/bicycle/names.feature @@ -2,7 +2,7 @@ Feature: Bike - Street names in instructions Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - A named street Given the node map @@ -19,26 +19,14 @@ Feature: Bike - Street names in instructions | a | c | My Way,Your Way | Scenario: Bike - Use way type to describe unnamed ways - Given the node map - | a | b | c | - - And the ways - | nodes | highway | name | - | ab | cycleway | | - | bc | track | | - - When I route I should get - | from | to | route | - | a | c | cycleway,track | - - Scenario: Bike - Don't create instructions for every node of unnamed ways Given the node map | a | b | c | d | And the ways | nodes | highway | name | - | abcd | cycleway | | + | ab | cycleway | | + | bcd | track | | When I route I should get - | from | to | route | - | a | d | cycleway | \ No newline at end of file + | from | to | route | + | a | d | cycleway,track | \ No newline at end of file diff --git a/features/bicycle/oneway.feature b/features/bicycle/oneway.feature index 0b1d3caf9..4e6cb4f2d 100644 --- a/features/bicycle/oneway.feature +++ b/features/bicycle/oneway.feature @@ -3,7 +3,7 @@ Feature: Bike - Oneway streets Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Simple oneway Then routability should be diff --git a/features/bicycle/restrictions.feature b/features/bicycle/restrictions.feature index 073233114..736c939aa 100644 --- a/features/bicycle/restrictions.feature +++ b/features/bicycle/restrictions.feature @@ -4,7 +4,7 @@ Feature: Bike - Turn restrictions Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes. Background: Use car routing - Given the speedprofile "bicycle" + Given the profile "bicycle" @no_turning Scenario: Bike - No left turn diff --git a/features/bicycle/stop_area.feature b/features/bicycle/stop_area.feature new file mode 100644 index 000000000..7113808b0 --- /dev/null +++ b/features/bicycle/stop_area.feature @@ -0,0 +1,37 @@ +@routing @bicycle @stop_area @todo +Feature: Bike - Stop areas for public transport +Platforms and railway/bus lines are connected using a relation rather that a way, as specified in: +http://wiki.openstreetmap.org/wiki/Tag:public_transport%3Dstop_area + + Background: + Given the profile "bicycle" + + Scenario: Bike - Platforms tagged using public_transport + Then routability should be + | highway | public_transport | bicycle | bothw | + | primary | | | x | + | (nil) | platform | | x | + + Scenario: Bike - railway platforms + Given the node map + | a | b | c | d | + | | s | t | | + + And the nodes + | node | public_transport | + | c | stop_position | + + And the ways + | nodes | highway | railway | bicycle | public_transport | + | abcd | (nil) | train | yes | | + | st | (nil) | (nil) | | platform | + + And the relations + | type | public_transport | node:stop | way:platform | + | public_transport | stop_area | c | st | + + When I route I should get + | from | to | route | + | a | d | abcd | + | s | t | st | + | s | d | /st,.+,abcd/ | diff --git a/features/bicycle/train.feature b/features/bicycle/train.feature index dd67e08db..1b5699f16 100644 --- a/features/bicycle/train.feature +++ b/features/bicycle/train.feature @@ -3,7 +3,7 @@ Feature: Bike - Handle ferry routes Bringing bikes on trains and subways Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Bringing bikes on trains Then routability should be diff --git a/features/bicycle/way.feature b/features/bicycle/way.feature index 9586c8e20..ca157bd25 100644 --- a/features/bicycle/way.feature +++ b/features/bicycle/way.feature @@ -2,11 +2,11 @@ Feature: Bike - Accessability of different way types Background: - Given the speedprofile "bicycle" + Given the profile "bicycle" Scenario: Bike - Basic access Bikes are allowed on footways etc because you can pull your bike at a lower speed. - Given the speedprofile "bicycle" + Given the profile "bicycle" Then routability should be | highway | forw | | (nil) | | diff --git a/features/car/access.feature b/features/car/access.feature index a2aca3b57..97e61c5f8 100644 --- a/features/car/access.feature +++ b/features/car/access.feature @@ -3,7 +3,7 @@ Feature: Car - Restricted access Reference: http://wiki.openstreetmap.org/wiki/Key:access Background: - Given the speedprofile "car" + Given the profile "car" Scenario: Car - Access tag hierachy on ways Then routability should be @@ -92,7 +92,7 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:access | no | | | private | | | agricultural | | - | forestery | | + | forestry | | | some_tag | x | @@ -105,7 +105,7 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:access | no | | | private | | | agricultural | | - | forestery | | + | forestry | | | some_tag | x | Scenario: Car - Access tags on both node and way diff --git a/features/car/barrier.feature b/features/car/barrier.feature index 1ae343237..9d37d354a 100644 --- a/features/car/barrier.feature +++ b/features/car/barrier.feature @@ -2,7 +2,7 @@ Feature: Car - Barriers Background: - Given the speedprofile "car" + Given the profile "car" Scenario: Car - Barriers Then routability should be diff --git a/features/car/destination.feature b/features/car/destination.feature index 35314369a..43059e1e2 100644 --- a/features/car/destination.feature +++ b/features/car/destination.feature @@ -2,7 +2,7 @@ Feature: Car - Destination only, no passing through Background: - Given the speedprofile "car" + Given the profile "car" Scenario: Car - Destination only street Given the node map diff --git a/features/car/ferry.feature b/features/car/ferry.feature index 4b1caf583..3182c7533 100644 --- a/features/car/ferry.feature +++ b/features/car/ferry.feature @@ -2,7 +2,7 @@ Feature: Car - Handle ferry routes Background: - Given the speedprofile "car" + Given the profile "car" Scenario: Car - Use a ferry route Given the node map diff --git a/features/car/maxspeed.feature b/features/car/maxspeed.feature index 52d920ec4..cc31c6c13 100644 --- a/features/car/maxspeed.feature +++ b/features/car/maxspeed.feature @@ -2,7 +2,7 @@ Feature: Car - Max speed restrictions Background: Use specific speeds - Given the speedprofile "car" + Given the profile "car" Given a grid size of 1000 meters Scenario: Car - Respect maxspeeds when lower that way type speed diff --git a/features/car/names.feature b/features/car/names.feature index d937b3855..d7d98b7e4 100644 --- a/features/car/names.feature +++ b/features/car/names.feature @@ -2,7 +2,7 @@ Feature: Car - Street names in instructions Background: - Given the speedprofile "car" + Given the profile "car" Scenario: Car - A named street Given the node map @@ -10,35 +10,24 @@ Feature: Car - Street names in instructions | | c | And the ways - | nodes | name | - | ab | My Way | + | nodes | name | + | ab | My Way | | bc | Your Way | When I route I should get | from | to | route | | a | c | My Way,Your Way | + @todo Scenario: Car - Use way type to describe unnamed ways - Given the node map - | a | b | c | - - And the ways - | nodes | highway | name | - | ab | tertiary | | - | bc | residential | | - - When I route I should get - | from | to | route | - | a | c | tertiary,residential | - - Scenario: Car - Don't create instructions for every node of unnamed ways Given the node map | a | b | c | d | And the ways - | nodes | highway | name | - | abcd | primary | | + | nodes | highway | name | + | ab | tertiary | | + | bcd | residential | | When I route I should get - | from | to | route | - | a | d | primary | + | from | to | route | + | a | c | tertiary,residential | diff --git a/features/car/oneway.feature b/features/car/oneway.feature index 99963680e..0d906c06c 100644 --- a/features/car/oneway.feature +++ b/features/car/oneway.feature @@ -3,7 +3,7 @@ Feature: Car - Oneway streets Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing Background: - Given the speedprofile "car" + Given the profile "car" Scenario: Car - Simple oneway Then routability should be diff --git a/features/car/restrictions.feature b/features/car/restrictions.feature index 2bc00f4a9..1ee527395 100644 --- a/features/car/restrictions.feature +++ b/features/car/restrictions.feature @@ -4,7 +4,7 @@ Feature: Car - Turn restrictions Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes. Background: Use car routing - Given the speedprofile "car" + Given the profile "car" @no_turning Scenario: Car - No left turn diff --git a/features/car/way.feature b/features/car/way.feature index 873dea943..8ca62a56c 100644 --- a/features/car/way.feature +++ b/features/car/way.feature @@ -2,7 +2,7 @@ Feature: Car - Accessability of different way types Background: - Given the speedprofile "car" + Given the profile "car" Scenario: Car - Basic access Then routability should be diff --git a/features/foot/oneway.feature b/features/foot/oneway.feature index 3eb82b4a4..e1c96e3ac 100644 --- a/features/foot/oneway.feature +++ b/features/foot/oneway.feature @@ -3,7 +3,7 @@ Feature: Foot - Oneway streets Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing Background: - Given the speedprofile "foot" + Given the profile "foot" Scenario: Foot - Walking should not be affected by oneways Then routability should be diff --git a/features/foot/way.feature b/features/foot/way.feature index 19b728ebd..e18d9f871 100644 --- a/features/foot/way.feature +++ b/features/foot/way.feature @@ -2,7 +2,7 @@ Feature: Foot - Accessability of different way types Background: - Given the speedprofile "foot" + Given the profile "foot" Scenario: Foot - Basic access Then routability should be diff --git a/features/investigate/weird.feature b/features/investigate/weird.feature index 7c4cbcfd7..f84a07592 100644 --- a/features/investigate/weird.feature +++ b/features/investigate/weird.feature @@ -2,7 +2,7 @@ Feature: Weird routings discovered Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Routing on a oneway roundabout Given the node map diff --git a/features/step_definitions/data.rb b/features/step_definitions/data.rb index f4e5de00e..fc34105fb 100644 --- a/features/step_definitions/data.rb +++ b/features/step_definitions/data.rb @@ -1,5 +1,5 @@ -Given /^the speedprofile "([^"]*)"$/ do |profile| - read_speedprofile profile +Given /^the profile "([^"]*)"$/ do |profile| + set_profile profile end Given /^a grid size of (\d+) meters$/ do |meters| diff --git a/features/step_definitions/errors.rb b/features/step_definitions/errors.rb deleted file mode 100644 index 554e07857..000000000 --- a/features/step_definitions/errors.rb +++ /dev/null @@ -1,15 +0,0 @@ - -When /^I preprocess data$/ do - begin - osrm_kill - reprocess - rescue OSRMError => e - @process_error = e - end -end - -Then /^preparing should return code (\d+)$/ do |code| - @process_error.class.should == OSRMError - @process_error.process.should == 'osrm-prepare' - @process_error.code.to_i.should == code.to_i -end diff --git a/features/step_definitions/processing.rb b/features/step_definitions/processing.rb deleted file mode 100644 index 323604e1d..000000000 --- a/features/step_definitions/processing.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'OSM/StreamParser' - -class OSMTestParserCallbacks < OSM::Callbacks - @@locations = nil - - def self.locations - if @@locations - @@locations - else - #parse the test file, so we can later reference nodes and ways by name in tests - @@locations = {} - file = 'test/data/test.osm' - callbacks = OSMTestParserCallbacks.new - parser = OSM::StreamParser.new(:filename => file, :callbacks => callbacks) - parser.parse - puts @@locations - end - end - - def node(node) - @@locations[node.name] = [node.lat,node.lon] - end -end - - -Given /^the OSM file contains$/ do |string| - file = 'data/test.osm' - File.open( file, 'w') {|f| f.write(string) } - - #convert from .osm to .osm.pbf, which is the format osrm reads - system "osmosis --read-xml data/test.osm --write-pbf data/test.osm.pbf omitmetadata=true" -end - -Given /^the speedprofile contains$/ do |string| - File.open( 'speedprofile.ini', 'w') {|f| f.write(string) } -end - - - -Given /^the data file "([^"]*)" is present$/ do |file| - File.exists?(file).should == true -end - -When /^I run the extractor with "([^"]*)"$/ do |cmd| - @response = `#{cmd}` - #Dir.chdir @test_folder do - # @response = IO.popen([cmd, :err=>[:child, :out]]) { |ls_io| ls_result_with_error = ls_io.read } - #end -end - -When /^I run the preprocessor with "([^"]*)"$/ do |cmd| - @response = `#{cmd}` -end - -Given /^the preprocessed files for "([^"]*)" are present and up to date$/ do |area| - File.exists?("#{area}.osrm").should == true - File.exists?("#{area}.osrm.names").should == true - File.exists?("#{area}.osrm.restrictions").should == true - File.exists?("#{area}.osrm.hsgr").should == true - File.exists?("#{area}.osrm.nodes").should == true - File.exists?("#{area}.osrm.edges").should == true - File.exists?("#{area}.osrm.ramIndex").should == true - File.exists?("#{area}.osrm.fileIndex").should == true -end - -Then /^I should see the file "([^"]*)"$/ do |file| - File.exists?(file).should == true -end - -When /^preprocessed files for "([^"]*)" has been removed$/ do |file| - FileUtils.rm_r Dir["#{file}.*"], :secure => true -end - diff --git a/features/step_definitions/requests.rb b/features/step_definitions/requests.rb new file mode 100644 index 000000000..d965b1aa0 --- /dev/null +++ b/features/step_definitions/requests.rb @@ -0,0 +1,45 @@ +When /^I request \/(.*)$/ do |path| + reprocess + OSRMLauncher.new do + @response = request_path path + end +end + +Then /^I should get a response/ do + @response.code.should == "200" + @response.body.should_not == nil + @response.body.should_not == '' +end + +Then /^response should be valid JSON$/ do + @json = JSON.parse @response.body +end + +Then /^response should be well-formed$/ do + @json['version'].class.should == Float + @json['status'].class.should == Fixnum + @json['transactionId'].class.should == String +end + +Then /^response should be a well-formed route$/ do + step "response should be well-formed" + @json['status_message'].class.should == String + @json['route_summary'].class.should == Hash + @json['route_geometry'].class.should == String + @json['route_instructions'].class.should == Array + @json['via_points'].class.should == Array +end + +When /^I preprocess data$/ do + begin + reprocess + rescue OSRMError => e + @process_error = e + end +end + +Then /^"([^"]*)" should return code (\d+)$/ do |binary, code| + @process_error.is_a?(OSRMError).should == true + @process_error.process.should == binary + @process_error.code.to_i.should == code.to_i +end diff --git a/features/step_definitions/routability.rb b/features/step_definitions/routability.rb new file mode 100644 index 000000000..d949d01b9 --- /dev/null +++ b/features/step_definitions/routability.rb @@ -0,0 +1,40 @@ +Then /^routability should be$/ do |table| + build_ways_from_table table + reprocess + actual = [] + if table.headers&["forw","backw","bothw"] == [] + raise "*** routability tabel must contain either 'forw', 'backw' or 'bothw' column" + end + OSRMLauncher.new do + table.hashes.each_with_index do |row,i| + got = row.dup + attempts = [] + ['forw','backw','bothw'].each do |direction| + if table.headers.include? direction + if direction == 'forw' || direction == 'bothw' + response = request_route("#{ORIGIN[1]},#{ORIGIN[0]+(1+WAY_SPACING*i)*@zoom}","#{ORIGIN[1]},#{ORIGIN[0]+(3+WAY_SPACING*i)*@zoom}") + elsif direction == 'backw' || direction == 'bothw' + response = request_route("#{ORIGIN[1]},#{ORIGIN[0]+(3+WAY_SPACING*i)*@zoom}","#{ORIGIN[1]},#{ORIGIN[0]+(1+WAY_SPACING*i)*@zoom}") + end + got[direction] = route_status response + json = JSON.parse(response.body) + if got[direction].empty? == false + route = way_list json['route_instructions'] + if route != "w#{i}" + got[direction] = "testing w#{i}, but got #{route}!?" + elsif row[direction] =~ /\d+s/ + time = json['route_summary']['total_time'] + got[direction] = "#{time}s" + end + end + if got[direction] != row[direction] + attempts << { :attempt => direction, :query => @query, :response => response } + end + end + end + log_fail row,got,attempts if got != row + actual << got + end + end + table.routing_diff! actual +end diff --git a/features/step_definitions/routing.rb b/features/step_definitions/routing.rb index efc214219..32e6f60e5 100644 --- a/features/step_definitions/routing.rb +++ b/features/step_definitions/routing.rb @@ -1,194 +1,4 @@ -When /^I request a route from ([^"]+) to ([^"]+)$/ do |a,b| - @response = request_route a,b - #puts @response.body - #@response -end - -When /^I request a route from "([^"]*)" to "([^"]*)"$/ do |a,b| - locations = OSMTestParserCallbacks.locations - raise "Locations hash is empty. To reference nodes by name, please preprocess the test file earlier in the test." unless locations - raise "Unknown node: #{a}" unless locations[a] - raise "Unknown node: #{b}" unless locations[b] - @response = request_route "#{locations[a][0]},#{locations[a][1]}", "#{locations[b][0]},#{locations[b][1]}" -end - -Then /^I should get a response/ do - @response.code.should == "200" - @response.body.should_not == nil - @response.body.should_not == '' -end - -Then /^response should be valid JSON$/ do - @json = JSON.parse @response.body -end - -Then /^response should be well-formed$/ do - @json['version'].class.should == Float - @json['status'].class.should == Fixnum - @json['status_message'].class.should == String - @json['route_summary'].class.should == Hash - @json['route_geometry'].class.should == String - @json['route_instructions'].class.should == Array - @json['via_points'].class.should == Array - @json['transactionId'].class.should == String -end - -Then /^a route should be found$/ do - @json['status'].should == 0 - @json['status_message'].should == "Found route between points" -end - -Then /^no route should be found$/ do - @json['status'].should == 207 - @json['status_message'].should == "Cannot find route between points" -end - -Then /^I should get a valid response$/ do - step "I should get a response" - step "response should be valid JSON" - step "response should be well-formed" - #step "no error should be reported in terminal" -end - -Then /^I should get a route$/ do - step "I should get a valid response" - step "a route should be found" - #puts @response.body -end - -Then /^I should not get a route$/ do - step "I should get a valid response" - step "no route should be found" -end - -Then /^the route should start at "([^']*)"$/ do |name| - @json['route_summary']['start_point'].should == name -end - -Then /^the route should end at "([^']*)"$/ do |name| - @json['route_summary']['end_point'].should == name -end - -Then /^distance should be between (\d+) and (\d+)$/ do |min,max| - @json['route_summary']['total_distance'].to_i.should >= min.to_i - @json['route_summary']['total_distance'].to_i.should <= max.to_i -end - -Then /^the distance should be close to (\d+)m$/ do |d| - @json['route_summary']['total_distance'].to_i.should >= d.to_i*0.95 - @json['route_summary']['total_distance'].to_i.should <= d.to_i/0.95 -end - -Then /^number of instructions should be (\d+)$/ do |n| - @json['route_instructions'].size.should == n -end - -Then /^there should be 1 turn$/ do - step 'there should be 1 turns' -end - -Then /^there should be (\d+) turns$/ do |n| - @json['route_instructions'].map {|t| t.first}.select {|t| t =~ /^Turn/ }.size.should == n.to_i -end - -Then /^there should be more than (\d+) turn$/ do |n| - @json['route_instructions'].map {|t| t.first}.select {|t| t =~ /^Turn/ }.size.should > n.to_i -end - -Then /^there should not be any turns$/ do - (@json['route_instructions'].size-1).should == 0 -end - -def sanitize_route route - route.split(',').map{|w| w.strip}.reject(&:empty?).join(', ') -end - -def computed_route - @json['route_instructions'].map { |r| r[1] }.reject(&:empty?).join(', ') -end - -Then /^the route should follow "([^"]*)"$/ do |route| - sanitize_route(route).should == computed_route -end - -Then /^the route should not follow "([^"]*)"$/ do |route| - sanitize_route(route).should_not == computed_route -end - -Then /^the route should include "([^"]*)"$/ do |route| - sanitize_route(route).should =~ /#{computed_route}/ -end - -Then /^the route should not include "([^"]*)"$/ do |route| - sanitize_route(route).should_not =~ /#{computed_route}/ -end - -Then /^the route should stay on "([^"]*)"$/ do |way| - step "the route should start at \"#{way}\"" - step "the route should end at \"#{way}\"" - step "the route should follow \"#{way}\"" - step "there should not be any turns" -end - -When /^I route between "([^"]*)" and "([^"]*)"$/ do |from,to| - reprocess - Dir.chdir 'test' do - from_node = name_node_hash[from] - to_node = name_node_hash[to] - a = "#{from_node.lon},#{from_node.lat}" - b = "#{to_node.lon},#{to_node.lat}" - @route = parse_response( request_route(a,b) ) - end -end - -Then /^"([^"]*)" should be returned$/ do |route| - @route.should == route.split(',').join(',') -end - -Then /^routability should be$/ do |table| - osrm_kill - build_ways_from_table table - reprocess - actual = [] - if table.headers&["forw","backw","bothw"] == [] - raise "*** routability tabel must contain either 'forw', 'backw' or 'bothw' column" - end - OSRMLauncher.new do - table.hashes.each_with_index do |row,i| - got = row.dup - attempts = [] - ['forw','backw','bothw'].each do |direction| - if table.headers.include? direction - if direction == 'forw' || direction == 'bothw' - response = request_route("#{ORIGIN[1]},#{ORIGIN[0]+(1+WAY_SPACING*i)*@zoom}","#{ORIGIN[1]},#{ORIGIN[0]+(3+WAY_SPACING*i)*@zoom}") - elsif direction == 'backw' || direction == 'bothw' - response = request_route("#{ORIGIN[1]},#{ORIGIN[0]+(3+WAY_SPACING*i)*@zoom}","#{ORIGIN[1]},#{ORIGIN[0]+(1+WAY_SPACING*i)*@zoom}") - end - got[direction] = route_status response - json = JSON.parse(response.body) - if got[direction].empty? == false - route = way_list json['route_instructions'] - if route != "w#{i}" - got[direction] = "testing w#{i}, but got #{route}!?" - elsif row[direction] =~ /\d+s/ - time = json['route_summary']['total_time'] - got[direction] = "#{time}s" - end - end - if got[direction] != row[direction] - attempts << { :attempt => direction, :query => @query, :response => response } - end - end - end - log_fail row,got,attempts if got != row - actual << got - end - end - table.routing_diff! actual -end - When /^I route I should get$/ do |table| - osrm_kill reprocess actual = [] OSRMLauncher.new do @@ -204,6 +14,7 @@ When /^I route I should get$/ do |table| instructions = way_list json['route_instructions'] bearings = bearing_list json['route_instructions'] compasses = compass_list json['route_instructions'] + turns = turn_list json['route_instructions'] end end @@ -232,11 +43,14 @@ When /^I route I should get$/ do |table| if table.headers.include? 'compass' got['compass'] = compasses end + if table.headers.include? 'turns' + got['turns'] = turns + end end ok = true row.keys.each do |key| - if row[key].match /(.*)\s+~(.+)%$/ + if row[key].match /(.*)\s+~(.+)%$/ #percentage range: 100 ~5% margin = 1 - $2.to_f*0.01 from = $1.to_f*margin to = $1.to_f/margin @@ -245,7 +59,7 @@ When /^I route I should get$/ do |table| else ok = false end - elsif row[key].match /(.*)\s+\+\-(.+)$/ + elsif row[key].match /(.*)\s+\+\-(.+)$/ #absolute range: 100 +-5 margin = $2.to_f from = $1.to_f-margin to = $1.to_f+margin @@ -254,6 +68,10 @@ When /^I route I should get$/ do |table| else ok = false end + elsif row[key] =~ /^\/(.*)\/$/ #regex: /a,b,.*/ + if got[key] =~ /#{$1}/ + got[key] = row[key] + end else ok = row[key] == got[key] end @@ -269,3 +87,11 @@ When /^I route I should get$/ do |table| end table.routing_diff! actual end + +When /^I route (\d+) times I should get$/ do |n,table| + ok = true + n.to_i.times do + ok = false unless step "I route I should get", table + end + ok +end \ No newline at end of file diff --git a/features/step_definitions/timestamp.rb b/features/step_definitions/timestamp.rb new file mode 100644 index 000000000..53d4083a8 --- /dev/null +++ b/features/step_definitions/timestamp.rb @@ -0,0 +1,7 @@ +Then /^I should get a valid timestamp/ do + step "I should get a response" + step "response should be valid JSON" + step "response should be well-formed" + @json['timestamp'].class.should == String + @json['timestamp'].should == OSM_TIMESTAMP +end diff --git a/features/stress/launch.feature b/features/stress/launch.feature new file mode 100644 index 000000000..246378204 --- /dev/null +++ b/features/stress/launch.feature @@ -0,0 +1,58 @@ +@stress +Feature: Stress testing + + Background: + Given the profile "testbot" + + Scenario: Stress - 10km star, request 1 route + #osrm-routed hangs very often + Given a grid size of 10000 meters + Given the node map + | h | a | b | + | g | x | c | + | f | e | d | + + And the ways + | nodes | highway | + | xa | primary | + | xb | primary | + | xc | primary | + | xd | primary | + | xe | primary | + | xf | primary | + | xg | primary | + | xh | primary | + + When I route 100 times I should get + | from | to | route | + | x | h | xh | + + Scenario: Stress - 10km star, request 8 routes + #osrm-routed hangs sometimes + Given a grid size of 10000 meters + Given the node map + | h | a | b | + | g | x | c | + | f | e | d | + + And the ways + | nodes | highway | + | xa | primary | + | xb | primary | + | xc | primary | + | xd | primary | + | xe | primary | + | xf | primary | + | xg | primary | + | xh | primary | + + When I route 100 times I should get + | from | to | route | + | x | a | xa | + | x | b | xb | + | x | c | xc | + | x | d | xd | + | x | e | xe | + | x | f | xf | + | x | g | xg | + | x | h | xh | diff --git a/features/support/config.rb b/features/support/config.rb index c66cdde5f..63350d511 100644 --- a/features/support/config.rb +++ b/features/support/config.rb @@ -1,21 +1,21 @@ -def speedprofile - @speedprofile ||= reset_speedprofile +def profile + @profile ||= reset_profile end -def reset_speedprofile - @speedprofile = nil - read_speedprofile DEFAULT_SPEEDPROFILE +def reset_profile + @profile = nil + set_profile DEFAULT_SPEEDPROFILE end -def read_speedprofile profile - @speedprofile = profile +def set_profile profile + @profile = profile end def write_server_ini s=<<-EOF Threads = 1 IP = 0.0.0.0 -Port = 5000 +Port = #{OSRM_PORT} hsgrData=#{@osm_file}.osrm.hsgr nodesData=#{@osm_file}.osrm.nodes @@ -23,6 +23,7 @@ edgesData=#{@osm_file}.osrm.edges ramIndex=#{@osm_file}.osrm.ramIndex fileIndex=#{@osm_file}.osrm.fileIndex namesData=#{@osm_file}.osrm.names +timestamp=#{@osm_file}.osrm.timestamp EOF File.open( 'server.ini', 'w') {|f| f.write( s ) } end diff --git a/features/support/data.rb b/features/support/data.rb index 88f211be5..392265da4 100644 --- a/features/support/data.rb +++ b/features/support/data.rb @@ -116,7 +116,7 @@ def reset_data #clear_log #clear_data_files end - reset_speedprofile + reset_profile reset_osm @fingerprint = nil end @@ -131,10 +131,6 @@ def reset_osm name_way_hash.clear @osm_str = nil @osm_hash = nil - - ##ID -1 causes trouble, so add a few nodes to avoid it - #node = OSM::Node.new nil, OSM_USER, OSM_TIMESTAMP, 0,0 - #node = OSM::Node.new nil, OSM_USER, OSM_TIMESTAMP, 0,0 @osm_id = 0 end @@ -180,9 +176,8 @@ def convert_osm_to_pbf unless File.exist?("#{@osm_file}.osm.pbf") log_preprocess_info log "== Converting #{@osm_file}.osm to protobuffer format...", :preprocess - #redirect stdout and stderr to a log file avoid output in the cucumber console unless system "osmosis --read-xml #{@osm_file}.osm --write-pbf #{@osm_file}.osm.pbf omitmetadata=true 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE}" - raise "Failed to convert to proto buffer format. Please see #{hash}.log for more info." + raise OsmosisError.new $?, "osmosis exited with code #{$?.exitstatus}" end log '', :preprocess end @@ -198,25 +193,30 @@ def prepared? File.exist?("#{@osm_file}.osrm.hsgr") end +def write_timestamp + File.open( "#{@osm_file}.osrm.timestamp", 'w') {|f| f.write(OSM_TIMESTAMP) } +end + def reprocess Dir.chdir TEST_FOLDER do write_osm + write_timestamp convert_osm_to_pbf unless extracted? log_preprocess_info log "== Extracting #{@osm_file}.osm...", :preprocess - unless system "../osrm-extract #{@osm_file}.osm.pbf 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE} ../profiles/#{@speedprofile}.lua" + unless system "../osrm-extract #{@osm_file}.osm.pbf 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE} ../profiles/#{@profile}.lua" log "*** Exited with code #{$?.exitstatus}.", :preprocess - raise OSRMError.new 'osrm-extract', $?.exitstatus, "*** osrm-extract exited with code #{$?.exitstatus}. The file preprocess.log might contain more info." + raise ExtractError.new $?.exitstatus, "osrm-extract exited with code #{$?.exitstatus}." end log '', :preprocess end unless prepared? log_preprocess_info log "== Preparing #{@osm_file}.osm...", :preprocess - unless system "../osrm-prepare #{@osm_file}.osrm #{@osm_file}.osrm.restrictions 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE} ../profiles/#{@speedprofile}.lua" + unless system "../osrm-prepare #{@osm_file}.osrm #{@osm_file}.osrm.restrictions 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE} ../profiles/#{@profile}.lua" log "*** Exited with code #{$?.exitstatus}.", :preprocess - raise OSRMError.new 'osrm-prepare', $?.exitstatus, "*** osrm-prepare exited with code #{$?.exitstatus}. The file preprocess.log might contain more info." + raise PrepareError.new $?.exitstatus, "osrm-prepare exited with code #{$?.exitstatus}." end log '', :preprocess end diff --git a/features/support/env.rb b/features/support/env.rb index 9fb7ec8d1..13a0b0c5e 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -1 +1,18 @@ -require 'rspec/expectations' \ No newline at end of file +require 'rspec/expectations' + +DEFAULT_PORT = 5000 + + +puts "Ruby version #{RUBY_VERSION}" +unless RUBY_VERSION =~ /^1.9/ + raise "*** Please upgrade to Ruby 1.9.x to run the OSRM cucumber tests" +end + +if ENV["OSRM_PORT"] + OSRM_PORT = ENV["OSRM_PORT"].to_i + puts "Port set to #{OSRM_PORT}" +else + OSRM_PORT = DEFAULT_PORT + puts "Using default port #{OSRM_PORT}" +end + diff --git a/features/support/exceptions.rb b/features/support/exceptions.rb index 730411379..22a6868ab 100644 --- a/features/support/exceptions.rb +++ b/features/support/exceptions.rb @@ -1,14 +1,49 @@ class OSRMError < StandardError - attr_accessor :process, :code, :msg - - def initialize process, code, msg + attr_accessor :msg, :code, :process + + def initialize process, code, msg, log, lines @process = process @code = code @msg = msg + @lines = lines + @log = log + @extract = log_tail @log, @lines end def to_s - @msg + "*** #{@msg}\nLast #{@lines} lines from #{@log}:\n#{@extract}\n" end -end \ No newline at end of file + + private + + def log_tail path, n + File.open(path) do |f| + return f.tail(n).map { |line| " > #{line}" }.join "\n" + end + end +end + +class OsmosisError < OSRMError + def initialize code, msg + super 'osmosis', code, msg, PREPROCESS_LOG_FILE, 40 + end +end + +class ExtractError < OSRMError + def initialize code, msg + super 'osrm-extract', code, msg, PREPROCESS_LOG_FILE, 3 + end +end + +class PrepareError < OSRMError + def initialize code, msg + super 'osrm-prepare', code, msg, PREPROCESS_LOG_FILE, 3 + end +end + +class RoutedError < OSRMError + def initialize msg + super 'osrm-routed', nil, msg, OSRM_ROUTED_LOG_FILE, 3 + end +end diff --git a/features/support/file.rb b/features/support/file.rb new file mode 100644 index 000000000..cd8fd14b3 --- /dev/null +++ b/features/support/file.rb @@ -0,0 +1,22 @@ +class File + + #read last n lines of a file. useful for getting last part of a big log file. + def tail(n) + buffer = 1024 + idx = (size - buffer).abs + chunks = [] + lines = 0 + + begin + seek(idx) + chunk = read(buffer) + lines += chunk.count("\n") + chunks.unshift chunk + idx -= buffer + end while lines < ( n + 1 ) && pos != 0 + + tail_of_file = chunks.join('') + ary = tail_of_file.split(/\n/) + lines_to_return = ary[ ary.size - n, ary.size - 1 ] + end +end \ No newline at end of file diff --git a/features/support/hash.rb b/features/support/hash.rb index 2c729fe21..b4b2f762b 100644 --- a/features/support/hash.rb +++ b/features/support/hash.rb @@ -11,8 +11,9 @@ def hash_of_file path return hash.hexdigest end -def speedprofile_hash - @speedprofile_hash ||= hash_of_file "../profiles/#{@speedprofile}.lua" +def profile_hash + @@profile_hashes ||= {} + @@profile_hashes[@profile] ||= hash_of_file "../profiles/#{@profile}.lua" end def osm_hash @@ -20,19 +21,19 @@ def osm_hash end def bin_extract_hash - @bin_hash ||= hash_of_file '../osrm-extract' + @@bin_extract_hash ||= hash_of_file '../osrm-extract' end def bin_prepare_hash - @bin_hash ||= hash_of_file '../osrm-prepare' + @@bin_prepare_hash ||= hash_of_file '../osrm-prepare' end def bin_routed_hash - @bin_hash ||= hash_of_file '../osrm-routed' + @@bin_routed_hash ||= hash_of_file '../osrm-routed' end -#combine state of data, speedprofile and binaries into a hash that identifies the exact test scenario +#combine state of data, profile and binaries into a hash that identifies the exact test scenario def fingerprint - @fingerprint ||= Digest::SHA1.hexdigest "#{bin_extract_hash}-#{bin_prepare_hash}-#{bin_routed_hash}-#{speedprofile_hash}-#{osm_hash}" + @fingerprint ||= Digest::SHA1.hexdigest "#{bin_extract_hash}-#{bin_prepare_hash}-#{bin_routed_hash}-#{profile_hash}-#{osm_hash}" end diff --git a/features/support/hooks.rb b/features/support/hooks.rb index 30579c52b..41f9b3d79 100644 --- a/features/support/hooks.rb +++ b/features/support/hooks.rb @@ -1,3 +1,6 @@ + +STRESS_TIMEOUT = 300 + Before do |scenario| @scenario_title = scenario.title @scenario_time = Time.now.strftime("%Y-%m-%dT%H:%m:%SZ") @@ -7,12 +10,11 @@ Before do |scenario| set_grid_size DEFAULT_GRID_SIZE end -Around('@routing') do |scenario, block| - Timeout.timeout(10) do +Around('@stress') do |scenario, block| + Timeout.timeout(STRESS_TIMEOUT) do block.call end end After do - osrm_kill end diff --git a/features/support/launch.rb b/features/support/launch.rb index d125985ac..8df2f27f5 100644 --- a/features/support/launch.rb +++ b/features/support/launch.rb @@ -1,71 +1,83 @@ require 'socket' -require 'sys/proctable' +require 'open3' + +LAUNCH_TIMEOUT = 2 +SHUTDOWN_TIMEOUT = 2 +OSRM_ROUTED_LOG_FILE = 'osrm-routed.log' class OSRMLauncher def initialize &block Dir.chdir TEST_FOLDER do + begin + launch + yield + ensure + shutdown + end + end + end + + private + + def launch + Timeout.timeout(LAUNCH_TIMEOUT) do osrm_up - yield + wait_for_connection + end + rescue Timeout::Error + raise RoutedError.new "Launching osrm-routed timed out." + end + + def shutdown + Timeout.timeout(SHUTDOWN_TIMEOUT) do osrm_down end + rescue Timeout::Error + kill + raise RoutedError.new "Shutting down osrm-routed timed out." end -end - -def each_process name, &block - Sys::ProcTable.ps do |process| - if process.comm.strip == name.strip - yield process.pid.to_i, process.state.strip + + + def osrm_up? + if @pid + `ps -o state -p #{@pid}`.split[1].to_s =~ /^[DRST]/ + else + false end end -end -def osrm_up? - find_pid('osrm-routed') != nil -end + def osrm_up + return if osrm_up? + @pid = Process.spawn(['../osrm-routed',''],:out=>OSRM_ROUTED_LOG_FILE, :err=>OSRM_ROUTED_LOG_FILE) + end -def find_pid name - each_process(name) { |pid,state| return pid.to_i } - return nil -end + def osrm_down + if @pid + Process.kill 'TERM', @pid + wait_for_shutdown + end + end -def osrm_up - return if osrm_up? - pipe = IO.popen('../osrm-routed 1>>osrm-routed.log 2>>osrm-routed.log') - timeout = 5 - (timeout*10).times do - begin - socket = TCPSocket.new('localhost', 5000) - socket.puts 'ping' - rescue Errno::ECONNREFUSED + def kill + if @pid + Process.kill 'KILL', @pid + end + end + + def wait_for_connection + while true + begin + socket = TCPSocket.new('localhost', OSRM_PORT) + return + rescue Errno::ECONNREFUSED + sleep 0.1 + end + end + end + + def wait_for_shutdown + while osrm_up? sleep 0.1 end end - sleep 0.1 -end - -def osrm_down - each_process('osrm-routed') { |pid,state| Process.kill 'TERM', pid } - each_process('osrm-prepare') { |pid,state| Process.kill 'TERM', pid } - each_process('osrm-extract') { |pid,state| Process.kill 'TERM', pid } - wait_for_shutdown 'osrm-routed' - wait_for_shutdown 'osrm-prepare' - wait_for_shutdown 'osrm-extract' -end - -def osrm_kill - each_process('osrm-routed') { |pid,state| Process.kill 'KILL', pid } - each_process('osrm-prepare') { |pid,state| Process.kill 'KILL', pid } - each_process('osrm-extract') { |pid,state| Process.kill 'KILL', pid } - wait_for_shutdown 'osrm-routed' - wait_for_shutdown 'osrm-prepare' - wait_for_shutdown 'osrm-extract' -end - -def wait_for_shutdown name - timeout = 10 - (timeout*10).times do - return if find_pid(name) == nil - sleep 0.1 - end - raise "*** Could not terminate #{name}." end diff --git a/features/support/log.rb b/features/support/log.rb index f0c9c1938..7aed85029 100644 --- a/features/support/log.rb +++ b/features/support/log.rb @@ -14,7 +14,7 @@ def log_scenario_fail_info log "Failed scenario: #{@scenario_title}" log "Time: #{@scenario_time}" log "Fingerprint: #{@fingerprint}" - log "Profile: #{@speedprofile}" + log "Profile: #{@profile}" log log '```xml' #so output can be posted directly to github comment fields log osm_str.strip @@ -51,7 +51,7 @@ def log_preprocess_info log '```', :preprocess log '', :preprocess log "== Profile:", :preprocess - log @speedprofile, :preprocess + log @profile, :preprocess log '', :preprocess @has_logged_preprocess_info = true end diff --git a/features/support/osm_parser.rb b/features/support/osm_parser.rb new file mode 100644 index 000000000..ea4e9bd16 --- /dev/null +++ b/features/support/osm_parser.rb @@ -0,0 +1,23 @@ +require 'OSM/StreamParser' + +class OSMTestParserCallbacks < OSM::Callbacks + @@locations = nil + + def self.locations + if @@locations + @@locations + else + #parse the test file, so we can later reference nodes and ways by name in tests + @@locations = {} + file = 'test/data/test.osm' + callbacks = OSMTestParserCallbacks.new + parser = OSM::StreamParser.new(:filename => file, :callbacks => callbacks) + parser.parse + puts @@locations + end + end + + def node(node) + @@locations[node.name] = [node.lat,node.lon] + end +end \ No newline at end of file diff --git a/features/support/route.rb b/features/support/route.rb index 593ce8383..8be4e9219 100644 --- a/features/support/route.rb +++ b/features/support/route.rb @@ -1,19 +1,26 @@ require 'net/http' +HOST = "http://localhost:#{OSRM_PORT}" +REQUEST_TIMEOUT = 1 DESTINATION_REACHED = 15 #OSRM instruction code -def request_route a,b - @query = "http://localhost:5000/viaroute?loc=#{a}&loc=#{b}&output=json&instructions=true" - #log @query - uri = URI.parse @query - Net::HTTP.get_response uri +def request_path path + @query = path + uri = URI.parse "#{HOST}/#{path}" + Timeout.timeout(REQUEST_TIMEOUT) do + Net::HTTP.get_response uri + end rescue Errno::ECONNREFUSED => e raise "*** osrm-routed is not running." rescue Timeout::Error raise "*** osrm-routed did not respond." end +def request_route a,b + request_path "viaroute?loc=#{a}&loc=#{b}&output=json&instructions=true&alt=true" +end + def parse_response response if response.code == "200" && response.body.empty? == false json = JSON.parse response.body @@ -83,3 +90,27 @@ def bearing_list instructions map { |r| r=="" ? '""' : r }. join(',') end + +def turn_list instructions + types = { + 0 => :none, + 1 => :straight, + 2 => :slight_right, + 3 => :right, + 4 => :sharp_right, + 5 => :u_turn, + 6 => :sharp_left, + 7 => :left, + 8 => :slight_left, + 9 => :via, + 10 => :head, + 11 => :enter_roundabout, + 12 => :leave_roundabout, + 13 => :stay_roundabout, + 14 => :start_end_of_street, + 15 => :destination + } + instructions. + map { |r| types[r[0].to_i].to_s }. + join(',') +end diff --git a/features/testbot/bad.feature b/features/testbot/bad.feature index 91ba269cc..77a660776 100644 --- a/features/testbot/bad.feature +++ b/features/testbot/bad.feature @@ -2,7 +2,7 @@ Feature: Handle bad data in a graceful manner Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Empty dataset Given the node map @@ -12,7 +12,7 @@ Feature: Handle bad data in a graceful manner | nodes | When I preprocess data - Then preparing should return code 255 + Then "osrm-extract" should return code 255 Scenario: Only dead-end oneways Given the node map diff --git a/features/testbot/basic.feature b/features/testbot/basic.feature index 497c1f5d3..aabdcaa00 100644 --- a/features/testbot/basic.feature +++ b/features/testbot/basic.feature @@ -2,7 +2,7 @@ Feature: Basic Routing Background: - Given the speedprofile "testbot" + Given the profile "testbot" @smallest Scenario: A single way with two nodes diff --git a/features/testbot/bearing.feature b/features/testbot/bearing.feature index 69394390f..48ac5bd05 100644 --- a/features/testbot/bearing.feature +++ b/features/testbot/bearing.feature @@ -2,7 +2,7 @@ Feature: Compass bearing Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Bearing when going northwest Given the node map diff --git a/features/testbot/distance.feature b/features/testbot/distance.feature index 167364512..ac1f38364 100644 --- a/features/testbot/distance.feature +++ b/features/testbot/distance.feature @@ -2,7 +2,7 @@ Feature: Distance calculation Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: 100m distance Given a grid size of 100 meters diff --git a/features/testbot/ferry.feature b/features/testbot/ferry.feature index 35b18d04e..aadd083c0 100644 --- a/features/testbot/ferry.feature +++ b/features/testbot/ferry.feature @@ -2,7 +2,7 @@ Feature: Testbot - Handle ferry routes Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Testbot - Ferry duration, single node Given the node map @@ -38,7 +38,8 @@ Feature: Testbot - Handle ferry routes | from | to | route | time | | a | d | abcd | 3600s +-1 | | d | a | abcd | 3600s +-1 | - + + @todo Scenario: Bike - Ferry duration, individual parts Given the node map | x | y | | z | | | v | diff --git a/features/testbot/origin.feature b/features/testbot/origin.feature index 9f3979540..3fe6d97fc 100644 --- a/features/testbot/origin.feature +++ b/features/testbot/origin.feature @@ -2,7 +2,7 @@ Feature: Routing close to the [0,0] origin Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: East-west oneways close to the origin Given the node locations diff --git a/features/testbot/penalty.feature b/features/testbot/penalty.feature index f680eac4e..8b96050c9 100644 --- a/features/testbot/penalty.feature +++ b/features/testbot/penalty.feature @@ -3,7 +3,7 @@ Feature: Penalties Testbot uses a signal penalty of 7s. Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Traffic signals should incur a delay, without changing distance Given the node map diff --git a/features/testbot/planetary.feature b/features/testbot/planetary.feature index e8f832321..242ba8b6a 100644 --- a/features/testbot/planetary.feature +++ b/features/testbot/planetary.feature @@ -1,8 +1,7 @@ @routing @planetary Feature: Distance calculation -Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VDistance/ - Scenario: Longitudinal distances at equator + Scenario: Approximated Longitudinal distances at equator Given the node locations | node | lat | lon | | a | 0 | 80 | @@ -16,7 +15,7 @@ Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VD | from | to | route | distance | | a | b | ab | 8905559m ~0.1% | - Scenario: Longitudinal distances at latitude 45 + Scenario: Approximated Longitudinal distances at latitude 45 Given the node locations | node | lat | lon | | c | 45 | 80 | @@ -28,9 +27,9 @@ Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VD When I route I should get | from | to | route | distance | - | c | d | cd | 6028844m ~0.5% | + | c | d | cd | 6028844m ~4.5% | - Scenario: Longitudinal distances at latitude 80 + Scenario: Approximated Longitudinal distances at latitude 80 Given the node locations | node | lat | lon | | c | 80 | 80 | @@ -42,9 +41,9 @@ Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VD When I route I should get | from | to | route | distance | - | c | d | cd | 1431469m ~0.5% | + | c | d | cd | 1431469m ~9.5% | - Scenario: Latitudinal distances at longitude 0 + Scenario: Approximated Latitudinal distances at longitude 0 Given the node locations | node | lat | lon | | a | 80 | 0 | @@ -58,7 +57,7 @@ Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VD | from | to | route | distance | | a | b | ab | 8905559m ~0.1% | - Scenario: Latitudinal distances at longitude 45 + Scenario: Approximated Latitudinal distances at longitude 45 Given the node locations | node | lat | lon | | a | 80 | 45 | @@ -72,7 +71,7 @@ Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VD | from | to | route | distance | | a | b | ab | 8905559m ~0.1% | - Scenario: Latitudinal distances at longitude 80 + Scenario: Approximated Latitudinal distances at longitude 80 Given the node locations | node | lat | lon | | a | 80 | 80 | diff --git a/features/testbot/snap.feature b/features/testbot/snap.feature index c359cc4bf..ebed9f829 100644 --- a/features/testbot/snap.feature +++ b/features/testbot/snap.feature @@ -2,7 +2,7 @@ Feature: Snap start/end point to the nearest way Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Snap to nearest protruding oneway Given the node map @@ -98,7 +98,6 @@ Feature: Snap start/end point to the nearest way | b | x | xb | | c | x | xc | - @xx Scenario: Find edges within 1km, but not 10km Given a grid size of 1000 meters Given the node map @@ -152,5 +151,4 @@ Feature: Snap start/end point to the nearest way | x | m | | | x | n | | | x | o | | - | x | p | | - + | x | p | | \ No newline at end of file diff --git a/features/testbot/time.feature b/features/testbot/time.feature index 0a19a3a37..b10544f8f 100644 --- a/features/testbot/time.feature +++ b/features/testbot/time.feature @@ -6,7 +6,7 @@ Secondary road: 18km/h = 18000m/3600s = 100m/20s Tertiary road: 12km/h = 12000m/3600s = 100m/30s Background: Use specific speeds - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Basic travel time, 10m scale Given a grid size of 10 meters diff --git a/features/testbot/turns.feature b/features/testbot/turns.feature new file mode 100644 index 000000000..34a0c9199 --- /dev/null +++ b/features/testbot/turns.feature @@ -0,0 +1,115 @@ +@routing @turns +Feature: Turn directions/codes + + Background: + Given the profile "testbot" + + Scenario: Turn directions + Given the node map + | o | p | a | b | c | + | n | | | | d | + | m | | x | | e | + | l | | | | f | + | k | j | i | h | g | + + And the ways + | nodes | + | xa | + | xb | + | xc | + | xd | + | xe | + | xf | + | xg | + | xh | + | xi | + | xj | + | xk | + | xl | + | xm | + | xn | + | xo | + | xp | + + When I route I should get + | from | to | route | turns | + | i | k | xi,xk | head,sharp_left,destination | + | i | m | xi,xm | head,left,destination | + | i | o | xi,xo | head,slight_left,destination | + | i | a | xi,xa | head,straight,destination | + | i | c | xi,xc | head,slight_right,destination | + | i | e | xi,xe | head,right,destination | + | i | g | xi,xg | head,sharp_right,destination | + + | k | m | xk,xm | head,sharp_left,destination | + | k | o | xk,xo | head,left,destination | + | k | a | xk,xa | head,slight_left,destination | + | k | c | xk,xc | head,straight,destination | + | k | e | xk,xe | head,slight_right,destination | + | k | g | xk,xg | head,right,destination | + | k | i | xk,xi | head,sharp_right,destination | + + | m | o | xm,xo | head,sharp_left,destination | + | m | a | xm,xa | head,left,destination | + | m | c | xm,xc | head,slight_left,destination | + | m | e | xm,xe | head,straight,destination | + | m | g | xm,xg | head,slight_right,destination | + | m | i | xm,xi | head,right,destination | + | m | k | xm,xk | head,sharp_right,destination | + + | o | a | xo,xa | head,sharp_left,destination | + | o | c | xo,xc | head,left,destination | + | o | e | xo,xe | head,slight_left,destination | + | o | g | xo,xg | head,straight,destination | + | o | i | xo,xi | head,slight_right,destination | + | o | k | xo,xk | head,right,destination | + | o | m | xo,xm | head,sharp_right,destination | + + | a | c | xa,xc | head,sharp_left,destination | + | a | e | xa,xe | head,left,destination | + | a | g | xa,xg | head,slight_left,destination | + | a | i | xa,xi | head,straight,destination | + | a | k | xa,xk | head,slight_right,destination | + | a | m | xa,xm | head,right,destination | + | a | o | xa,xo | head,sharp_right,destination | + + | c | e | xc,xe | head,sharp_left,destination | + | c | g | xc,xg | head,left,destination | + | c | i | xc,xi | head,slight_left,destination | + | c | k | xc,xk | head,straight,destination | + | c | m | xc,xm | head,slight_right,destination | + | c | o | xc,xo | head,right,destination | + | c | a | xc,xa | head,sharp_right,destination | + + | e | g | xe,xg | head,sharp_left,destination | + | e | i | xe,xi | head,left,destination | + | e | k | xe,xk | head,slight_left,destination | + | e | m | xe,xm | head,straight,destination | + | e | o | xe,xo | head,slight_right,destination | + | e | a | xe,xa | head,right,destination | + | e | c | xe,xc | head,sharp_right,destination | + + | g | i | xg,xi | head,sharp_left,destination | + | g | k | xg,xk | head,left,destination | + | g | m | xg,xm | head,slight_left,destination | + | g | o | xg,xo | head,straight,destination | + | g | a | xg,xa | head,slight_right,destination | + | g | c | xg,xc | head,right,destination | + | g | e | xg,xe | head,sharp_right,destination | + + Scenario: Skadestuevej, København + https://github.com/DennisOSRM/Project-OSRM/issues/532 + Given the node locations + | node | lat | lon | + | a | 55.68679 | 12.52360 | + | b | 55.68745 | 12.52407 | + | c | 55.68720 | 12.52509 | + + And the ways + | nodes | + | ab | + | bc | + + When I route I should get + | from | to | route | turns | + | a | c | ab,bc | head,right,destination | diff --git a/features/testbot/utf.feature b/features/testbot/utf.feature index 13d0c6fde..784bd4c80 100644 --- a/features/testbot/utf.feature +++ b/features/testbot/utf.feature @@ -2,7 +2,7 @@ Feature: Handling of UTF characters Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Streetnames with UTF characters Given the node map diff --git a/features/testbot/weight.feature b/features/testbot/weight.feature index b884a37bf..0e3551ff2 100644 --- a/features/testbot/weight.feature +++ b/features/testbot/weight.feature @@ -2,7 +2,7 @@ Feature: Choosing route based on length, speed, etc Background: - Given the speedprofile "testbot" + Given the profile "testbot" Scenario: Pick the geometrically shortest route, way types being equal Given the node map diff --git a/features/timestamp/timestamp.feature b/features/timestamp/timestamp.feature new file mode 100644 index 000000000..7886bad7a --- /dev/null +++ b/features/timestamp/timestamp.feature @@ -0,0 +1,12 @@ +@timestamp +Feature: Timestamp + + Scenario: Request timestamp + Given the node map + | a | b | + And the ways + | nodes | + | ab | + When I request /timestamp + Then I should get a valid timestamp + diff --git a/profiles/bicycle.lua b/profiles/bicycle.lua index d2372afe6..c27771b14 100644 --- a/profiles/bicycle.lua +++ b/profiles/bicycle.lua @@ -1,5 +1,5 @@ -- Begin of globals -barrier_whitelist = { [""] = true, ["bollard"] = true, ["entrance"] = true, ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true} +barrier_whitelist = { [""] = true, ["cycle_barrier"] = true, ["bollard"] = true, ["entrance"] = true, ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true} access_tag_whitelist = { ["yes"] = true, ["permissive"] = true, ["designated"] = true } access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestery"] = true } access_tag_restricted = { ["destination"] = true, ["delivery"] = true } @@ -121,6 +121,7 @@ function way_function (way, numberOfNodesInWay) local junction = way.tags:Find("junction") local route = way.tags:Find("route") local railway = way.tags:Find("railway") + local public_transport = way.tags:Find("public_transport") local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") ) local man_made = way.tags:Find("man_made") local barrier = way.tags:Find("barrier") @@ -135,12 +136,14 @@ function way_function (way, numberOfNodesInWay) local amenity = way.tags:Find("amenity") local access = find_access_tag(way) - -- only route on things with highway tag set (not buildings, boundaries, etc) + -- initial routability check, filters out buildings, boundaries, etc if (not highway or highway == '') and (not route or route == '') and (not railway or railway=='') and - (not amenity or amenity=='') then - return 0 + (not amenity or amenity=='') and + (not public_transport or public_transport=='') + then + return 0 end -- access @@ -168,8 +171,11 @@ function way_function (way, numberOfNodesInWay) way.speed = route_speeds[route] end elseif railway and platform_speeds[railway] then - -- railway platforms + -- railway platforms (old tagging scheme) way.speed = platform_speeds[railway] + elseif platform_speeds[public_transport] then + -- public_transport platforms (new tagging platform) + way.speed = platform_speeds[public_transport] elseif railway and railway_speeds[railway] then -- railways if access and access_tag_whitelist[access] then diff --git a/profiles/car.lua b/profiles/car.lua index b2291c1b0..1e2d6c379 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -2,7 +2,7 @@ barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true} access_tag_whitelist = { ["yes"] = true, ["motorcar"] = true, ["motor_vehicle"] = true, ["vehicle"] = true, ["permissive"] = true, ["designated"] = true } -access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestery"] = true } +access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true } access_tag_restricted = { ["destination"] = true, ["delivery"] = true } access_tags = { "motorcar", "motor_vehicle", "vehicle" } access_tags_hierachy = { "motorcar", "motor_vehicle", "vehicle", "access" } diff --git a/routed.cpp b/routed.cpp index 87119eaa1..bdf30c652 100644 --- a/routed.cpp +++ b/routed.cpp @@ -82,7 +82,7 @@ int main (int argc, char * argv[0]) { //} try { - std::cout << "[server] starting up engines, saved at " << __TIMESTAMP__ << std::endl; + std::cout << std::endl << "[server] starting up engines, saved at " << __TIMESTAMP__ << std::endl; #ifndef _WIN32 int sig = 0; @@ -135,11 +135,14 @@ int main (int argc, char * argv[0]) { s->Run(); #endif - std::cout << std::endl << "[server] shutting down" << std::endl; + std::cout << "[server] initiating shutdown" << std::endl; s->Stop(); + std::cout << "[server] stopping threads" << std::endl; t.join(); + std::cout << "[server] freeing objects" << std::endl; delete s; delete objects; + std::cout << "[server] shutdown completed" << std::endl; } catch (std::exception& e) { std::cerr << "[fatal error] exception: " << e.what() << std::endl; }