Merge branch 'develop'
This commit is contained in:
commit
6574436c33
@ -41,7 +41,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#include "../DataStructures/NodeCoords.h"
|
#include "../DataStructures/NodeCoords.h"
|
||||||
#include "../DataStructures/Percent.h"
|
#include "../DataStructures/Percent.h"
|
||||||
#include "../DataStructures/Restriction.h"
|
#include "../DataStructures/Restriction.h"
|
||||||
|
#include "../DataStructures/TurnInstructions.h"
|
||||||
|
|
||||||
// Strongly connected components using Tarjan's Algorithm
|
// Strongly connected components using Tarjan's Algorithm
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ private:
|
|||||||
unsigned nameID;
|
unsigned nameID;
|
||||||
bool forward;
|
bool forward;
|
||||||
bool backward;
|
bool backward;
|
||||||
short turnInstruction;
|
TurnInstruction turnInstruction;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
|
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
NodeID via;
|
NodeID via;
|
||||||
unsigned nameID;
|
unsigned nameID;
|
||||||
int distance;
|
int distance;
|
||||||
short turnInstruction;
|
TurnInstruction turnInstruction;
|
||||||
bool shortcut:1;
|
bool shortcut:1;
|
||||||
bool forward:1;
|
bool forward:1;
|
||||||
bool backward:1;
|
bool backward:1;
|
||||||
|
@ -122,8 +122,7 @@ public:
|
|||||||
assert( newEdge.data.distance > 0 );
|
assert( newEdge.data.distance > 0 );
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) {
|
if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) {
|
||||||
std::cout << "Edge Weight too large -> May lead to invalid CH" << std::endl;
|
WARN("Edge weight large -> " << newEdge.data.distance);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
edges.push_back( newEdge );
|
edges.push_back( newEdge );
|
||||||
|
@ -95,8 +95,6 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
|
|||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) {
|
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) {
|
||||||
GUARANTEE(0 == outputEdgeList.size(), "Vector passed to EdgeBasedGraphFactory::GetEdgeBasedEdges(..) is not empty");
|
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);
|
edgeBasedEdges.swap(outputEdgeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +278,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
|
|||||||
if(_trafficLights.find(v) != _trafficLights.end()) {
|
if(_trafficLights.find(v) != _trafficLights.end()) {
|
||||||
distance += speedProfile.trafficSignalPenalty;
|
distance += speedProfile.trafficSignalPenalty;
|
||||||
}
|
}
|
||||||
short turnInstruction = AnalyzeTurn(u, v, w);
|
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w);
|
||||||
if(turnInstruction == TurnInstructions.UTurn)
|
if(turnInstruction == TurnInstructions.UTurn)
|
||||||
distance += speedProfile.uTurnPenalty;
|
distance += speedProfile.uTurnPenalty;
|
||||||
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
|
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
|
||||||
@ -297,7 +295,6 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
|
|||||||
}
|
}
|
||||||
OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction);
|
OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction);
|
||||||
EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false );
|
EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false );
|
||||||
assert(u != w);
|
|
||||||
originalEdgeData.push_back(oed);
|
originalEdgeData.push_back(oed);
|
||||||
if(originalEdgeData.size() > 100000) {
|
if(originalEdgeData.size() > 100000) {
|
||||||
originalEdgeDataOutFile.write((char*)&(originalEdgeData[0]), originalEdgeData.size()*sizeof(OriginalEdgeData));
|
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");
|
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) {
|
if(u == w) {
|
||||||
return TurnInstructions.UTurn;
|
return TurnInstructions.UTurn;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ private:
|
|||||||
unsigned nameID;
|
unsigned nameID;
|
||||||
bool forward;
|
bool forward;
|
||||||
bool backward;
|
bool backward;
|
||||||
short turnInstruction;
|
TurnInstruction turnInstruction;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
|
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
|
||||||
@ -138,7 +138,7 @@ public:
|
|||||||
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
|
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
|
||||||
void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes);
|
void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes);
|
||||||
void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
|
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;
|
unsigned GetNumberOfNodes() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,23 +57,7 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat
|
|||||||
assert(lon1 != INT_MIN);
|
assert(lon1 != INT_MIN);
|
||||||
assert(lat2 != INT_MIN);
|
assert(lat2 != INT_MIN);
|
||||||
assert(lon2 != 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;
|
double RAD = 0.017453292519943295769236907684886;
|
||||||
//std::cout << "RAD: " << RAD << std::endl;
|
|
||||||
//main code inside the class
|
|
||||||
double lt1 = lat1/100000.;
|
double lt1 = lat1/100000.;
|
||||||
double ln1 = lon1/100000.;
|
double ln1 = lon1/100000.;
|
||||||
double lt2 = lat2/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
|
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;
|
double distance=earth*cHarv;
|
||||||
return distance;
|
return distance;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) {
|
inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) {
|
||||||
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
|
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_ */
|
#endif /* COORDINATE_H_ */
|
||||||
|
@ -85,7 +85,7 @@ public:
|
|||||||
return origEdgeData.at(id).nameID;
|
return origEdgeData.at(id).nameID;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline short getTurnInstructionFromEdgeID(const unsigned id) const {
|
inline TurnInstruction getTurnInstructionFromEdgeID(const unsigned id) const {
|
||||||
return origEdgeData.at(id).turnInstruction;
|
return origEdgeData.at(id).turnInstruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,16 +23,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#ifndef QUERYEDGE_H_
|
#ifndef QUERYEDGE_H_
|
||||||
#define QUERYEDGE_H_
|
#define QUERYEDGE_H_
|
||||||
|
|
||||||
#include <climits>
|
#include "TurnInstructions.h"
|
||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
struct OriginalEdgeData{
|
struct OriginalEdgeData{
|
||||||
explicit OriginalEdgeData(NodeID v, unsigned n, short t) : viaNode(v), nameID(n), turnInstruction(t) {}
|
explicit OriginalEdgeData(NodeID v, unsigned n, TurnInstruction t) : viaNode(v), nameID(n), turnInstruction(t) {}
|
||||||
OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(SHRT_MAX) {}
|
OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {}
|
||||||
NodeID viaNode;
|
NodeID viaNode;
|
||||||
unsigned nameID;
|
unsigned nameID;
|
||||||
short turnInstruction;
|
TurnInstruction turnInstruction;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryEdge {
|
struct QueryEdge {
|
||||||
|
@ -23,17 +23,19 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
|
||||||
|
#include "TurnInstructions.h"
|
||||||
|
|
||||||
struct SegmentInformation {
|
struct SegmentInformation {
|
||||||
_Coordinate location;
|
_Coordinate location;
|
||||||
NodeID nameID;
|
NodeID nameID;
|
||||||
double length;
|
double length;
|
||||||
unsigned duration;
|
unsigned duration;
|
||||||
double bearing;
|
double bearing;
|
||||||
short turnInstruction;
|
TurnInstruction turnInstruction;
|
||||||
bool necessary;
|
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) {}
|
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) {}
|
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,28 +23,30 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
typedef unsigned char TurnInstruction;
|
||||||
|
|
||||||
//This is a hack until c++0x is available enough to use scoped enums
|
//This is a hack until c++0x is available enough to use scoped enums
|
||||||
struct TurnInstructionsClass {
|
struct TurnInstructionsClass {
|
||||||
|
|
||||||
const static short NoTurn = 0; //Give no instruction at all
|
const static TurnInstruction NoTurn = 0; //Give no instruction at all
|
||||||
const static short GoStraight = 1; //Tell user to go straight!
|
const static TurnInstruction GoStraight = 1; //Tell user to go straight!
|
||||||
const static short TurnSlightRight = 2;
|
const static TurnInstruction TurnSlightRight = 2;
|
||||||
const static short TurnRight = 3;
|
const static TurnInstruction TurnRight = 3;
|
||||||
const static short TurnSharpRight = 4;
|
const static TurnInstruction TurnSharpRight = 4;
|
||||||
const static short UTurn = 5;
|
const static TurnInstruction UTurn = 5;
|
||||||
const static short TurnSharpLeft = 6;
|
const static TurnInstruction TurnSharpLeft = 6;
|
||||||
const static short TurnLeft = 7;
|
const static TurnInstruction TurnLeft = 7;
|
||||||
const static short TurnSlightLeft = 8;
|
const static TurnInstruction TurnSlightLeft = 8;
|
||||||
const static short ReachViaPoint = 9;
|
const static TurnInstruction ReachViaPoint = 9;
|
||||||
const static short HeadOn = 10;
|
const static TurnInstruction HeadOn = 10;
|
||||||
const static short EnterRoundAbout = 11;
|
const static TurnInstruction EnterRoundAbout = 11;
|
||||||
const static short LeaveRoundAbout = 12;
|
const static TurnInstruction LeaveRoundAbout = 12;
|
||||||
const static short StayOnRoundAbout = 13;
|
const static TurnInstruction StayOnRoundAbout = 13;
|
||||||
const static short StartAtEndOfStreet = 14;
|
const static TurnInstruction StartAtEndOfStreet = 14;
|
||||||
const static short ReachedYourDestination = 15;
|
const static TurnInstruction ReachedYourDestination = 15;
|
||||||
|
|
||||||
const static short AccessRestrictionFlag = (1<<14);
|
const static TurnInstruction AccessRestrictionFlag = 128;
|
||||||
const static short InverseAccessRestrictionFlag = ~(1<<14);
|
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
|
||||||
|
|
||||||
@ -84,7 +86,7 @@ struct TurnInstructionsClass {
|
|||||||
// Ordinals[11] = "one of the too many";
|
// 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) {
|
if(angle >= 23 && angle < 67) {
|
||||||
return TurnSharpRight;
|
return TurnSharpRight;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe
|
|||||||
/** starts at index 1 */
|
/** starts at index 1 */
|
||||||
pathDescription[0].length = 0;
|
pathDescription[0].length = 0;
|
||||||
for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
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;
|
double lengthOfSegment = 0;
|
||||||
@ -111,32 +111,37 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe
|
|||||||
becomes:
|
becomes:
|
||||||
10. Turn left on B 36 for 35 km
|
10. Turn left on B 36 for 35 km
|
||||||
*/
|
*/
|
||||||
unsigned lastTurn = 0;
|
//TODO: rework to check only end and start of string.
|
||||||
for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
// stl string is way to expensive
|
||||||
string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].nameID);
|
|
||||||
if(TurnInstructionsClass::GoStraight == pathDescription[i].turnInstruction) {
|
// unsigned lastTurn = 0;
|
||||||
if(std::string::npos != string0.find(string1+";") ||
|
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
||||||
std::string::npos != string0.find(";"+string1) ||
|
// string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].nameID);
|
||||||
std::string::npos != string0.find(string1+" ;") ||
|
// if(TurnInstructionsClass::GoStraight == pathDescription[i].turnInstruction) {
|
||||||
std::string::npos != string0.find("; "+string1)){
|
// 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);
|
// INFO("->next correct: " << string0 << " contains " << string1);
|
||||||
for(; lastTurn != i; ++lastTurn)
|
// for(; lastTurn != i; ++lastTurn)
|
||||||
pathDescription[lastTurn].nameID = pathDescription[i].nameID;
|
// pathDescription[lastTurn].nameID = pathDescription[i].nameID;
|
||||||
pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
|
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
|
||||||
} else if(std::string::npos != string1.find(string0+";") ||
|
// } 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+" ;")||
|
// || std::string::npos != string1.find(string0+" ;")
|
||||||
std::string::npos != string1.find("; "+string0)) {
|
// || std::string::npos != string1.find("; "+string0)
|
||||||
|
// ){
|
||||||
// INFO("->prev correct: " << string1 << " contains " << string0);
|
// INFO("->prev correct: " << string1 << " contains " << string0);
|
||||||
pathDescription[i].nameID = pathDescription[i-1].nameID;
|
// pathDescription[i].nameID = pathDescription[i-1].nameID;
|
||||||
pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
|
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
|
// if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
|
||||||
lastTurn = i;
|
// lastTurn = i;
|
||||||
}
|
// }
|
||||||
string0 = string1;
|
// string0 = string1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
for(unsigned i = 1; i < pathDescription.size(); ++i) {
|
||||||
|
@ -69,7 +69,9 @@ public:
|
|||||||
void SetConfig(const _DescriptorConfig & c) { config = c; }
|
void SetConfig(const _DescriptorConfig & c) { config = c; }
|
||||||
|
|
||||||
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) {
|
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) {
|
||||||
|
|
||||||
WriteHeaderToOutput(reply.content);
|
WriteHeaderToOutput(reply.content);
|
||||||
|
|
||||||
if(rawRoute.lengthOfShortestPath != INT_MAX) {
|
if(rawRoute.lengthOfShortestPath != INT_MAX) {
|
||||||
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
|
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
|
||||||
reply.content += "0,"
|
reply.content += "0,"
|
||||||
@ -102,7 +104,7 @@ public:
|
|||||||
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine, shortestSegments);
|
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine, shortestSegments);
|
||||||
} else {
|
} else {
|
||||||
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
||||||
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||||
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +157,7 @@ public:
|
|||||||
BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine, alternativeSegments);
|
BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine, alternativeSegments);
|
||||||
} else {
|
} else {
|
||||||
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) {
|
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) {
|
||||||
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||||
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,7 +244,6 @@ public:
|
|||||||
reply.content += "},";
|
reply.content += "},";
|
||||||
reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
|
reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
|
||||||
reply.content += "}";
|
reply.content += "}";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetRouteNames(std::vector<Segment> & shortestSegments, std::vector<Segment> & alternativeSegments, SearchEngineT &sEngine, RouteNames & routeNames) {
|
void GetRouteNames(std::vector<Segment> & shortestSegments, std::vector<Segment> & alternativeSegments, SearchEngineT &sEngine, RouteNames & routeNames) {
|
||||||
@ -312,7 +313,7 @@ public:
|
|||||||
std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction;
|
std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction;
|
||||||
//Fetch data from Factory and generate a string from it.
|
//Fetch data from Factory and generate a string from it.
|
||||||
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
||||||
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||||
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
|
||||||
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
|
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
|
||||||
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
|
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
|
||||||
@ -384,7 +385,6 @@ public:
|
|||||||
reply.content += "0.0";
|
reply.content += "0.0";
|
||||||
reply.content += "]";
|
reply.content += "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -24,8 +24,6 @@ extern "C" {
|
|||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
|
||||||
|
|
||||||
#include "ScriptingEnvironment.h"
|
#include "ScriptingEnvironment.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
#include "../Util/OpenMPWrapper.h"
|
#include "../Util/OpenMPWrapper.h"
|
||||||
|
@ -36,7 +36,7 @@ struct RouteParameters {
|
|||||||
bool geometry;
|
bool geometry;
|
||||||
bool compression;
|
bool compression;
|
||||||
bool deprecatedAPI;
|
bool deprecatedAPI;
|
||||||
int checkSum;
|
unsigned checkSum;
|
||||||
std::string service;
|
std::string service;
|
||||||
std::string outputFormat;
|
std::string outputFormat;
|
||||||
std::string jsonpParameter;
|
std::string jsonpParameter;
|
||||||
@ -58,7 +58,7 @@ struct RouteParameters {
|
|||||||
deprecatedAPI = true;
|
deprecatedAPI = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setChecksum(const int c) {
|
void setChecksum(const unsigned c) {
|
||||||
checkSum = c;
|
checkSum = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ public:
|
|||||||
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
|
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
|
||||||
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
|
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
std::string JSONParameter;
|
|
||||||
|
|
||||||
//json
|
//json
|
||||||
if("" != routeParameters.jsonpParameter) {
|
if("" != routeParameters.jsonpParameter) {
|
||||||
@ -53,7 +52,7 @@ public:
|
|||||||
reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON timestamp (v0.3)\"";
|
reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON timestamp (v0.3)\"";
|
||||||
reply.content += ("}");
|
reply.content += ("}");
|
||||||
reply.headers.resize(3);
|
reply.headers.resize(3);
|
||||||
if("" != JSONParameter) {
|
if("" != routeParameters.jsonpParameter) {
|
||||||
reply.content += ")";
|
reply.content += ")";
|
||||||
reply.headers[1].name = "Content-Type";
|
reply.headers[1].name = "Content-Type";
|
||||||
reply.headers[1].value = "text/javascript";
|
reply.headers[1].value = "text/javascript";
|
||||||
|
8
Rakefile
8
Rakefile
@ -6,6 +6,7 @@ require 'sys/proctable'
|
|||||||
|
|
||||||
DATA_FOLDER = 'sandbox'
|
DATA_FOLDER = 'sandbox'
|
||||||
PROFILE = 'bicycle'
|
PROFILE = 'bicycle'
|
||||||
|
OSRM_PORT = 5000
|
||||||
|
|
||||||
Cucumber::Rake::Task.new do |t|
|
Cucumber::Rake::Task.new do |t|
|
||||||
t.cucumber_opts = %w{--format pretty}
|
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
|
def each_process name, &block
|
||||||
Sys::ProcTable.ps do |process|
|
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
|
yield process.pid.to_i, process.state.strip
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -60,7 +61,7 @@ def write_server_ini osm_file
|
|||||||
s=<<-EOF
|
s=<<-EOF
|
||||||
Threads = 1
|
Threads = 1
|
||||||
IP = 0.0.0.0
|
IP = 0.0.0.0
|
||||||
Port = 5000
|
Port = #{OSRM_PORT}
|
||||||
|
|
||||||
hsgrData=#{osm_file}.osrm.hsgr
|
hsgrData=#{osm_file}.osrm.hsgr
|
||||||
nodesData=#{osm_file}.osrm.nodes
|
nodesData=#{osm_file}.osrm.nodes
|
||||||
@ -68,6 +69,7 @@ def write_server_ini osm_file
|
|||||||
ramIndex=#{osm_file}.osrm.ramIndex
|
ramIndex=#{osm_file}.osrm.ramIndex
|
||||||
fileIndex=#{osm_file}.osrm.fileIndex
|
fileIndex=#{osm_file}.osrm.fileIndex
|
||||||
namesData=#{osm_file}.osrm.names
|
namesData=#{osm_file}.osrm.names
|
||||||
|
timestamp=#{osm_file}.osrm.timestamp
|
||||||
EOF
|
EOF
|
||||||
File.open( 'server.ini', 'w') {|f| f.write( s ) }
|
File.open( 'server.ini', 'w') {|f| f.write( s ) }
|
||||||
end
|
end
|
||||||
@ -150,7 +152,7 @@ task :up => :setup do
|
|||||||
timeout = 5
|
timeout = 5
|
||||||
(timeout*10).times do
|
(timeout*10).times do
|
||||||
begin
|
begin
|
||||||
socket = TCPSocket.new('localhost', 5000)
|
socket = TCPSocket.new('localhost', OSRM_PORT)
|
||||||
socket.puts 'ping'
|
socket.puts 'ping'
|
||||||
rescue Errno::ECONNREFUSED
|
rescue Errno::ECONNREFUSED
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
std::vector<NodeID> alternativePath;
|
std::vector<NodeID> alternativePath;
|
||||||
std::vector<NodeID> viaNodeCandidates;
|
std::vector<NodeID> viaNodeCandidates;
|
||||||
std::deque <NodeID> packedShortestPath;
|
std::vector <NodeID> packedShortestPath;
|
||||||
std::vector<PreselectedNode> nodesThatPassPreselection;
|
std::vector<PreselectedNode> nodesThatPassPreselection;
|
||||||
|
|
||||||
HeapPtr & forwardHeap = super::_queryData.forwardHeap;
|
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,
|
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) {
|
const NodeID s_v_middle, const NodeID v_t_middle, std::vector<_PathData> & unpackedPath) {
|
||||||
//unpack [s,v)
|
//unpack [s,v)
|
||||||
std::deque<NodeID> packed_s_v_path, packed_v_t_path;
|
std::vector<NodeID> packed_s_v_path, packed_v_t_path;
|
||||||
super::RetrievePackedPathFromHeap(_forwardHeap1, _backwardHeap2, s_v_middle, packed_s_v_path);
|
super::RetrievePackedPathFromHeap(_forwardHeap1, _backwardHeap2, s_v_middle, packed_s_v_path);
|
||||||
packed_s_v_path.resize(packed_s_v_path.size()-1);
|
packed_s_v_path.resize(packed_s_v_path.size()-1);
|
||||||
//unpack [v,t]
|
//unpack [v,t]
|
||||||
@ -171,7 +171,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void computeLengthAndSharingOfViaPath(const PreselectedNode& node, int *lengthOfViaPath, int *sharingOfViaPath,
|
inline void computeLengthAndSharingOfViaPath(const PreselectedNode& node, int *lengthOfViaPath, int *sharingOfViaPath,
|
||||||
const int offset, const std::deque<NodeID> & packedShortestPath) {
|
const int offset, const std::vector<NodeID> & packedShortestPath) {
|
||||||
//compute and unpack <s,..,v> and <v,..,t> by exploring search spaces from v and intersecting against queues
|
//compute and unpack <s,..,v> and <v,..,t> by exploring search spaces from v and intersecting against queues
|
||||||
//only half-searches have to be done at this stage
|
//only half-searches have to be done at this stage
|
||||||
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
|
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
|
||||||
@ -181,8 +181,8 @@ private:
|
|||||||
HeapPtr & newForwardHeap = super::_queryData.forwardHeap2;
|
HeapPtr & newForwardHeap = super::_queryData.forwardHeap2;
|
||||||
HeapPtr & newBackwardHeap = super::_queryData.backwardHeap2;
|
HeapPtr & newBackwardHeap = super::_queryData.backwardHeap2;
|
||||||
|
|
||||||
std::deque < NodeID > packed_s_v_path;
|
std::vector < NodeID > packed_s_v_path;
|
||||||
std::deque < NodeID > packed_v_t_path;
|
std::vector < NodeID > packed_v_t_path;
|
||||||
|
|
||||||
std::vector<NodeID> partiallyUnpackedShortestPath;
|
std::vector<NodeID> partiallyUnpackedShortestPath;
|
||||||
std::vector<NodeID> partiallyUnpackedViaPath;
|
std::vector<NodeID> partiallyUnpackedViaPath;
|
||||||
@ -258,8 +258,8 @@ private:
|
|||||||
//finished partial unpacking spree! Amount of sharing is stored to appropriate poiner variable
|
//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<NodeID> & packedShortestPath) {
|
inline int approximateAmountOfSharing(const NodeID middleNodeIDOfAlternativePath, HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const std::vector<NodeID> & packedShortestPath) {
|
||||||
std::deque<NodeID> packedAlternativePath;
|
std::vector<NodeID> packedAlternativePath;
|
||||||
super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfAlternativePath, packedAlternativePath);
|
super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfAlternativePath, packedAlternativePath);
|
||||||
|
|
||||||
if(packedShortestPath.size() < 2 || packedAlternativePath.size() < 2)
|
if(packedShortestPath.size() < 2 || packedAlternativePath.size() < 2)
|
||||||
@ -336,8 +336,8 @@ private:
|
|||||||
|
|
||||||
//conduct T-Test
|
//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) {
|
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::vector < NodeID > packed_s_v_path;
|
||||||
std::deque < NodeID > packed_v_t_path;
|
std::vector < NodeID > packed_v_t_path;
|
||||||
|
|
||||||
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
|
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
|
||||||
*s_v_middle = UINT_MAX;
|
*s_v_middle = UINT_MAX;
|
||||||
|
@ -104,7 +104,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void UnpackPath(std::deque<NodeID> & packedPath, std::vector<_PathData> & unpackedPath) const {
|
inline void UnpackPath(std::vector<NodeID> & packedPath, std::vector<_PathData> & unpackedPath) const {
|
||||||
|
|
||||||
const unsigned sizeOfPackedPath = packedPath.size();
|
const unsigned sizeOfPackedPath = packedPath.size();
|
||||||
std::stack<std::pair<NodeID, NodeID> > recursionStack;
|
std::stack<std::pair<NodeID, NodeID> > recursionStack;
|
||||||
@ -204,13 +204,15 @@ public:
|
|||||||
unpackedPath.push_back(t);
|
unpackedPath.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RetrievePackedPathFromHeap(const typename QueryDataT::HeapPtr & _fHeap, const typename QueryDataT::HeapPtr & _bHeap, const NodeID middle, std::deque<NodeID>& packedPath) {
|
inline void RetrievePackedPathFromHeap(const typename QueryDataT::HeapPtr & _fHeap, const typename QueryDataT::HeapPtr & _bHeap, const NodeID middle, std::vector<NodeID>& packedPath) {
|
||||||
NodeID pathNode = middle;
|
NodeID pathNode = middle;
|
||||||
while(pathNode != _fHeap->GetData(pathNode).parent) {
|
while(pathNode != _fHeap->GetData(pathNode).parent) {
|
||||||
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);
|
packedPath.push_back(middle);
|
||||||
pathNode = middle;
|
pathNode = middle;
|
||||||
while (pathNode != _bHeap->GetData(pathNode).parent){
|
while (pathNode != _bHeap->GetData(pathNode).parent){
|
||||||
|
@ -47,8 +47,8 @@ public:
|
|||||||
bool searchFrom2ndStartNode(true);
|
bool searchFrom2ndStartNode(true);
|
||||||
NodeID middle1 = ( NodeID ) UINT_MAX;
|
NodeID middle1 = ( NodeID ) UINT_MAX;
|
||||||
NodeID middle2 = ( NodeID ) UINT_MAX;
|
NodeID middle2 = ( NodeID ) UINT_MAX;
|
||||||
std::deque<NodeID> packedPath1;
|
std::vector<NodeID> packedPath1;
|
||||||
std::deque<NodeID> packedPath2;
|
std::vector<NodeID> packedPath2;
|
||||||
|
|
||||||
typename QueryDataT::HeapPtr & forwardHeap = super::_queryData.forwardHeap;
|
typename QueryDataT::HeapPtr & forwardHeap = super::_queryData.forwardHeap;
|
||||||
typename QueryDataT::HeapPtr & backwardHeap = super::_queryData.backwardHeap;
|
typename QueryDataT::HeapPtr & backwardHeap = super::_queryData.backwardHeap;
|
||||||
@ -141,8 +141,8 @@ public:
|
|||||||
// INFO("middle1: " << middle1);
|
// INFO("middle1: " << middle1);
|
||||||
|
|
||||||
//Unpack paths if they exist
|
//Unpack paths if they exist
|
||||||
std::deque<NodeID> temporaryPackedPath1;
|
std::vector<NodeID> temporaryPackedPath1;
|
||||||
std::deque<NodeID> temporaryPackedPath2;
|
std::vector<NodeID> temporaryPackedPath2;
|
||||||
if(INT_MAX != _localUpperbound1) {
|
if(INT_MAX != _localUpperbound1) {
|
||||||
super::RetrievePackedPathFromHeap(forwardHeap, backwardHeap, middle1, temporaryPackedPath1);
|
super::RetrievePackedPathFromHeap(forwardHeap, backwardHeap, middle1, temporaryPackedPath1);
|
||||||
// INFO("temporaryPackedPath1 ends with " << *(temporaryPackedPath1.end()-1) );
|
// INFO("temporaryPackedPath1 ends with " << *(temporaryPackedPath1.end()-1) );
|
||||||
|
@ -32,8 +32,8 @@ namespace qi = boost::spirit::qi;
|
|||||||
template <typename Iterator, class HandlerT>
|
template <typename Iterator, class HandlerT>
|
||||||
struct APIGrammar : qi::grammar<Iterator> {
|
struct APIGrammar : qi::grammar<Iterator> {
|
||||||
APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h) {
|
APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h) {
|
||||||
api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> ('?') >> query;
|
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) ) ;
|
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)];
|
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)];
|
output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)];
|
||||||
@ -53,7 +53,7 @@ struct APIGrammar : qi::grammar<Iterator> {
|
|||||||
}
|
}
|
||||||
qi::rule<Iterator> api_call, query;
|
qi::rule<Iterator> api_call, query;
|
||||||
qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, hint,
|
qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, hint,
|
||||||
compressed_geometry, stringwithDot, language, instruction, geometry,
|
stringwithDot, language, instruction, geometry,
|
||||||
cmp, alt_route, old_API;
|
cmp, alt_route, old_API;
|
||||||
|
|
||||||
HandlerT * handler;
|
HandlerT * handler;
|
||||||
|
@ -46,8 +46,8 @@ QueryObjectsStorage::QueryObjectsStorage(std::string hsgrPath, std::string ramIn
|
|||||||
}
|
}
|
||||||
if(!timestamp.length())
|
if(!timestamp.length())
|
||||||
timestamp = "n/a";
|
timestamp = "n/a";
|
||||||
if(15 < timestamp.length())
|
if(25 < timestamp.length())
|
||||||
timestamp.resize(15);
|
timestamp.resize(25);
|
||||||
|
|
||||||
INFO("Loading auxiliary information");
|
INFO("Loading auxiliary information");
|
||||||
//Init nearest neighbor data structure
|
//Init nearest neighbor data structure
|
||||||
|
@ -61,7 +61,7 @@ struct ServerFactory {
|
|||||||
ERR("file index file not found");
|
ERR("file index file not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned threads = omp_get_num_procs();
|
int threads = omp_get_num_procs();
|
||||||
if(serverConfig.GetParameter("IP") == "")
|
if(serverConfig.GetParameter("IP") == "")
|
||||||
serverConfig.SetParameter("IP", "0.0.0.0");
|
serverConfig.SetParameter("IP", "0.0.0.0");
|
||||||
if(serverConfig.GetParameter("Port") == "")
|
if(serverConfig.GetParameter("Port") == "")
|
||||||
|
@ -41,6 +41,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#include "../DataStructures/DeallocatingVector.h"
|
#include "../DataStructures/DeallocatingVector.h"
|
||||||
#include "../DataStructures/DynamicGraph.h"
|
#include "../DataStructures/DynamicGraph.h"
|
||||||
#include "../DataStructures/QueryEdge.h"
|
#include "../DataStructures/QueryEdge.h"
|
||||||
|
#include "../DataStructures/TurnInstructions.h"
|
||||||
#include "../Util/BaseConfiguration.h"
|
#include "../Util/BaseConfiguration.h"
|
||||||
#include "../Util/InputFileUtil.h"
|
#include "../Util/InputFileUtil.h"
|
||||||
#include "../Util/GraphLoader.h"
|
#include "../Util/GraphLoader.h"
|
||||||
|
@ -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<NasaGridSquare> g();
|
|
||||||
* cout << g.height(lng,lat) << endl;
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SRTMLOOKUP_H
|
|
||||||
#define SRTMLOOKUP_H
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#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<NasaGridSquare*> cache;
|
|
||||||
static const int MAX_CACHE_SIZE = 250;
|
|
||||||
std::string ROOT_PATH;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SRTMLOOKUP_H
|
|
@ -2,3 +2,4 @@
|
|||||||
##YAML Template
|
##YAML Template
|
||||||
---
|
---
|
||||||
default: --require features
|
default: --require features
|
||||||
|
verify: --require features --tags ~@todo --tag ~@stress -f progress
|
@ -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.
|
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" {
|
extern "C" {
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
@ -139,7 +131,6 @@ int main (int argc, char *argv[]) {
|
|||||||
speedProfile.uTurnPenalty = 10*lua_tointeger(myLuaState, -1);
|
speedProfile.uTurnPenalty = 10*lua_tointeger(myLuaState, -1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<ImportEdge> edgeList;
|
std::vector<ImportEdge> edgeList;
|
||||||
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
|
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
|
||||||
in.close();
|
in.close();
|
||||||
|
@ -3,7 +3,7 @@ Feature: Bike - Restricted access
|
|||||||
Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Access tag hierachy on ways
|
Scenario: Bike - Access tag hierachy on ways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Bike - Squares and other areas
|
Feature: Bike - Squares and other areas
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
@square
|
@square
|
||||||
Scenario: Bike - Route along edge of a squares
|
Scenario: Bike - Route along edge of a squares
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Barriers
|
Feature: Barriers
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Barriers
|
Scenario: Bike - Barriers
|
||||||
Then routability should be
|
Then routability should be
|
||||||
@ -10,6 +10,7 @@ Feature: Barriers
|
|||||||
| | x |
|
| | x |
|
||||||
| bollard | x |
|
| bollard | x |
|
||||||
| gate | x |
|
| gate | x |
|
||||||
|
| cycle_barrier | x |
|
||||||
| cattle_grid | x |
|
| cattle_grid | x |
|
||||||
| border_control | x |
|
| border_control | x |
|
||||||
| toll_booth | x |
|
| toll_booth | x |
|
||||||
|
@ -3,7 +3,7 @@ Feature: Bike - Cycle tracks/lanes
|
|||||||
Reference: http://wiki.openstreetmap.org/wiki/Key:cycleway
|
Reference: http://wiki.openstreetmap.org/wiki/Key:cycleway
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Cycle tracks/lanes should enable biking
|
Scenario: Bike - Cycle tracks/lanes should enable biking
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Bike - Destination only, no passing through
|
Feature: Bike - Destination only, no passing through
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Destination only street
|
Scenario: Bike - Destination only street
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Bike - Handle ferry routes
|
Feature: Bike - Handle ferry routes
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Ferry route
|
Scenario: Bike - Ferry route
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -114,6 +114,7 @@ Feature: Bike - Handle ferry routes
|
|||||||
| a | g | abcdefg | 23400s +-1 |
|
| a | g | abcdefg | 23400s +-1 |
|
||||||
| g | a | abcdefg | 23400s +-1 |
|
| g | a | abcdefg | 23400s +-1 |
|
||||||
|
|
||||||
|
@todo
|
||||||
Scenario: Bike - Ferry duration, individual parts
|
Scenario: Bike - Ferry duration, individual parts
|
||||||
Given the node map
|
Given the node map
|
||||||
| x | y | | z | | | v |
|
| x | y | | z | | | v |
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Bike - Max speed restrictions
|
Feature: Bike - Max speed restrictions
|
||||||
|
|
||||||
Background: Use specific speeds
|
Background: Use specific speeds
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Respect maxspeeds when lower that way type speed
|
Scenario: Bike - Respect maxspeeds when lower that way type speed
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Bike - Street names in instructions
|
Feature: Bike - Street names in instructions
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - A named street
|
Scenario: Bike - A named street
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -19,26 +19,14 @@ Feature: Bike - Street names in instructions
|
|||||||
| a | c | My Way,Your Way |
|
| a | c | My Way,Your Way |
|
||||||
|
|
||||||
Scenario: Bike - Use way type to describe unnamed ways
|
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
|
Given the node map
|
||||||
| a | b | c | d |
|
| a | b | c | d |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | highway | name |
|
| nodes | highway | name |
|
||||||
| abcd | cycleway | |
|
| ab | cycleway | |
|
||||||
|
| bcd | track | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route |
|
| from | to | route |
|
||||||
| a | d | cycleway |
|
| a | d | cycleway,track |
|
@ -3,7 +3,7 @@ Feature: Bike - Oneway streets
|
|||||||
Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
|
Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Simple oneway
|
Scenario: Bike - Simple oneway
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -4,7 +4,7 @@ Feature: Bike - Turn restrictions
|
|||||||
Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes.
|
Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes.
|
||||||
|
|
||||||
Background: Use car routing
|
Background: Use car routing
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
@no_turning
|
@no_turning
|
||||||
Scenario: Bike - No left turn
|
Scenario: Bike - No left turn
|
||||||
|
37
features/bicycle/stop_area.feature
Normal file
37
features/bicycle/stop_area.feature
Normal file
@ -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/ |
|
@ -3,7 +3,7 @@ Feature: Bike - Handle ferry routes
|
|||||||
Bringing bikes on trains and subways
|
Bringing bikes on trains and subways
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Bringing bikes on trains
|
Scenario: Bike - Bringing bikes on trains
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
Feature: Bike - Accessability of different way types
|
Feature: Bike - Accessability of different way types
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Basic access
|
Scenario: Bike - Basic access
|
||||||
Bikes are allowed on footways etc because you can pull your bike at a lower speed.
|
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
|
Then routability should be
|
||||||
| highway | forw |
|
| highway | forw |
|
||||||
| (nil) | |
|
| (nil) | |
|
||||||
|
@ -3,7 +3,7 @@ Feature: Car - Restricted access
|
|||||||
Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
|
|
||||||
Scenario: Car - Access tag hierachy on ways
|
Scenario: Car - Access tag hierachy on ways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
@ -92,7 +92,7 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
|||||||
| no | |
|
| no | |
|
||||||
| private | |
|
| private | |
|
||||||
| agricultural | |
|
| agricultural | |
|
||||||
| forestery | |
|
| forestry | |
|
||||||
| some_tag | x |
|
| some_tag | x |
|
||||||
|
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
|||||||
| no | |
|
| no | |
|
||||||
| private | |
|
| private | |
|
||||||
| agricultural | |
|
| agricultural | |
|
||||||
| forestery | |
|
| forestry | |
|
||||||
| some_tag | x |
|
| some_tag | x |
|
||||||
|
|
||||||
Scenario: Car - Access tags on both node and way
|
Scenario: Car - Access tags on both node and way
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Car - Barriers
|
Feature: Car - Barriers
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
|
|
||||||
Scenario: Car - Barriers
|
Scenario: Car - Barriers
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Car - Destination only, no passing through
|
Feature: Car - Destination only, no passing through
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
|
|
||||||
Scenario: Car - Destination only street
|
Scenario: Car - Destination only street
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Car - Handle ferry routes
|
Feature: Car - Handle ferry routes
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
|
|
||||||
Scenario: Car - Use a ferry route
|
Scenario: Car - Use a ferry route
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Car - Max speed restrictions
|
Feature: Car - Max speed restrictions
|
||||||
|
|
||||||
Background: Use specific speeds
|
Background: Use specific speeds
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
Given a grid size of 1000 meters
|
Given a grid size of 1000 meters
|
||||||
|
|
||||||
Scenario: Car - Respect maxspeeds when lower that way type speed
|
Scenario: Car - Respect maxspeeds when lower that way type speed
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Car - Street names in instructions
|
Feature: Car - Street names in instructions
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
|
|
||||||
Scenario: Car - A named street
|
Scenario: Car - A named street
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -18,27 +18,16 @@ Feature: Car - Street names in instructions
|
|||||||
| from | to | route |
|
| from | to | route |
|
||||||
| a | c | My Way,Your Way |
|
| a | c | My Way,Your Way |
|
||||||
|
|
||||||
|
@todo
|
||||||
Scenario: Car - Use way type to describe unnamed ways
|
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
|
Given the node map
|
||||||
| a | b | c | d |
|
| a | b | c | d |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | highway | name |
|
| nodes | highway | name |
|
||||||
| abcd | primary | |
|
| ab | tertiary | |
|
||||||
|
| bcd | residential | |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route |
|
| from | to | route |
|
||||||
| a | d | primary |
|
| a | c | tertiary,residential |
|
||||||
|
@ -3,7 +3,7 @@ Feature: Car - Oneway streets
|
|||||||
Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
|
Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
|
|
||||||
Scenario: Car - Simple oneway
|
Scenario: Car - Simple oneway
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -4,7 +4,7 @@ Feature: Car - Turn restrictions
|
|||||||
Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes.
|
Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes.
|
||||||
|
|
||||||
Background: Use car routing
|
Background: Use car routing
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
|
|
||||||
@no_turning
|
@no_turning
|
||||||
Scenario: Car - No left turn
|
Scenario: Car - No left turn
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Car - Accessability of different way types
|
Feature: Car - Accessability of different way types
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "car"
|
Given the profile "car"
|
||||||
|
|
||||||
Scenario: Car - Basic access
|
Scenario: Car - Basic access
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -3,7 +3,7 @@ Feature: Foot - Oneway streets
|
|||||||
Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
|
Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "foot"
|
Given the profile "foot"
|
||||||
|
|
||||||
Scenario: Foot - Walking should not be affected by oneways
|
Scenario: Foot - Walking should not be affected by oneways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Foot - Accessability of different way types
|
Feature: Foot - Accessability of different way types
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "foot"
|
Given the profile "foot"
|
||||||
|
|
||||||
Scenario: Foot - Basic access
|
Scenario: Foot - Basic access
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Weird routings discovered
|
Feature: Weird routings discovered
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Routing on a oneway roundabout
|
Scenario: Routing on a oneway roundabout
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Given /^the speedprofile "([^"]*)"$/ do |profile|
|
Given /^the profile "([^"]*)"$/ do |profile|
|
||||||
read_speedprofile profile
|
set_profile profile
|
||||||
end
|
end
|
||||||
|
|
||||||
Given /^a grid size of (\d+) meters$/ do |meters|
|
Given /^a grid size of (\d+) meters$/ do |meters|
|
||||||
|
@ -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
|
|
@ -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
|
|
||||||
|
|
45
features/step_definitions/requests.rb
Normal file
45
features/step_definitions/requests.rb
Normal file
@ -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
|
40
features/step_definitions/routability.rb
Normal file
40
features/step_definitions/routability.rb
Normal file
@ -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
|
@ -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|
|
When /^I route I should get$/ do |table|
|
||||||
osrm_kill
|
|
||||||
reprocess
|
reprocess
|
||||||
actual = []
|
actual = []
|
||||||
OSRMLauncher.new do
|
OSRMLauncher.new do
|
||||||
@ -204,6 +14,7 @@ When /^I route I should get$/ do |table|
|
|||||||
instructions = way_list json['route_instructions']
|
instructions = way_list json['route_instructions']
|
||||||
bearings = bearing_list json['route_instructions']
|
bearings = bearing_list json['route_instructions']
|
||||||
compasses = compass_list json['route_instructions']
|
compasses = compass_list json['route_instructions']
|
||||||
|
turns = turn_list json['route_instructions']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -232,11 +43,14 @@ When /^I route I should get$/ do |table|
|
|||||||
if table.headers.include? 'compass'
|
if table.headers.include? 'compass'
|
||||||
got['compass'] = compasses
|
got['compass'] = compasses
|
||||||
end
|
end
|
||||||
|
if table.headers.include? 'turns'
|
||||||
|
got['turns'] = turns
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
ok = true
|
ok = true
|
||||||
row.keys.each do |key|
|
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
|
margin = 1 - $2.to_f*0.01
|
||||||
from = $1.to_f*margin
|
from = $1.to_f*margin
|
||||||
to = $1.to_f/margin
|
to = $1.to_f/margin
|
||||||
@ -245,7 +59,7 @@ When /^I route I should get$/ do |table|
|
|||||||
else
|
else
|
||||||
ok = false
|
ok = false
|
||||||
end
|
end
|
||||||
elsif row[key].match /(.*)\s+\+\-(.+)$/
|
elsif row[key].match /(.*)\s+\+\-(.+)$/ #absolute range: 100 +-5
|
||||||
margin = $2.to_f
|
margin = $2.to_f
|
||||||
from = $1.to_f-margin
|
from = $1.to_f-margin
|
||||||
to = $1.to_f+margin
|
to = $1.to_f+margin
|
||||||
@ -254,6 +68,10 @@ When /^I route I should get$/ do |table|
|
|||||||
else
|
else
|
||||||
ok = false
|
ok = false
|
||||||
end
|
end
|
||||||
|
elsif row[key] =~ /^\/(.*)\/$/ #regex: /a,b,.*/
|
||||||
|
if got[key] =~ /#{$1}/
|
||||||
|
got[key] = row[key]
|
||||||
|
end
|
||||||
else
|
else
|
||||||
ok = row[key] == got[key]
|
ok = row[key] == got[key]
|
||||||
end
|
end
|
||||||
@ -269,3 +87,11 @@ When /^I route I should get$/ do |table|
|
|||||||
end
|
end
|
||||||
table.routing_diff! actual
|
table.routing_diff! actual
|
||||||
end
|
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
|
7
features/step_definitions/timestamp.rb
Normal file
7
features/step_definitions/timestamp.rb
Normal file
@ -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
|
58
features/stress/launch.feature
Normal file
58
features/stress/launch.feature
Normal file
@ -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 |
|
@ -1,21 +1,21 @@
|
|||||||
def speedprofile
|
def profile
|
||||||
@speedprofile ||= reset_speedprofile
|
@profile ||= reset_profile
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_speedprofile
|
def reset_profile
|
||||||
@speedprofile = nil
|
@profile = nil
|
||||||
read_speedprofile DEFAULT_SPEEDPROFILE
|
set_profile DEFAULT_SPEEDPROFILE
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_speedprofile profile
|
def set_profile profile
|
||||||
@speedprofile = profile
|
@profile = profile
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_server_ini
|
def write_server_ini
|
||||||
s=<<-EOF
|
s=<<-EOF
|
||||||
Threads = 1
|
Threads = 1
|
||||||
IP = 0.0.0.0
|
IP = 0.0.0.0
|
||||||
Port = 5000
|
Port = #{OSRM_PORT}
|
||||||
|
|
||||||
hsgrData=#{@osm_file}.osrm.hsgr
|
hsgrData=#{@osm_file}.osrm.hsgr
|
||||||
nodesData=#{@osm_file}.osrm.nodes
|
nodesData=#{@osm_file}.osrm.nodes
|
||||||
@ -23,6 +23,7 @@ edgesData=#{@osm_file}.osrm.edges
|
|||||||
ramIndex=#{@osm_file}.osrm.ramIndex
|
ramIndex=#{@osm_file}.osrm.ramIndex
|
||||||
fileIndex=#{@osm_file}.osrm.fileIndex
|
fileIndex=#{@osm_file}.osrm.fileIndex
|
||||||
namesData=#{@osm_file}.osrm.names
|
namesData=#{@osm_file}.osrm.names
|
||||||
|
timestamp=#{@osm_file}.osrm.timestamp
|
||||||
EOF
|
EOF
|
||||||
File.open( 'server.ini', 'w') {|f| f.write( s ) }
|
File.open( 'server.ini', 'w') {|f| f.write( s ) }
|
||||||
end
|
end
|
||||||
|
@ -116,7 +116,7 @@ def reset_data
|
|||||||
#clear_log
|
#clear_log
|
||||||
#clear_data_files
|
#clear_data_files
|
||||||
end
|
end
|
||||||
reset_speedprofile
|
reset_profile
|
||||||
reset_osm
|
reset_osm
|
||||||
@fingerprint = nil
|
@fingerprint = nil
|
||||||
end
|
end
|
||||||
@ -131,10 +131,6 @@ def reset_osm
|
|||||||
name_way_hash.clear
|
name_way_hash.clear
|
||||||
@osm_str = nil
|
@osm_str = nil
|
||||||
@osm_hash = 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
|
@osm_id = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -180,9 +176,8 @@ def convert_osm_to_pbf
|
|||||||
unless File.exist?("#{@osm_file}.osm.pbf")
|
unless File.exist?("#{@osm_file}.osm.pbf")
|
||||||
log_preprocess_info
|
log_preprocess_info
|
||||||
log "== Converting #{@osm_file}.osm to protobuffer format...", :preprocess
|
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}"
|
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
|
end
|
||||||
log '', :preprocess
|
log '', :preprocess
|
||||||
end
|
end
|
||||||
@ -198,25 +193,30 @@ def prepared?
|
|||||||
File.exist?("#{@osm_file}.osrm.hsgr")
|
File.exist?("#{@osm_file}.osrm.hsgr")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def write_timestamp
|
||||||
|
File.open( "#{@osm_file}.osrm.timestamp", 'w') {|f| f.write(OSM_TIMESTAMP) }
|
||||||
|
end
|
||||||
|
|
||||||
def reprocess
|
def reprocess
|
||||||
Dir.chdir TEST_FOLDER do
|
Dir.chdir TEST_FOLDER do
|
||||||
write_osm
|
write_osm
|
||||||
|
write_timestamp
|
||||||
convert_osm_to_pbf
|
convert_osm_to_pbf
|
||||||
unless extracted?
|
unless extracted?
|
||||||
log_preprocess_info
|
log_preprocess_info
|
||||||
log "== Extracting #{@osm_file}.osm...", :preprocess
|
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
|
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
|
end
|
||||||
log '', :preprocess
|
log '', :preprocess
|
||||||
end
|
end
|
||||||
unless prepared?
|
unless prepared?
|
||||||
log_preprocess_info
|
log_preprocess_info
|
||||||
log "== Preparing #{@osm_file}.osm...", :preprocess
|
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
|
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
|
end
|
||||||
log '', :preprocess
|
log '', :preprocess
|
||||||
end
|
end
|
||||||
|
@ -1 +1,18 @@
|
|||||||
require 'rspec/expectations'
|
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
|
||||||
|
|
||||||
|
@ -1,14 +1,49 @@
|
|||||||
|
|
||||||
class OSRMError < StandardError
|
class OSRMError < StandardError
|
||||||
attr_accessor :process, :code, :msg
|
attr_accessor :msg, :code, :process
|
||||||
|
|
||||||
def initialize process, code, msg
|
def initialize process, code, msg, log, lines
|
||||||
@process = process
|
@process = process
|
||||||
@code = code
|
@code = code
|
||||||
@msg = msg
|
@msg = msg
|
||||||
|
@lines = lines
|
||||||
|
@log = log
|
||||||
|
@extract = log_tail @log, @lines
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
@msg
|
"*** #{@msg}\nLast #{@lines} lines from #{@log}:\n#{@extract}\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
end
|
end
|
22
features/support/file.rb
Normal file
22
features/support/file.rb
Normal file
@ -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
|
@ -11,8 +11,9 @@ def hash_of_file path
|
|||||||
return hash.hexdigest
|
return hash.hexdigest
|
||||||
end
|
end
|
||||||
|
|
||||||
def speedprofile_hash
|
def profile_hash
|
||||||
@speedprofile_hash ||= hash_of_file "../profiles/#{@speedprofile}.lua"
|
@@profile_hashes ||= {}
|
||||||
|
@@profile_hashes[@profile] ||= hash_of_file "../profiles/#{@profile}.lua"
|
||||||
end
|
end
|
||||||
|
|
||||||
def osm_hash
|
def osm_hash
|
||||||
@ -20,19 +21,19 @@ def osm_hash
|
|||||||
end
|
end
|
||||||
|
|
||||||
def bin_extract_hash
|
def bin_extract_hash
|
||||||
@bin_hash ||= hash_of_file '../osrm-extract'
|
@@bin_extract_hash ||= hash_of_file '../osrm-extract'
|
||||||
end
|
end
|
||||||
|
|
||||||
def bin_prepare_hash
|
def bin_prepare_hash
|
||||||
@bin_hash ||= hash_of_file '../osrm-prepare'
|
@@bin_prepare_hash ||= hash_of_file '../osrm-prepare'
|
||||||
end
|
end
|
||||||
|
|
||||||
def bin_routed_hash
|
def bin_routed_hash
|
||||||
@bin_hash ||= hash_of_file '../osrm-routed'
|
@@bin_routed_hash ||= hash_of_file '../osrm-routed'
|
||||||
end
|
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
|
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
|
end
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
|
||||||
|
STRESS_TIMEOUT = 300
|
||||||
|
|
||||||
Before do |scenario|
|
Before do |scenario|
|
||||||
@scenario_title = scenario.title
|
@scenario_title = scenario.title
|
||||||
@scenario_time = Time.now.strftime("%Y-%m-%dT%H:%m:%SZ")
|
@scenario_time = Time.now.strftime("%Y-%m-%dT%H:%m:%SZ")
|
||||||
@ -7,12 +10,11 @@ Before do |scenario|
|
|||||||
set_grid_size DEFAULT_GRID_SIZE
|
set_grid_size DEFAULT_GRID_SIZE
|
||||||
end
|
end
|
||||||
|
|
||||||
Around('@routing') do |scenario, block|
|
Around('@stress') do |scenario, block|
|
||||||
Timeout.timeout(10) do
|
Timeout.timeout(STRESS_TIMEOUT) do
|
||||||
block.call
|
block.call
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
After do
|
After do
|
||||||
osrm_kill
|
|
||||||
end
|
end
|
||||||
|
@ -1,71 +1,83 @@
|
|||||||
require 'socket'
|
require 'socket'
|
||||||
require 'sys/proctable'
|
require 'open3'
|
||||||
|
|
||||||
|
LAUNCH_TIMEOUT = 2
|
||||||
|
SHUTDOWN_TIMEOUT = 2
|
||||||
|
OSRM_ROUTED_LOG_FILE = 'osrm-routed.log'
|
||||||
|
|
||||||
class OSRMLauncher
|
class OSRMLauncher
|
||||||
def initialize &block
|
def initialize &block
|
||||||
Dir.chdir TEST_FOLDER do
|
Dir.chdir TEST_FOLDER do
|
||||||
osrm_up
|
begin
|
||||||
|
launch
|
||||||
yield
|
yield
|
||||||
|
ensure
|
||||||
|
shutdown
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def launch
|
||||||
|
Timeout.timeout(LAUNCH_TIMEOUT) do
|
||||||
|
osrm_up
|
||||||
|
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
|
osrm_down
|
||||||
end
|
end
|
||||||
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
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def osrm_up?
|
def osrm_up?
|
||||||
find_pid('osrm-routed') != nil
|
if @pid
|
||||||
|
`ps -o state -p #{@pid}`.split[1].to_s =~ /^[DRST]/
|
||||||
|
else
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_pid name
|
|
||||||
each_process(name) { |pid,state| return pid.to_i }
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def osrm_up
|
def osrm_up
|
||||||
return if osrm_up?
|
return if osrm_up?
|
||||||
pipe = IO.popen('../osrm-routed 1>>osrm-routed.log 2>>osrm-routed.log')
|
@pid = Process.spawn(['../osrm-routed',''],:out=>OSRM_ROUTED_LOG_FILE, :err=>OSRM_ROUTED_LOG_FILE)
|
||||||
timeout = 5
|
end
|
||||||
(timeout*10).times do
|
|
||||||
|
def osrm_down
|
||||||
|
if @pid
|
||||||
|
Process.kill 'TERM', @pid
|
||||||
|
wait_for_shutdown
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def kill
|
||||||
|
if @pid
|
||||||
|
Process.kill 'KILL', @pid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait_for_connection
|
||||||
|
while true
|
||||||
begin
|
begin
|
||||||
socket = TCPSocket.new('localhost', 5000)
|
socket = TCPSocket.new('localhost', OSRM_PORT)
|
||||||
socket.puts 'ping'
|
return
|
||||||
rescue Errno::ECONNREFUSED
|
rescue Errno::ECONNREFUSED
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait_for_shutdown
|
||||||
|
while osrm_up?
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
end
|
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
|
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
|
end
|
||||||
|
@ -14,7 +14,7 @@ def log_scenario_fail_info
|
|||||||
log "Failed scenario: #{@scenario_title}"
|
log "Failed scenario: #{@scenario_title}"
|
||||||
log "Time: #{@scenario_time}"
|
log "Time: #{@scenario_time}"
|
||||||
log "Fingerprint: #{@fingerprint}"
|
log "Fingerprint: #{@fingerprint}"
|
||||||
log "Profile: #{@speedprofile}"
|
log "Profile: #{@profile}"
|
||||||
log
|
log
|
||||||
log '```xml' #so output can be posted directly to github comment fields
|
log '```xml' #so output can be posted directly to github comment fields
|
||||||
log osm_str.strip
|
log osm_str.strip
|
||||||
@ -51,7 +51,7 @@ def log_preprocess_info
|
|||||||
log '```', :preprocess
|
log '```', :preprocess
|
||||||
log '', :preprocess
|
log '', :preprocess
|
||||||
log "== Profile:", :preprocess
|
log "== Profile:", :preprocess
|
||||||
log @speedprofile, :preprocess
|
log @profile, :preprocess
|
||||||
log '', :preprocess
|
log '', :preprocess
|
||||||
@has_logged_preprocess_info = true
|
@has_logged_preprocess_info = true
|
||||||
end
|
end
|
||||||
|
23
features/support/osm_parser.rb
Normal file
23
features/support/osm_parser.rb
Normal file
@ -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
|
@ -1,19 +1,26 @@
|
|||||||
require 'net/http'
|
require 'net/http'
|
||||||
|
|
||||||
|
HOST = "http://localhost:#{OSRM_PORT}"
|
||||||
|
REQUEST_TIMEOUT = 1
|
||||||
DESTINATION_REACHED = 15 #OSRM instruction code
|
DESTINATION_REACHED = 15 #OSRM instruction code
|
||||||
|
|
||||||
|
|
||||||
def request_route a,b
|
def request_path path
|
||||||
@query = "http://localhost:5000/viaroute?loc=#{a}&loc=#{b}&output=json&instructions=true"
|
@query = path
|
||||||
#log @query
|
uri = URI.parse "#{HOST}/#{path}"
|
||||||
uri = URI.parse @query
|
Timeout.timeout(REQUEST_TIMEOUT) do
|
||||||
Net::HTTP.get_response uri
|
Net::HTTP.get_response uri
|
||||||
|
end
|
||||||
rescue Errno::ECONNREFUSED => e
|
rescue Errno::ECONNREFUSED => e
|
||||||
raise "*** osrm-routed is not running."
|
raise "*** osrm-routed is not running."
|
||||||
rescue Timeout::Error
|
rescue Timeout::Error
|
||||||
raise "*** osrm-routed did not respond."
|
raise "*** osrm-routed did not respond."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def request_route a,b
|
||||||
|
request_path "viaroute?loc=#{a}&loc=#{b}&output=json&instructions=true&alt=true"
|
||||||
|
end
|
||||||
|
|
||||||
def parse_response response
|
def parse_response response
|
||||||
if response.code == "200" && response.body.empty? == false
|
if response.code == "200" && response.body.empty? == false
|
||||||
json = JSON.parse response.body
|
json = JSON.parse response.body
|
||||||
@ -83,3 +90,27 @@ def bearing_list instructions
|
|||||||
map { |r| r=="" ? '""' : r }.
|
map { |r| r=="" ? '""' : r }.
|
||||||
join(',')
|
join(',')
|
||||||
end
|
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
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Handle bad data in a graceful manner
|
Feature: Handle bad data in a graceful manner
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Empty dataset
|
Scenario: Empty dataset
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -12,7 +12,7 @@ Feature: Handle bad data in a graceful manner
|
|||||||
| nodes |
|
| nodes |
|
||||||
|
|
||||||
When I preprocess data
|
When I preprocess data
|
||||||
Then preparing should return code 255
|
Then "osrm-extract" should return code 255
|
||||||
|
|
||||||
Scenario: Only dead-end oneways
|
Scenario: Only dead-end oneways
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Basic Routing
|
Feature: Basic Routing
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
@smallest
|
@smallest
|
||||||
Scenario: A single way with two nodes
|
Scenario: A single way with two nodes
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Compass bearing
|
Feature: Compass bearing
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Bearing when going northwest
|
Scenario: Bearing when going northwest
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Distance calculation
|
Feature: Distance calculation
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: 100m distance
|
Scenario: 100m distance
|
||||||
Given a grid size of 100 meters
|
Given a grid size of 100 meters
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Testbot - Handle ferry routes
|
Feature: Testbot - Handle ferry routes
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Testbot - Ferry duration, single node
|
Scenario: Testbot - Ferry duration, single node
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -39,6 +39,7 @@ Feature: Testbot - Handle ferry routes
|
|||||||
| a | d | abcd | 3600s +-1 |
|
| a | d | abcd | 3600s +-1 |
|
||||||
| d | a | abcd | 3600s +-1 |
|
| d | a | abcd | 3600s +-1 |
|
||||||
|
|
||||||
|
@todo
|
||||||
Scenario: Bike - Ferry duration, individual parts
|
Scenario: Bike - Ferry duration, individual parts
|
||||||
Given the node map
|
Given the node map
|
||||||
| x | y | | z | | | v |
|
| x | y | | z | | | v |
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Routing close to the [0,0] origin
|
Feature: Routing close to the [0,0] origin
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: East-west oneways close to the origin
|
Scenario: East-west oneways close to the origin
|
||||||
Given the node locations
|
Given the node locations
|
||||||
|
@ -3,7 +3,7 @@ Feature: Penalties
|
|||||||
Testbot uses a signal penalty of 7s.
|
Testbot uses a signal penalty of 7s.
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Traffic signals should incur a delay, without changing distance
|
Scenario: Traffic signals should incur a delay, without changing distance
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
@routing @planetary
|
@routing @planetary
|
||||||
Feature: Distance calculation
|
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
|
Given the node locations
|
||||||
| node | lat | lon |
|
| node | lat | lon |
|
||||||
| a | 0 | 80 |
|
| a | 0 | 80 |
|
||||||
@ -16,7 +15,7 @@ Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VD
|
|||||||
| from | to | route | distance |
|
| from | to | route | distance |
|
||||||
| a | b | ab | 8905559m ~0.1% |
|
| a | b | ab | 8905559m ~0.1% |
|
||||||
|
|
||||||
Scenario: Longitudinal distances at latitude 45
|
Scenario: Approximated Longitudinal distances at latitude 45
|
||||||
Given the node locations
|
Given the node locations
|
||||||
| node | lat | lon |
|
| node | lat | lon |
|
||||||
| c | 45 | 80 |
|
| 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
|
When I route I should get
|
||||||
| from | to | route | distance |
|
| 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
|
Given the node locations
|
||||||
| node | lat | lon |
|
| node | lat | lon |
|
||||||
| c | 80 | 80 |
|
| 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
|
When I route I should get
|
||||||
| from | to | route | distance |
|
| 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
|
Given the node locations
|
||||||
| node | lat | lon |
|
| node | lat | lon |
|
||||||
| a | 80 | 0 |
|
| a | 80 | 0 |
|
||||||
@ -58,7 +57,7 @@ Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VD
|
|||||||
| from | to | route | distance |
|
| from | to | route | distance |
|
||||||
| a | b | ab | 8905559m ~0.1% |
|
| a | b | ab | 8905559m ~0.1% |
|
||||||
|
|
||||||
Scenario: Latitudinal distances at longitude 45
|
Scenario: Approximated Latitudinal distances at longitude 45
|
||||||
Given the node locations
|
Given the node locations
|
||||||
| node | lat | lon |
|
| node | lat | lon |
|
||||||
| a | 80 | 45 |
|
| a | 80 | 45 |
|
||||||
@ -72,7 +71,7 @@ Reference distances have been calculated usign http://seismo.cqu.edu.au/CQSRG/VD
|
|||||||
| from | to | route | distance |
|
| from | to | route | distance |
|
||||||
| a | b | ab | 8905559m ~0.1% |
|
| a | b | ab | 8905559m ~0.1% |
|
||||||
|
|
||||||
Scenario: Latitudinal distances at longitude 80
|
Scenario: Approximated Latitudinal distances at longitude 80
|
||||||
Given the node locations
|
Given the node locations
|
||||||
| node | lat | lon |
|
| node | lat | lon |
|
||||||
| a | 80 | 80 |
|
| a | 80 | 80 |
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Snap start/end point to the nearest way
|
Feature: Snap start/end point to the nearest way
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Snap to nearest protruding oneway
|
Scenario: Snap to nearest protruding oneway
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -98,7 +98,6 @@ Feature: Snap start/end point to the nearest way
|
|||||||
| b | x | xb |
|
| b | x | xb |
|
||||||
| c | x | xc |
|
| c | x | xc |
|
||||||
|
|
||||||
@xx
|
|
||||||
Scenario: Find edges within 1km, but not 10km
|
Scenario: Find edges within 1km, but not 10km
|
||||||
Given a grid size of 1000 meters
|
Given a grid size of 1000 meters
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -153,4 +152,3 @@ Feature: Snap start/end point to the nearest way
|
|||||||
| x | n | |
|
| x | n | |
|
||||||
| x | o | |
|
| x | o | |
|
||||||
| x | p | |
|
| x | p | |
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ Secondary road: 18km/h = 18000m/3600s = 100m/20s
|
|||||||
Tertiary road: 12km/h = 12000m/3600s = 100m/30s
|
Tertiary road: 12km/h = 12000m/3600s = 100m/30s
|
||||||
|
|
||||||
Background: Use specific speeds
|
Background: Use specific speeds
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Basic travel time, 10m scale
|
Scenario: Basic travel time, 10m scale
|
||||||
Given a grid size of 10 meters
|
Given a grid size of 10 meters
|
||||||
|
115
features/testbot/turns.feature
Normal file
115
features/testbot/turns.feature
Normal file
@ -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 |
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Handling of UTF characters
|
Feature: Handling of UTF characters
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Streetnames with UTF characters
|
Scenario: Streetnames with UTF characters
|
||||||
Given the node map
|
Given the node map
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Feature: Choosing route based on length, speed, etc
|
Feature: Choosing route based on length, speed, etc
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the speedprofile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
Scenario: Pick the geometrically shortest route, way types being equal
|
Scenario: Pick the geometrically shortest route, way types being equal
|
||||||
Given the node map
|
Given the node map
|
||||||
|
12
features/timestamp/timestamp.feature
Normal file
12
features/timestamp/timestamp.feature
Normal file
@ -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
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
-- Begin of globals
|
-- 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_whitelist = { ["yes"] = 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, ["forestery"] = true }
|
||||||
access_tag_restricted = { ["destination"] = true, ["delivery"] = true }
|
access_tag_restricted = { ["destination"] = true, ["delivery"] = true }
|
||||||
@ -121,6 +121,7 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
local junction = way.tags:Find("junction")
|
local junction = way.tags:Find("junction")
|
||||||
local route = way.tags:Find("route")
|
local route = way.tags:Find("route")
|
||||||
local railway = way.tags:Find("railway")
|
local railway = way.tags:Find("railway")
|
||||||
|
local public_transport = way.tags:Find("public_transport")
|
||||||
local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") )
|
local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") )
|
||||||
local man_made = way.tags:Find("man_made")
|
local man_made = way.tags:Find("man_made")
|
||||||
local barrier = way.tags:Find("barrier")
|
local barrier = way.tags:Find("barrier")
|
||||||
@ -135,11 +136,13 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
local amenity = way.tags:Find("amenity")
|
local amenity = way.tags:Find("amenity")
|
||||||
local access = find_access_tag(way)
|
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
|
if (not highway or highway == '') and
|
||||||
(not route or route == '') and
|
(not route or route == '') and
|
||||||
(not railway or railway=='') and
|
(not railway or railway=='') and
|
||||||
(not amenity or amenity=='') then
|
(not amenity or amenity=='') and
|
||||||
|
(not public_transport or public_transport=='')
|
||||||
|
then
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -168,8 +171,11 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
way.speed = route_speeds[route]
|
way.speed = route_speeds[route]
|
||||||
end
|
end
|
||||||
elseif railway and platform_speeds[railway] then
|
elseif railway and platform_speeds[railway] then
|
||||||
-- railway platforms
|
-- railway platforms (old tagging scheme)
|
||||||
way.speed = platform_speeds[railway]
|
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
|
elseif railway and railway_speeds[railway] then
|
||||||
-- railways
|
-- railways
|
||||||
if access and access_tag_whitelist[access] then
|
if access and access_tag_whitelist[access] then
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true}
|
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_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_tag_restricted = { ["destination"] = true, ["delivery"] = true }
|
||||||
access_tags = { "motorcar", "motor_vehicle", "vehicle" }
|
access_tags = { "motorcar", "motor_vehicle", "vehicle" }
|
||||||
access_tags_hierachy = { "motorcar", "motor_vehicle", "vehicle", "access" }
|
access_tags_hierachy = { "motorcar", "motor_vehicle", "vehicle", "access" }
|
||||||
|
@ -82,7 +82,7 @@ int main (int argc, char * argv[0]) {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
try {
|
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
|
#ifndef _WIN32
|
||||||
int sig = 0;
|
int sig = 0;
|
||||||
@ -135,11 +135,14 @@ int main (int argc, char * argv[0]) {
|
|||||||
s->Run();
|
s->Run();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::cout << std::endl << "[server] shutting down" << std::endl;
|
std::cout << "[server] initiating shutdown" << std::endl;
|
||||||
s->Stop();
|
s->Stop();
|
||||||
|
std::cout << "[server] stopping threads" << std::endl;
|
||||||
t.join();
|
t.join();
|
||||||
|
std::cout << "[server] freeing objects" << std::endl;
|
||||||
delete s;
|
delete s;
|
||||||
delete objects;
|
delete objects;
|
||||||
|
std::cout << "[server] shutdown completed" << std::endl;
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
std::cerr << "[fatal error] exception: " << e.what() << std::endl;
|
std::cerr << "[fatal error] exception: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user