Merge branch 'feature/opposite_direction' into develop
This commit is contained in:
commit
348e656671
@ -157,11 +157,13 @@ public:
|
|||||||
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
|
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
|
||||||
//remove parallel edges
|
//remove parallel edges
|
||||||
while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) {
|
while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) {
|
||||||
if ( edges[i].data.forward )
|
if ( edges[i].data.forward) {
|
||||||
forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance );
|
forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance );
|
||||||
if ( edges[i].data.backward )
|
}
|
||||||
|
if ( edges[i].data.backward) {
|
||||||
backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance );
|
backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance );
|
||||||
i++;
|
}
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
//merge edges (s,t) and (t,s) into bidirectional edge
|
//merge edges (s,t) and (t,s) into bidirectional edge
|
||||||
if ( forwardEdge.data.distance == backwardEdge.data.distance ) {
|
if ( forwardEdge.data.distance == backwardEdge.data.distance ) {
|
||||||
@ -242,7 +244,7 @@ public:
|
|||||||
nodePriority[x] = _Evaluate( data, &nodeData[x], x );
|
nodePriority[x] = _Evaluate( data, &nodeData[x], x );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "ok" << std::endl << "preprocessing ..." << std::flush;
|
std::cout << "ok" << std::endl << "preprocessing " << numberOfNodes << " nodes ..." << std::flush;
|
||||||
|
|
||||||
bool flushedContractor = false;
|
bool flushedContractor = false;
|
||||||
while ( numberOfContractedNodes < numberOfNodes ) {
|
while ( numberOfContractedNodes < numberOfNodes ) {
|
||||||
|
@ -61,9 +61,9 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
|
|||||||
edge.data.forward = i->isForward();
|
edge.data.forward = i->isForward();
|
||||||
edge.data.backward = i->isBackward();
|
edge.data.backward = i->isBackward();
|
||||||
}
|
}
|
||||||
if(edge.source == edge.target)
|
if(edge.source == edge.target) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
edge.data.distance = (std::max)((int)i->weight(), 1 );
|
edge.data.distance = (std::max)((int)i->weight(), 1 );
|
||||||
assert( edge.data.distance > 0 );
|
assert( edge.data.distance > 0 );
|
||||||
edge.data.shortcut = false;
|
edge.data.shortcut = false;
|
||||||
@ -73,6 +73,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
|
|||||||
edge.data.type = i->type();
|
edge.data.type = i->type();
|
||||||
edge.data.isAccessRestricted = i->isAccessRestricted();
|
edge.data.isAccessRestricted = i->isAccessRestricted();
|
||||||
edge.data.edgeBasedNodeID = edges.size();
|
edge.data.edgeBasedNodeID = edges.size();
|
||||||
|
edge.data.contraFlow = i->isContraFlow();
|
||||||
edges.push_back( edge );
|
edges.push_back( edge );
|
||||||
if( edge.data.backward ) {
|
if( edge.data.backward ) {
|
||||||
std::swap( edge.source, edge.target );
|
std::swap( edge.source, edge.target );
|
||||||
@ -107,7 +108,7 @@ NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(const NodeID u, const
|
|||||||
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
|
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
|
||||||
if (restrIter != _restrictionMap.end()) {
|
if (restrIter != _restrictionMap.end()) {
|
||||||
unsigned index = restrIter->second;
|
unsigned index = restrIter->second;
|
||||||
BOOST_FOREACH(RestrictionSource restrictionTarget, _restrictionBucketVector.at(index)) {
|
BOOST_FOREACH(const RestrictionSource & restrictionTarget, _restrictionBucketVector.at(index)) {
|
||||||
if(restrictionTarget.second) {
|
if(restrictionTarget.second) {
|
||||||
return restrictionTarget.first;
|
return restrictionTarget.first;
|
||||||
}
|
}
|
||||||
@ -239,6 +240,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
|
|||||||
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
|
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
|
||||||
++nodeBasedEdgeCounter;
|
++nodeBasedEdgeCounter;
|
||||||
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
|
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
|
||||||
|
bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end());
|
||||||
//EdgeWeight heightPenalty = ComputeHeightPenalty(u, v);
|
//EdgeWeight heightPenalty = ComputeHeightPenalty(u, v);
|
||||||
NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v);
|
NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v);
|
||||||
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
|
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
|
||||||
@ -248,7 +250,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
|
|||||||
++numberOfSkippedTurns;
|
++numberOfSkippedTurns;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end());
|
|
||||||
if(u == w && 1 != _nodeBasedGraph->GetOutDegree(v) ) {
|
if(u == w && 1 != _nodeBasedGraph->GetOutDegree(v) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -291,7 +293,6 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
|
|||||||
originalEdgeData.clear();
|
originalEdgeData.clear();
|
||||||
}
|
}
|
||||||
++numberOfOriginalEdges;
|
++numberOfOriginalEdges;
|
||||||
++nodeBasedEdgeCounter;
|
|
||||||
edgeBasedEdges.push_back(newEdge);
|
edgeBasedEdges.push_back(newEdge);
|
||||||
} else {
|
} else {
|
||||||
++numberOfSkippedTurns;
|
++numberOfSkippedTurns;
|
||||||
@ -316,6 +317,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
|
|||||||
// std::vector<EdgeBasedNode>(edgeBasedNodes).swap(edgeBasedNodes);
|
// std::vector<EdgeBasedNode>(edgeBasedNodes).swap(edgeBasedNodes);
|
||||||
// INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity());
|
// INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity());
|
||||||
INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges");
|
INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges");
|
||||||
|
INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges");
|
||||||
// INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << 2*((double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter));
|
// INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << 2*((double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter));
|
||||||
INFO("Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions.");
|
INFO("Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions.");
|
||||||
INFO("Generated " << edgeBasedNodes.size() << " edge based nodes");
|
INFO("Generated " << edgeBasedNodes.size() << " edge based nodes");
|
||||||
@ -332,6 +334,13 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
|
|||||||
_NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1);
|
_NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1);
|
||||||
_NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2);
|
_NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2);
|
||||||
|
|
||||||
|
if(!data1.contraFlow && data2.contraFlow) {
|
||||||
|
return TurnInstructions.EnterAgainstAllowedDirection;
|
||||||
|
}
|
||||||
|
if(data1.contraFlow && !data2.contraFlow) {
|
||||||
|
return TurnInstructions.LeaveAgainstAllowedDirection;
|
||||||
|
}
|
||||||
|
|
||||||
//roundabouts need to be handled explicitely
|
//roundabouts need to be handled explicitely
|
||||||
if(data1.roundabout && data2.roundabout) {
|
if(data1.roundabout && data2.roundabout) {
|
||||||
//Is a turn possible? If yes, we stay on the roundabout!
|
//Is a turn possible? If yes, we stay on the roundabout!
|
||||||
@ -353,10 +362,12 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
|
|||||||
}
|
}
|
||||||
|
|
||||||
//If street names stay the same and if we are certain that it is not a roundabout, we skip it.
|
//If street names stay the same and if we are certain that it is not a roundabout, we skip it.
|
||||||
if( (data1.nameID == data2.nameID) && (0 != data1.nameID))
|
if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) {
|
||||||
return TurnInstructions.NoTurn;
|
return TurnInstructions.NoTurn;
|
||||||
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) )
|
}
|
||||||
|
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) {
|
||||||
return TurnInstructions.NoTurn;
|
return TurnInstructions.NoTurn;
|
||||||
|
}
|
||||||
|
|
||||||
double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
|
double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
|
||||||
return TurnInstructions.GetTurnDirectionOfInstruction(angle);
|
return TurnInstructions.GetTurnDirectionOfInstruction(angle);
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
#include <boost/unordered_set.hpp>
|
#include <boost/unordered_set.hpp>
|
||||||
@ -49,34 +50,7 @@
|
|||||||
#include "../DataStructures/TurnInstructions.h"
|
#include "../DataStructures/TurnInstructions.h"
|
||||||
#include "../Util/BaseConfiguration.h"
|
#include "../Util/BaseConfiguration.h"
|
||||||
|
|
||||||
class EdgeBasedGraphFactory {
|
class EdgeBasedGraphFactory : boost::noncopyable {
|
||||||
private:
|
|
||||||
struct _NodeBasedEdgeData {
|
|
||||||
int distance;
|
|
||||||
unsigned edgeBasedNodeID;
|
|
||||||
unsigned nameID;
|
|
||||||
short type;
|
|
||||||
bool isAccessRestricted;
|
|
||||||
bool shortcut:1;
|
|
||||||
bool forward:1;
|
|
||||||
bool backward:1;
|
|
||||||
bool roundabout:1;
|
|
||||||
bool ignoreInGrid:1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _EdgeBasedEdgeData {
|
|
||||||
int distance;
|
|
||||||
unsigned via;
|
|
||||||
unsigned nameID;
|
|
||||||
bool forward;
|
|
||||||
bool backward;
|
|
||||||
TurnInstruction turnInstruction;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
|
|
||||||
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
|
|
||||||
std::vector<NodeInfo> inputNodeInfoList;
|
|
||||||
unsigned numberOfTurnRestrictions;
|
|
||||||
public:
|
public:
|
||||||
struct EdgeBasedNode {
|
struct EdgeBasedNode {
|
||||||
bool operator<(const EdgeBasedNode & other) const {
|
bool operator<(const EdgeBasedNode & other) const {
|
||||||
@ -96,13 +70,41 @@ public:
|
|||||||
bool ignoreInGrid:1;
|
bool ignoreInGrid:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct SpeedProfileProperties{
|
struct SpeedProfileProperties{
|
||||||
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0) {}
|
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0) {}
|
||||||
int trafficSignalPenalty;
|
int trafficSignalPenalty;
|
||||||
int uTurnPenalty;
|
int uTurnPenalty;
|
||||||
} speedProfile;
|
} speedProfile;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct _NodeBasedEdgeData {
|
||||||
|
int distance;
|
||||||
|
unsigned edgeBasedNodeID;
|
||||||
|
unsigned nameID;
|
||||||
|
short type;
|
||||||
|
bool isAccessRestricted;
|
||||||
|
bool shortcut:1;
|
||||||
|
bool forward:1;
|
||||||
|
bool backward:1;
|
||||||
|
bool roundabout:1;
|
||||||
|
bool ignoreInGrid:1;
|
||||||
|
bool contraFlow;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _EdgeBasedEdgeData {
|
||||||
|
int distance;
|
||||||
|
unsigned via;
|
||||||
|
unsigned nameID;
|
||||||
|
bool forward;
|
||||||
|
bool backward;
|
||||||
|
TurnInstruction turnInstruction;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
|
||||||
|
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
|
||||||
|
std::vector<NodeInfo> inputNodeInfoList;
|
||||||
|
unsigned numberOfTurnRestrictions;
|
||||||
|
|
||||||
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
|
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
|
||||||
boost::unordered_set<NodeID> _barrierNodes;
|
boost::unordered_set<NodeID> _barrierNodes;
|
||||||
boost::unordered_set<NodeID> _trafficLights;
|
boost::unordered_set<NodeID> _trafficLights;
|
||||||
@ -114,7 +116,6 @@ private:
|
|||||||
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
|
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
|
||||||
RestrictionMap _restrictionMap;
|
RestrictionMap _restrictionMap;
|
||||||
|
|
||||||
|
|
||||||
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges;
|
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges;
|
||||||
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
|
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
|
||||||
std::vector<OriginalEdgeData> originalEdgeData;
|
std::vector<OriginalEdgeData> originalEdgeData;
|
||||||
|
@ -302,6 +302,18 @@ public:
|
|||||||
size_t _index = index % bucketSizeC;
|
size_t _index = index % bucketSizeC;
|
||||||
return (mBucketList[_bucket][_index]);
|
return (mBucketList[_bucket][_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ElementT & back() {
|
||||||
|
size_t _bucket = mCurrentSize / bucketSizeC;
|
||||||
|
size_t _index = mCurrentSize % bucketSizeC;
|
||||||
|
return (mBucketList[_bucket][_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const inline ElementT & back() const {
|
||||||
|
size_t _bucket = mCurrentSize / bucketSizeC;
|
||||||
|
size_t _index = mCurrentSize % bucketSizeC;
|
||||||
|
return (mBucketList[_bucket][_index]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DEALLOCATINGVECTOR_H_ */
|
#endif /* DEALLOCATINGVECTOR_H_ */
|
||||||
|
@ -72,6 +72,7 @@ class DynamicGraph {
|
|||||||
m_nodes[node].edges = edge - lastEdge;
|
m_nodes[node].edges = edge - lastEdge;
|
||||||
position += m_nodes[node].edges;
|
position += m_nodes[node].edges;
|
||||||
}
|
}
|
||||||
|
m_nodes.back().firstEdge = position;
|
||||||
m_edges.reserve( position * 1.1 );
|
m_edges.reserve( position * 1.1 );
|
||||||
m_edges.resize( position );
|
m_edges.resize( position );
|
||||||
edge = 0;
|
edge = 0;
|
||||||
|
@ -40,12 +40,8 @@ public:
|
|||||||
return (source() < e.source());
|
return (source() < e.source());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Default constructor. target and weight are set to 0.*/
|
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar, bool cf) :
|
||||||
NodeBasedEdge() :
|
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar), _contraFlow(cf) { if(ty < 0) {ERR("Type: " << ty);}; }
|
||||||
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false) { assert(false); } //shall not be used.
|
|
||||||
|
|
||||||
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar) :
|
|
||||||
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar) { if(ty < 0) {ERR("Type: " << ty);}; }
|
|
||||||
|
|
||||||
NodeID target() const {return _target; }
|
NodeID target() const {return _target; }
|
||||||
NodeID source() const {return _source; }
|
NodeID source() const {return _source; }
|
||||||
@ -59,6 +55,7 @@ public:
|
|||||||
bool isRoundabout() const { return _roundabout; }
|
bool isRoundabout() const { return _roundabout; }
|
||||||
bool ignoreInGrid() const { return _ignoreInGrid; }
|
bool ignoreInGrid() const { return _ignoreInGrid; }
|
||||||
bool isAccessRestricted() const { return _accessRestricted; }
|
bool isAccessRestricted() const { return _accessRestricted; }
|
||||||
|
bool isContraFlow() const { return _contraFlow; }
|
||||||
|
|
||||||
NodeID _source;
|
NodeID _source;
|
||||||
NodeID _target;
|
NodeID _target;
|
||||||
@ -70,6 +67,13 @@ public:
|
|||||||
bool _roundabout;
|
bool _roundabout;
|
||||||
bool _ignoreInGrid;
|
bool _ignoreInGrid;
|
||||||
bool _accessRestricted;
|
bool _accessRestricted;
|
||||||
|
bool _contraFlow;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Default constructor. target and weight are set to 0.*/
|
||||||
|
NodeBasedEdge() :
|
||||||
|
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false), _contraFlow(false) { assert(false); } //shall not be used.
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EdgeBasedEdge {
|
class EdgeBasedEdge {
|
||||||
|
@ -221,7 +221,7 @@ public:
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << "; newEndpoint: " << resultNode.location);
|
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << "; newEndpoint: " << resultNode.location);
|
||||||
double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
|
const double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
|
||||||
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
|
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
|
||||||
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
|
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
|
||||||
//Hack to fix rounding errors and wandering via nodes.
|
//Hack to fix rounding errors and wandering via nodes.
|
||||||
@ -232,12 +232,13 @@ public:
|
|||||||
|
|
||||||
resultNode.weight1 *= ratio;
|
resultNode.weight1 *= ratio;
|
||||||
if(INT_MAX != resultNode.weight2) {
|
if(INT_MAX != resultNode.weight2) {
|
||||||
resultNode.weight2 -= resultNode.weight1;
|
resultNode.weight2 *= (1.-ratio);
|
||||||
}
|
}
|
||||||
resultNode.ratio = ratio;
|
resultNode.ratio = ratio;
|
||||||
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
|
|
||||||
// INFO("start: " << edgeStartCoord << ", end: " << edgeEndCoord);
|
// INFO("start: " << edgeStartCoord << ", end: " << edgeEndCoord);
|
||||||
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no") << "\n--");
|
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no"));
|
||||||
|
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
|
||||||
|
// INFO("distance to input coordinate: " << ApproximateDistance(location, resultNode.location) << "\n--");
|
||||||
// double time2 = get_timestamp();
|
// double time2 = get_timestamp();
|
||||||
// INFO("NN-Lookup in " << 1000*(time2-time1) << "ms");
|
// INFO("NN-Lookup in " << 1000*(time2-time1) << "ms");
|
||||||
return foundNode;
|
return foundNode;
|
||||||
|
@ -21,12 +21,12 @@
|
|||||||
#ifndef TURNINSTRUCTIONS_H_
|
#ifndef TURNINSTRUCTIONS_H_
|
||||||
#define TURNINSTRUCTIONS_H_
|
#define TURNINSTRUCTIONS_H_
|
||||||
|
|
||||||
#include <string>
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
typedef unsigned char TurnInstruction;
|
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 : boost::noncopyable {
|
||||||
|
|
||||||
const static TurnInstruction NoTurn = 0; //Give no instruction at all
|
const static TurnInstruction NoTurn = 0; //Give no instruction at all
|
||||||
const static TurnInstruction GoStraight = 1; //Tell user to go straight!
|
const static TurnInstruction GoStraight = 1; //Tell user to go straight!
|
||||||
@ -44,48 +44,14 @@ struct TurnInstructionsClass {
|
|||||||
const static TurnInstruction StayOnRoundAbout = 13;
|
const static TurnInstruction StayOnRoundAbout = 13;
|
||||||
const static TurnInstruction StartAtEndOfStreet = 14;
|
const static TurnInstruction StartAtEndOfStreet = 14;
|
||||||
const static TurnInstruction ReachedYourDestination = 15;
|
const static TurnInstruction ReachedYourDestination = 15;
|
||||||
|
const static TurnInstruction EnterAgainstAllowedDirection = 16;
|
||||||
|
const static TurnInstruction LeaveAgainstAllowedDirection = 17;
|
||||||
|
|
||||||
const static TurnInstruction AccessRestrictionFlag = 128;
|
const static TurnInstruction AccessRestrictionFlag = 128;
|
||||||
const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning.
|
const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning.
|
||||||
|
|
||||||
const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag
|
const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag
|
||||||
|
|
||||||
// std::string TurnStrings[16];
|
|
||||||
// std::string Ordinals[12];
|
|
||||||
|
|
||||||
//This is a hack until c++0x is available enough to use initializer lists.
|
|
||||||
// TurnInstructionsClass(){
|
|
||||||
// TurnStrings [0] = "";
|
|
||||||
// TurnStrings [1] = "Continue";
|
|
||||||
// TurnStrings [2] = "Turn slight right";
|
|
||||||
// TurnStrings [3] = "Turn right";
|
|
||||||
// TurnStrings [4] = "Turn sharp right";
|
|
||||||
// TurnStrings [5] = "U-Turn";
|
|
||||||
// TurnStrings [6] = "Turn sharp left";
|
|
||||||
// TurnStrings [7] = "Turn left";
|
|
||||||
// TurnStrings [8] = "Turn slight left";
|
|
||||||
// TurnStrings [9] = "Reach via point";
|
|
||||||
// TurnStrings[10] = "Head";
|
|
||||||
// TurnStrings[11] = "Enter roundabout";
|
|
||||||
// TurnStrings[12] = "Leave roundabout";
|
|
||||||
// TurnStrings[13] = "Stay on roundabout";
|
|
||||||
// TurnStrings[14] = "Start";
|
|
||||||
// TurnStrings[15] = "You have reached your destination";
|
|
||||||
//
|
|
||||||
// Ordinals[0] = "zeroth";
|
|
||||||
// Ordinals[1] = "first";
|
|
||||||
// Ordinals[2] = "second";
|
|
||||||
// Ordinals[3] = "third";
|
|
||||||
// Ordinals[4] = "fourth";
|
|
||||||
// Ordinals[5] = "fifth";
|
|
||||||
// Ordinals[6] = "sixth";
|
|
||||||
// Ordinals[7] = "seventh";
|
|
||||||
// Ordinals[8] = "eighth";
|
|
||||||
// Ordinals[9] = "nineth";
|
|
||||||
// Ordinals[10] = "tenth";
|
|
||||||
// Ordinals[11] = "one of the too many";
|
|
||||||
// };
|
|
||||||
|
|
||||||
static inline TurnInstruction 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;
|
||||||
|
@ -231,17 +231,17 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
|
|||||||
fout.write((char*)&edgeIT->target, sizeof(unsigned));
|
fout.write((char*)&edgeIT->target, sizeof(unsigned));
|
||||||
fout.write((char*)&intDist, sizeof(int));
|
fout.write((char*)&intDist, sizeof(int));
|
||||||
switch(edgeIT->direction) {
|
switch(edgeIT->direction) {
|
||||||
case _Way::notSure:
|
case ExtractionWay::notSure:
|
||||||
fout.write((char*)&zero, sizeof(short));
|
fout.write((char*)&zero, sizeof(short));
|
||||||
break;
|
break;
|
||||||
case _Way::oneway:
|
case ExtractionWay::oneway:
|
||||||
fout.write((char*)&one, sizeof(short));
|
fout.write((char*)&one, sizeof(short));
|
||||||
break;
|
break;
|
||||||
case _Way::bidirectional:
|
case ExtractionWay::bidirectional:
|
||||||
fout.write((char*)&zero, sizeof(short));
|
fout.write((char*)&zero, sizeof(short));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case _Way::opposite:
|
case ExtractionWay::opposite:
|
||||||
fout.write((char*)&one, sizeof(short));
|
fout.write((char*)&one, sizeof(short));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -256,6 +256,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
|
|||||||
fout.write((char*)&edgeIT->isRoundabout, sizeof(bool));
|
fout.write((char*)&edgeIT->isRoundabout, sizeof(bool));
|
||||||
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
|
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
|
||||||
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
|
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
|
||||||
|
fout.write((char*)&edgeIT->isContraFlow, sizeof(bool));
|
||||||
}
|
}
|
||||||
++usedEdgeCounter;
|
++usedEdgeCounter;
|
||||||
++edgeIT;
|
++edgeIT;
|
||||||
|
@ -31,7 +31,7 @@ class ExtractionContainers {
|
|||||||
public:
|
public:
|
||||||
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
|
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
|
||||||
typedef stxxl::vector<_Node> STXXLNodeVector;
|
typedef stxxl::vector<_Node> STXXLNodeVector;
|
||||||
typedef stxxl::vector<_Edge> STXXLEdgeVector;
|
typedef stxxl::vector<InternalExtractorEdge> STXXLEdgeVector;
|
||||||
typedef stxxl::vector<std::string> STXXLStringVector;
|
typedef stxxl::vector<std::string> STXXLStringVector;
|
||||||
typedef stxxl::vector<_RawRestrictionContainer> STXXLRestrictionsVector;
|
typedef stxxl::vector<_RawRestrictionContainer> STXXLRestrictionsVector;
|
||||||
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
|
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
|
||||||
|
@ -64,46 +64,84 @@ bool ExtractorCallbacks::restrictionFunction(_RawRestrictionContainer &r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** warning: caller needs to take care of synchronization! */
|
/** warning: caller needs to take care of synchronization! */
|
||||||
bool ExtractorCallbacks::wayFunction(_Way &w) {
|
bool ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
|
||||||
/*** Store name of way and split it into edge segments ***/
|
if ( parsed_way.speed > 0 || (0 < parsed_way.duration)) { //Only true if the way is specified by the speed profile
|
||||||
|
if(parsed_way.id == UINT_MAX){
|
||||||
if ( (0 < w.speed) || (0 < w.duration) ) { //Only true if the way is specified by the speed profile
|
WARN("found bogus way with id: " << parsed_way.id << " of size " << parsed_way.path.size());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//Get the unique identifier for the street name
|
//Get the unique identifier for the street name
|
||||||
const StringMap::const_iterator strit = stringMap->find(w.name);
|
const StringMap::const_iterator string_map_iterator = stringMap->find(parsed_way.name);
|
||||||
if(strit == stringMap->end()) {
|
if(string_map_iterator == stringMap->end()) {
|
||||||
w.nameID = externalMemory->nameVector.size();
|
parsed_way.nameID = externalMemory->nameVector.size();
|
||||||
externalMemory->nameVector.push_back(w.name);
|
externalMemory->nameVector.push_back(parsed_way.name);
|
||||||
stringMap->insert(StringMap::value_type(w.name, w.nameID));
|
stringMap->insert(StringMap::value_type(parsed_way.name, parsed_way.nameID));
|
||||||
} else {
|
} else {
|
||||||
w.nameID = strit->second;
|
parsed_way.nameID = string_map_iterator->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(w.duration > 0) {
|
if(parsed_way.duration > 0) {
|
||||||
//TODO: iterate all way segments and set duration corresponding to the length of each segment
|
//TODO: iterate all way segments and set duration corresponding to the length of each segment
|
||||||
w.speed = w.duration/(w.path.size()-1);
|
parsed_way.speed = parsed_way.duration/(parsed_way.path.size()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fabs(-1. - w.speed) < FLT_EPSILON){
|
if(fabs(-1. - parsed_way.speed) < FLT_EPSILON){
|
||||||
WARN("found way with bogus speed, id: " << w.id);
|
WARN("found way with bogus speed, id: " << parsed_way.id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(w.id == UINT_MAX) {
|
if(parsed_way.id == UINT_MAX) {
|
||||||
WARN("found way with unknown type: " << w.id);
|
WARN("found way with unknown type: " << parsed_way.id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( w.direction == _Way::opposite ){
|
if ( parsed_way.direction == ExtractionWay::opposite ){
|
||||||
std::reverse( w.path.begin(), w.path.end() );
|
std::reverse( parsed_way.path.begin(), parsed_way.path.end() );
|
||||||
|
parsed_way.direction = ExtractionWay::oneway;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::vector< NodeID >::size_type n = 0; n < w.path.size()-1; ++n) {
|
bool split_bidirectional_edge = (parsed_way.backward_speed > 0) && (parsed_way.speed != parsed_way.backward_speed);
|
||||||
externalMemory->allEdges.push_back(_Edge(w.path[n], w.path[n+1], w.type, w.direction, w.speed, w.nameID, w.roundabout, w.ignoreInGrid, (w.duration > 0), w.isAccessRestricted));
|
|
||||||
externalMemory->usedNodeIDs.push_back(w.path[n]);
|
for(std::vector< NodeID >::size_type n = 0; n < parsed_way.path.size()-1; ++n) {
|
||||||
|
externalMemory->allEdges.push_back(
|
||||||
|
InternalExtractorEdge(parsed_way.path[n],
|
||||||
|
parsed_way.path[n+1],
|
||||||
|
parsed_way.type,
|
||||||
|
(split_bidirectional_edge ? ExtractionWay::oneway : parsed_way.direction),
|
||||||
|
parsed_way.speed,
|
||||||
|
parsed_way.nameID,
|
||||||
|
parsed_way.roundabout,
|
||||||
|
parsed_way.ignoreInGrid,
|
||||||
|
(0 < parsed_way.duration),
|
||||||
|
parsed_way.isAccessRestricted
|
||||||
|
)
|
||||||
|
);
|
||||||
|
externalMemory->usedNodeIDs.push_back(parsed_way.path[n]);
|
||||||
}
|
}
|
||||||
externalMemory->usedNodeIDs.push_back(w.path.back());
|
externalMemory->usedNodeIDs.push_back(parsed_way.path.back());
|
||||||
|
|
||||||
//The following information is needed to identify start and end segments of restrictions
|
//The following information is needed to identify start and end segments of restrictions
|
||||||
externalMemory->wayStartEndVector.push_back(_WayIDStartAndEndEdge(w.id, w.path[0], w.path[1], w.path[w.path.size()-2], w.path[w.path.size()-1]));
|
externalMemory->wayStartEndVector.push_back(_WayIDStartAndEndEdge(parsed_way.id, parsed_way.path[0], parsed_way.path[1], parsed_way.path[parsed_way.path.size()-2], parsed_way.path.back()));
|
||||||
|
|
||||||
|
if ( split_bidirectional_edge) { //Only true if the way should be split
|
||||||
|
std::reverse( parsed_way.path.begin(), parsed_way.path.end() );
|
||||||
|
for(std::vector< NodeID >::size_type n = 0; n < parsed_way.path.size()-1; ++n) {
|
||||||
|
externalMemory->allEdges.push_back(
|
||||||
|
InternalExtractorEdge(parsed_way.path[n],
|
||||||
|
parsed_way.path[n+1],
|
||||||
|
parsed_way.type,
|
||||||
|
ExtractionWay::oneway,
|
||||||
|
parsed_way.backward_speed,
|
||||||
|
parsed_way.nameID,
|
||||||
|
parsed_way.roundabout,
|
||||||
|
parsed_way.ignoreInGrid,
|
||||||
|
(0 < parsed_way.duration),
|
||||||
|
parsed_way.isAccessRestricted,
|
||||||
|
(ExtractionWay::oneway == parsed_way.direction)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
externalMemory->wayStartEndVector.push_back(_WayIDStartAndEndEdge(parsed_way.id, parsed_way.path[0], parsed_way.path[1], parsed_way.path[parsed_way.path.size()-2], parsed_way.path.back()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
bool restrictionFunction(_RawRestrictionContainer &r);
|
bool restrictionFunction(_RawRestrictionContainer &r);
|
||||||
|
|
||||||
/** warning: caller needs to take care of synchronization! */
|
/** warning: caller needs to take care of synchronization! */
|
||||||
bool wayFunction(_Way &w);
|
bool wayFunction(ExtractionWay &w);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
typedef boost::unordered_map<std::string, NodeID > StringMap;
|
typedef boost::unordered_map<std::string, NodeID > StringMap;
|
||||||
typedef boost::unordered_map<std::string, std::pair<int, short> > StringToIntPairMap;
|
typedef boost::unordered_map<std::string, std::pair<int, short> > StringToIntPairMap;
|
||||||
|
|
||||||
struct _Way {
|
struct ExtractionWay {
|
||||||
_Way() {
|
ExtractionWay() {
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,8 +50,9 @@ struct _Way {
|
|||||||
nameID = UINT_MAX;
|
nameID = UINT_MAX;
|
||||||
path.clear();
|
path.clear();
|
||||||
keyVals.EraseAll();
|
keyVals.EraseAll();
|
||||||
direction = _Way::notSure;
|
direction = ExtractionWay::notSure;
|
||||||
speed = -1;
|
speed = -1;
|
||||||
|
backward_speed = -1;
|
||||||
duration = -1;
|
duration = -1;
|
||||||
type = -1;
|
type = -1;
|
||||||
access = true;
|
access = true;
|
||||||
@ -67,6 +68,7 @@ struct _Way {
|
|||||||
unsigned nameID;
|
unsigned nameID;
|
||||||
std::string name;
|
std::string name;
|
||||||
double speed;
|
double speed;
|
||||||
|
double backward_speed;
|
||||||
double duration;
|
double duration;
|
||||||
short type;
|
short type;
|
||||||
bool access;
|
bool access;
|
||||||
@ -77,19 +79,22 @@ struct _Way {
|
|||||||
HashTable<std::string, std::string> keyVals;
|
HashTable<std::string, std::string> keyVals;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Relation {
|
struct ExtractorRelation {
|
||||||
_Relation() : type(unknown){}
|
ExtractorRelation() : type(unknown){}
|
||||||
enum {
|
enum {
|
||||||
unknown = 0, ferry, turnRestriction
|
unknown = 0, ferry, turnRestriction
|
||||||
} type;
|
} type;
|
||||||
HashTable<std::string, std::string> keyVals;
|
HashTable<std::string, std::string> keyVals;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Edge {
|
struct InternalExtractorEdge {
|
||||||
_Edge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) {};
|
InternalExtractorEdge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) {};
|
||||||
_Edge(NodeID s, NodeID t) : start(s), target(t), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) { }
|
InternalExtractorEdge(NodeID s, NodeID t) : start(s), target(t), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) { }
|
||||||
_Edge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) { }
|
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) { }
|
||||||
_Edge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar) {
|
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar), isContraFlow(false) {
|
||||||
|
assert(0 <= type);
|
||||||
|
}
|
||||||
|
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar, bool icf): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar), isContraFlow(icf) {
|
||||||
assert(0 <= type);
|
assert(0 <= type);
|
||||||
}
|
}
|
||||||
NodeID start;
|
NodeID start;
|
||||||
@ -102,19 +107,21 @@ struct _Edge {
|
|||||||
bool ignoreInGrid;
|
bool ignoreInGrid;
|
||||||
bool isDurationSet;
|
bool isDurationSet;
|
||||||
bool isAccessRestricted;
|
bool isAccessRestricted;
|
||||||
|
bool isContraFlow;
|
||||||
|
|
||||||
_Coordinate startCoord;
|
_Coordinate startCoord;
|
||||||
_Coordinate targetCoord;
|
_Coordinate targetCoord;
|
||||||
|
|
||||||
static _Edge min_value() {
|
static InternalExtractorEdge min_value() {
|
||||||
return _Edge(0,0);
|
return InternalExtractorEdge(0,0);
|
||||||
}
|
}
|
||||||
static _Edge max_value() {
|
static InternalExtractorEdge max_value() {
|
||||||
return _Edge((std::numeric_limits<unsigned>::max)(), (std::numeric_limits<unsigned>::max)());
|
return InternalExtractorEdge((std::numeric_limits<unsigned>::max)(), (std::numeric_limits<unsigned>::max)());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct _WayIDStartAndEndEdge {
|
struct _WayIDStartAndEndEdge {
|
||||||
unsigned wayID;
|
unsigned wayID;
|
||||||
NodeID firstStart;
|
NodeID firstStart;
|
||||||
@ -171,34 +178,29 @@ struct CmpNodeByID : public std::binary_function<_Node, _Node, bool> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmpEdgeByStartID : public std::binary_function<_Edge, _Edge, bool>
|
struct CmpEdgeByStartID : public std::binary_function<InternalExtractorEdge, InternalExtractorEdge, bool> {
|
||||||
{
|
typedef InternalExtractorEdge value_type;
|
||||||
typedef _Edge value_type;
|
bool operator () (const InternalExtractorEdge & a, const InternalExtractorEdge & b) const {
|
||||||
bool operator () (const _Edge & a, const _Edge & b) const {
|
|
||||||
return a.start < b.start;
|
return a.start < b.start;
|
||||||
}
|
}
|
||||||
value_type max_value() {
|
value_type max_value() {
|
||||||
return _Edge::max_value();
|
return InternalExtractorEdge::max_value();
|
||||||
}
|
}
|
||||||
value_type min_value() {
|
value_type min_value() {
|
||||||
return _Edge::min_value();
|
return InternalExtractorEdge::min_value();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmpEdgeByTargetID : public std::binary_function<_Edge, _Edge, bool>
|
struct CmpEdgeByTargetID : public std::binary_function<InternalExtractorEdge, InternalExtractorEdge, bool> {
|
||||||
{
|
typedef InternalExtractorEdge value_type;
|
||||||
typedef _Edge value_type;
|
bool operator () (const InternalExtractorEdge & a, const InternalExtractorEdge & b) const {
|
||||||
bool operator () (const _Edge & a, const _Edge & b) const
|
|
||||||
{
|
|
||||||
return a.target < b.target;
|
return a.target < b.target;
|
||||||
}
|
}
|
||||||
value_type max_value()
|
value_type max_value() {
|
||||||
{
|
return InternalExtractorEdge::max_value();
|
||||||
return _Edge::max_value();
|
|
||||||
}
|
}
|
||||||
value_type min_value()
|
value_type min_value() {
|
||||||
{
|
return InternalExtractorEdge::min_value();
|
||||||
return _Edge::min_value();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -332,8 +332,8 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::parseWay(_ThreadData * threadData) {
|
inline void PBFParser::parseWay(_ThreadData * threadData) {
|
||||||
_Way w;
|
ExtractionWay w;
|
||||||
std::vector<_Way> waysToParse(threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size());
|
std::vector<ExtractionWay> waysToParse(threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size());
|
||||||
for(int i = 0, ways_size = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i < ways_size; ++i) {
|
for(int i = 0, ways_size = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i < ways_size; ++i) {
|
||||||
w.Clear();
|
w.Clear();
|
||||||
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
|
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
|
||||||
@ -356,7 +356,7 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
|
|||||||
unsigned endi_ways = waysToParse.size();
|
unsigned endi_ways = waysToParse.size();
|
||||||
#pragma omp parallel for schedule ( guided )
|
#pragma omp parallel for schedule ( guided )
|
||||||
for(unsigned i = 0; i < endi_ways; ++i) {
|
for(unsigned i = 0; i < endi_ways; ++i) {
|
||||||
_Way & w = waysToParse[i];
|
ExtractionWay & w = waysToParse[i];
|
||||||
/** Pass the unpacked way to the LUA call back **/
|
/** Pass the unpacked way to the LUA call back **/
|
||||||
try {
|
try {
|
||||||
luabind::call_function<int>(
|
luabind::call_function<int>(
|
||||||
@ -376,7 +376,7 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(_Way & w, waysToParse) {
|
BOOST_FOREACH(ExtractionWay & w, waysToParse) {
|
||||||
if(!externalMemory->wayFunction(w)) {
|
if(!externalMemory->wayFunction(w)) {
|
||||||
std::cerr << "[PBFParser] way not parsed" << std::endl;
|
std::cerr << "[PBFParser] way not parsed" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#include "ExtractorStructs.h"
|
#include "ExtractorStructs.h"
|
||||||
#include "ScriptingEnvironment.h"
|
#include "ScriptingEnvironment.h"
|
||||||
|
|
||||||
class PBFParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> {
|
class PBFParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, ExtractionWay> {
|
||||||
|
|
||||||
enum EntityType {
|
enum EntityType {
|
||||||
TypeNode = 1,
|
TypeNode = 1,
|
||||||
|
@ -65,18 +65,19 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
luabind::module(myLuaState) [
|
luabind::module(myLuaState) [
|
||||||
luabind::class_<_Way>("Way")
|
luabind::class_<ExtractionWay>("Way")
|
||||||
.def(luabind::constructor<>())
|
.def(luabind::constructor<>())
|
||||||
.def_readwrite("name", &_Way::name)
|
.def_readwrite("name", &ExtractionWay::name)
|
||||||
.def_readwrite("speed", &_Way::speed)
|
.def_readwrite("speed", &ExtractionWay::speed)
|
||||||
.def_readwrite("duration", &_Way::duration)
|
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
|
||||||
.def_readwrite("type", &_Way::type)
|
.def_readwrite("duration", &ExtractionWay::duration)
|
||||||
.def_readwrite("access", &_Way::access)
|
.def_readwrite("type", &ExtractionWay::type)
|
||||||
.def_readwrite("roundabout", &_Way::roundabout)
|
.def_readwrite("access", &ExtractionWay::access)
|
||||||
.def_readwrite("is_access_restricted", &_Way::isAccessRestricted)
|
.def_readwrite("roundabout", &ExtractionWay::roundabout)
|
||||||
.def_readwrite("ignore_in_grid", &_Way::ignoreInGrid)
|
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
|
||||||
.def_readwrite("tags", &_Way::keyVals)
|
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
|
||||||
.def_readwrite("direction", &_Way::direction)
|
.def_readwrite("tags", &ExtractionWay::keyVals)
|
||||||
|
.def_readwrite("direction", &ExtractionWay::direction)
|
||||||
.enum_("constants")
|
.enum_("constants")
|
||||||
[
|
[
|
||||||
luabind::value("notSure", 0),
|
luabind::value("notSure", 0),
|
||||||
|
@ -100,7 +100,7 @@ bool XMLParser::Parse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
|
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
|
||||||
_Way way = _ReadXMLWay( );
|
ExtractionWay way = _ReadXMLWay( );
|
||||||
|
|
||||||
/** Pass the unpacked way to the LUA call back **/
|
/** Pass the unpacked way to the LUA call back **/
|
||||||
try {
|
try {
|
||||||
@ -221,8 +221,8 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
|
|||||||
return restriction;
|
return restriction;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Way XMLParser::_ReadXMLWay() {
|
ExtractionWay XMLParser::_ReadXMLWay() {
|
||||||
_Way way;
|
ExtractionWay way;
|
||||||
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
|
||||||
const int depth = xmlTextReaderDepth( inputReader );
|
const int depth = xmlTextReaderDepth( inputReader );
|
||||||
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
while ( xmlTextReaderRead( inputReader ) == 1 ) {
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "ExtractorCallbacks.h"
|
#include "ExtractorCallbacks.h"
|
||||||
#include "ScriptingEnvironment.h"
|
#include "ScriptingEnvironment.h"
|
||||||
|
|
||||||
class XMLParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> {
|
class XMLParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, ExtractionWay> {
|
||||||
public:
|
public:
|
||||||
XMLParser(const char * filename);
|
XMLParser(const char * filename);
|
||||||
virtual ~XMLParser();
|
virtual ~XMLParser();
|
||||||
@ -39,7 +39,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
_RawRestrictionContainer _ReadXMLRestriction();
|
_RawRestrictionContainer _ReadXMLRestriction();
|
||||||
_Way _ReadXMLWay();
|
ExtractionWay _ReadXMLWay();
|
||||||
ImportNode _ReadXMLNode( );
|
ImportNode _ReadXMLNode( );
|
||||||
/* Input Reader */
|
/* Input Reader */
|
||||||
xmlTextReaderPtr inputReader;
|
xmlTextReaderPtr inputReader;
|
||||||
|
@ -101,7 +101,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
|
|||||||
short type;
|
short type;
|
||||||
NodeID nameID;
|
NodeID nameID;
|
||||||
int length;
|
int length;
|
||||||
bool isRoundabout, ignoreInGrid, isAccessRestricted;
|
bool isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow;
|
||||||
|
|
||||||
for (EdgeID i=0; i<m; ++i) {
|
for (EdgeID i=0; i<m; ++i) {
|
||||||
in.read((char*)&source, sizeof(unsigned));
|
in.read((char*)&source, sizeof(unsigned));
|
||||||
@ -114,6 +114,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
|
|||||||
in.read((char*)&isRoundabout, sizeof(bool));
|
in.read((char*)&isRoundabout, sizeof(bool));
|
||||||
in.read((char*)&ignoreInGrid, sizeof(bool));
|
in.read((char*)&ignoreInGrid, sizeof(bool));
|
||||||
in.read((char*)&isAccessRestricted, sizeof(bool));
|
in.read((char*)&isAccessRestricted, sizeof(bool));
|
||||||
|
in.read((char*)&isContraFlow, sizeof(bool));
|
||||||
|
|
||||||
GUARANTEE(length > 0, "loaded null length edge" );
|
GUARANTEE(length > 0, "loaded null length edge" );
|
||||||
GUARANTEE(weight > 0, "loaded null weight");
|
GUARANTEE(weight > 0, "loaded null weight");
|
||||||
@ -150,7 +151,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
|
|||||||
std::swap(forward, backward);
|
std::swap(forward, backward);
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid, isAccessRestricted );
|
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow );
|
||||||
edgeList.push_back(inputEdge);
|
edgeList.push_back(inputEdge);
|
||||||
}
|
}
|
||||||
std::sort(edgeList.begin(), edgeList.end());
|
std::sort(edgeList.begin(), edgeList.end());
|
||||||
|
@ -58,7 +58,6 @@ int main (int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
omp_set_num_threads(numberOfThreads);
|
omp_set_num_threads(numberOfThreads);
|
||||||
|
|
||||||
|
|
||||||
INFO("extracting data from input file " << argv[1]);
|
INFO("extracting data from input file " << argv[1]);
|
||||||
bool isPBF(false);
|
bool isPBF(false);
|
||||||
std::string outputFileName(argv[1]);
|
std::string outputFileName(argv[1]);
|
||||||
@ -93,10 +92,9 @@ int main (int argc, char *argv[]) {
|
|||||||
StringMap stringMap;
|
StringMap stringMap;
|
||||||
ExtractionContainers externalMemory;
|
ExtractionContainers externalMemory;
|
||||||
|
|
||||||
|
|
||||||
stringMap[""] = 0;
|
stringMap[""] = 0;
|
||||||
extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap);
|
extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap);
|
||||||
BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> * parser;
|
BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, ExtractionWay> * parser;
|
||||||
if(isPBF) {
|
if(isPBF) {
|
||||||
parser = new PBFParser(argv[1]);
|
parser = new PBFParser(argv[1]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
@routing @bicycle @access
|
@routing @bicycle @access
|
||||||
Feature: Bike - Restricted access
|
Feature: Bike - Access tags on ways
|
||||||
Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
@ -7,37 +7,95 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
|||||||
|
|
||||||
Scenario: Bike - Access tag hierachy on ways
|
Scenario: Bike - Access tag hierachy on ways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| access | vehicle | bicycle | bothw |
|
| highway | access | vehicle | bicycle | bothw |
|
||||||
| | | | x |
|
| | | | | x |
|
||||||
| yes | | | x |
|
| | yes | | | x |
|
||||||
| no | | | |
|
| | no | | | |
|
||||||
| | yes | | x |
|
| | | yes | | x |
|
||||||
| | no | | |
|
| | | no | | |
|
||||||
| no | yes | | x |
|
| | no | yes | | x |
|
||||||
| yes | no | | |
|
| | yes | no | | |
|
||||||
| | | yes | x |
|
| | | | yes | x |
|
||||||
| | | no | |
|
| | | | no | |
|
||||||
| no | | yes | x |
|
| | no | | yes | x |
|
||||||
| yes | | no | |
|
| | yes | | no | |
|
||||||
| | no | yes | x |
|
| | | no | yes | x |
|
||||||
| | yes | no | |
|
| | | yes | no | |
|
||||||
|
| runway | | | | |
|
||||||
|
| runway | yes | | | x |
|
||||||
|
| runway | no | | | |
|
||||||
|
| runway | | yes | | x |
|
||||||
|
| runway | | no | | |
|
||||||
|
| runway | no | yes | | x |
|
||||||
|
| runway | yes | no | | |
|
||||||
|
| runway | | | yes | x |
|
||||||
|
| runway | | | no | |
|
||||||
|
| runway | no | | yes | x |
|
||||||
|
| runway | yes | | no | |
|
||||||
|
| runway | | no | yes | x |
|
||||||
|
| runway | | yes | no | |
|
||||||
|
|
||||||
Scenario: Bike - Access tag hierachy on nodes
|
@todo
|
||||||
Then routability should be
|
Scenario: Bike - Access tag in forward direction
|
||||||
| node/access | node/vehicle | node/bicycle | bothw |
|
Then routability should be
|
||||||
| | | | x |
|
| highway | access:forward | vehicle:forward | bicycle:forward | forw | backw |
|
||||||
| yes | | | x |
|
| | | | | x | |
|
||||||
| no | | | |
|
| | yes | | | x | |
|
||||||
| | yes | | x |
|
| | no | | | | |
|
||||||
| | no | | |
|
| | | yes | | x | |
|
||||||
| no | yes | | x |
|
| | | no | | | |
|
||||||
| yes | no | | |
|
| | no | yes | | x | |
|
||||||
| | | yes | x |
|
| | yes | no | | | |
|
||||||
| | | no | |
|
| | | | yes | x | |
|
||||||
| no | | yes | x |
|
| | | | no | | |
|
||||||
| yes | | no | |
|
| | no | | yes | x | |
|
||||||
| | no | yes | x |
|
| | yes | | no | | |
|
||||||
| | yes | no | |
|
| | | no | yes | x | |
|
||||||
|
| | | yes | no | | |
|
||||||
|
| runway | | | | x | |
|
||||||
|
| runway | yes | | | x | |
|
||||||
|
| runway | no | | | | |
|
||||||
|
| runway | | yes | | x | |
|
||||||
|
| runway | | no | | | |
|
||||||
|
| runway | no | yes | | x | |
|
||||||
|
| runway | yes | no | | | |
|
||||||
|
| runway | | | yes | x | |
|
||||||
|
| runway | | | no | | |
|
||||||
|
| runway | no | | yes | x | |
|
||||||
|
| runway | yes | | no | | |
|
||||||
|
| runway | | no | yes | x | |
|
||||||
|
| runway | | yes | no | | |
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Scenario: Bike - Access tag in backward direction
|
||||||
|
Then routability should be
|
||||||
|
| highway | access:forward | vehicle:forward | bicycle:forward | forw | backw |
|
||||||
|
| | | | | | x |
|
||||||
|
| | yes | | | | x |
|
||||||
|
| | no | | | | |
|
||||||
|
| | | yes | | | x |
|
||||||
|
| | | no | | | |
|
||||||
|
| | no | yes | | | x |
|
||||||
|
| | yes | no | | | |
|
||||||
|
| | | | yes | | x |
|
||||||
|
| | | | no | | |
|
||||||
|
| | no | | yes | | x |
|
||||||
|
| | yes | | no | | |
|
||||||
|
| | | no | yes | | x |
|
||||||
|
| | | yes | no | | |
|
||||||
|
| runway | | | | | x |
|
||||||
|
| runway | yes | | | | x |
|
||||||
|
| runway | no | | | | |
|
||||||
|
| runway | | yes | | | x |
|
||||||
|
| runway | | no | | | |
|
||||||
|
| runway | no | yes | | | x |
|
||||||
|
| runway | yes | no | | | |
|
||||||
|
| runway | | | yes | | x |
|
||||||
|
| runway | | | no | | |
|
||||||
|
| runway | no | | yes | | x |
|
||||||
|
| runway | yes | | no | | |
|
||||||
|
| runway | | no | yes | | x |
|
||||||
|
| runway | | yes | no | | |
|
||||||
|
|
||||||
Scenario: Bike - Overwriting implied acccess on ways
|
Scenario: Bike - Overwriting implied acccess on ways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
@ -51,18 +109,6 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
|||||||
| runway | | yes | | x |
|
| runway | | yes | | x |
|
||||||
| runway | | | yes | x |
|
| runway | | | yes | x |
|
||||||
|
|
||||||
Scenario: Bike - Overwriting implied acccess on nodes
|
|
||||||
Then routability should be
|
|
||||||
| highway | node/access | node/vehicle | node/bicycle | bothw |
|
|
||||||
| cycleway | | | | x |
|
|
||||||
| runway | | | | |
|
|
||||||
| cycleway | no | | | |
|
|
||||||
| cycleway | | no | | |
|
|
||||||
| cycleway | | | no | |
|
|
||||||
| runway | yes | | | |
|
|
||||||
| runway | | yes | | |
|
|
||||||
| runway | | | yes | |
|
|
||||||
|
|
||||||
Scenario: Bike - Access tags on ways
|
Scenario: Bike - Access tags on ways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| access | vehicle | bicycle | bothw |
|
| access | vehicle | bicycle | bothw |
|
||||||
@ -92,35 +138,6 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
|||||||
| | | agricultural | |
|
| | | agricultural | |
|
||||||
| | | forestery | |
|
| | | forestery | |
|
||||||
|
|
||||||
Scenario: Bike - Access tags on nodes
|
|
||||||
Then routability should be
|
|
||||||
| node/access | node/vehicle | node/bicycle | bothw |
|
|
||||||
| | | | x |
|
|
||||||
| yes | | | x |
|
|
||||||
| permissive | | | x |
|
|
||||||
| designated | | | x |
|
|
||||||
| some_tag | | | x |
|
|
||||||
| no | | | |
|
|
||||||
| private | | | |
|
|
||||||
| agricultural | | | |
|
|
||||||
| forestery | | | |
|
|
||||||
| | yes | | x |
|
|
||||||
| | permissive | | x |
|
|
||||||
| | designated | | x |
|
|
||||||
| | some_tag | | x |
|
|
||||||
| | no | | |
|
|
||||||
| | private | | |
|
|
||||||
| | agricultural | | |
|
|
||||||
| | forestery | | |
|
|
||||||
| | | yes | x |
|
|
||||||
| | | permissive | x |
|
|
||||||
| | | designated | x |
|
|
||||||
| | | some_tag | x |
|
|
||||||
| | | no | |
|
|
||||||
| | | private | |
|
|
||||||
| | | agricultural | |
|
|
||||||
| | | forestery | |
|
|
||||||
|
|
||||||
Scenario: Bike - Access tags on both node and way
|
Scenario: Bike - Access tags on both node and way
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| access | node/access | bothw |
|
| access | node/access | bothw |
|
||||||
@ -147,10 +164,10 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
|||||||
|
|
||||||
Scenario: Bike - Ignore access tags for other modes
|
Scenario: Bike - Ignore access tags for other modes
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| highway | foot | motor_vehicle | moped | bothw |
|
| highway | boat | motor_vehicle | moped | bothw |
|
||||||
| runway | yes | | | |
|
| river | yes | | | |
|
||||||
| cycleway | no | | | x |
|
| cycleway | no | | | x |
|
||||||
| runway | | yes | | |
|
| runway | | yes | | |
|
||||||
| cycleway | | no | | x |
|
| cycleway | | no | | x |
|
||||||
| runway | | | yes | |
|
| runway | | | yes | |
|
||||||
| cycleway | | | no | x |
|
| cycleway | | | no | x |
|
||||||
|
64
features/bicycle/access_node.feature
Normal file
64
features/bicycle/access_node.feature
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
@routing @bicycle @access
|
||||||
|
Feature: Bike - Access tags on nodes
|
||||||
|
Reference: http://wiki.openstreetmap.org/wiki/Key:access
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the profile "bicycle"
|
||||||
|
|
||||||
|
Scenario: Bike - Access tag hierachy on nodes
|
||||||
|
Then routability should be
|
||||||
|
| node/access | node/vehicle | node/bicycle | bothw |
|
||||||
|
| | | | x |
|
||||||
|
| yes | | | x |
|
||||||
|
| no | | | |
|
||||||
|
| | yes | | x |
|
||||||
|
| | no | | |
|
||||||
|
| no | yes | | x |
|
||||||
|
| yes | no | | |
|
||||||
|
| | | yes | x |
|
||||||
|
| | | no | |
|
||||||
|
| no | | yes | x |
|
||||||
|
| yes | | no | |
|
||||||
|
| | no | yes | x |
|
||||||
|
| | yes | no | |
|
||||||
|
|
||||||
|
Scenario: Bike - Overwriting implied acccess on nodes
|
||||||
|
Then routability should be
|
||||||
|
| highway | node/access | node/vehicle | node/bicycle | bothw |
|
||||||
|
| cycleway | | | | x |
|
||||||
|
| runway | | | | |
|
||||||
|
| cycleway | no | | | |
|
||||||
|
| cycleway | | no | | |
|
||||||
|
| cycleway | | | no | |
|
||||||
|
| runway | yes | | | |
|
||||||
|
| runway | | yes | | |
|
||||||
|
| runway | | | yes | |
|
||||||
|
|
||||||
|
Scenario: Bike - Access tags on nodes
|
||||||
|
Then routability should be
|
||||||
|
| node/access | node/vehicle | node/bicycle | bothw |
|
||||||
|
| | | | x |
|
||||||
|
| yes | | | x |
|
||||||
|
| permissive | | | x |
|
||||||
|
| designated | | | x |
|
||||||
|
| some_tag | | | x |
|
||||||
|
| no | | | |
|
||||||
|
| private | | | |
|
||||||
|
| agricultural | | | |
|
||||||
|
| forestery | | | |
|
||||||
|
| | yes | | x |
|
||||||
|
| | permissive | | x |
|
||||||
|
| | designated | | x |
|
||||||
|
| | some_tag | | x |
|
||||||
|
| | no | | |
|
||||||
|
| | private | | |
|
||||||
|
| | agricultural | | |
|
||||||
|
| | forestery | | |
|
||||||
|
| | | yes | x |
|
||||||
|
| | | permissive | x |
|
||||||
|
| | | designated | x |
|
||||||
|
| | | some_tag | x |
|
||||||
|
| | | no | |
|
||||||
|
| | | private | |
|
||||||
|
| | | agricultural | |
|
||||||
|
| | | forestery | |
|
@ -29,16 +29,16 @@ Reference: http://wiki.openstreetmap.org/wiki/Key:cycleway
|
|||||||
Then routability should be
|
Then routability should be
|
||||||
| highway | cycleway | cycleway:left | cycleway:right | forw | backw |
|
| highway | cycleway | cycleway:left | cycleway:right | forw | backw |
|
||||||
| primary | | | | x | x |
|
| primary | | | | x | x |
|
||||||
| pirmary | track | | | x | x |
|
| primary | track | | | x | x |
|
||||||
| pirmary | opposite | | | x | x |
|
| primary | opposite | | | x | x |
|
||||||
| pirmary | | track | | x | x |
|
| primary | | track | | x | x |
|
||||||
| pirmary | | opposite | | x | x |
|
| primary | | opposite | | x | x |
|
||||||
| pirmary | | | track | x | x |
|
| primary | | | track | x | x |
|
||||||
| pirmary | | | opposite | x | x |
|
| primary | | | opposite | x | x |
|
||||||
| pirmary | | track | track | x | x |
|
| primary | | track | track | x | x |
|
||||||
| pirmary | | opposite | opposite | x | x |
|
| primary | | opposite | opposite | x | x |
|
||||||
| pirmary | | track | opposite | x | x |
|
| primary | | track | opposite | x | x |
|
||||||
| pirmary | | opposite | track | x | x |
|
| primary | | opposite | track | x | x |
|
||||||
|
|
||||||
Scenario: Bike - Left/right side cycleways on implied oneways
|
Scenario: Bike - Left/right side cycleways on implied oneways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
|
@ -36,3 +36,35 @@ Feature: Bike - Max speed restrictions
|
|||||||
| residential | | 40s ~10% |
|
| residential | | 40s ~10% |
|
||||||
| residential | none | 40s ~10% |
|
| residential | none | 40s ~10% |
|
||||||
| residential | signals | 40s ~10% |
|
| residential | signals | 40s ~10% |
|
||||||
|
|
||||||
|
Scenario: Bike - Do not use maxspeed when higher that way type speed
|
||||||
|
Given the node map
|
||||||
|
| a | b | c |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway | maxspeed |
|
||||||
|
| ab | residential | |
|
||||||
|
| bc | residential | 80 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route | time |
|
||||||
|
| a | b | ab | 20s ~5% |
|
||||||
|
| b | c | bc | 20s ~5% |
|
||||||
|
|
||||||
|
Scenario: Bike - Forward/backward maxspeed
|
||||||
|
Given the shortcuts
|
||||||
|
| key | value |
|
||||||
|
| bike | 43s ~10% |
|
||||||
|
| run | 73s ~10% |
|
||||||
|
| walk | 145s ~10% |
|
||||||
|
| snail | 720s ~10% |
|
||||||
|
|
||||||
|
Then routability should be
|
||||||
|
| maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
|
||||||
|
| | | | bike | bike |
|
||||||
|
| 10 | | | run | run |
|
||||||
|
| | 10 | | run | bike |
|
||||||
|
| | | 10 | bike | run |
|
||||||
|
| 1 | 10 | | run | snail |
|
||||||
|
| 1 | | 10 | snail | run |
|
||||||
|
| 1 | 5 | 10 | walk | run |
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
@routing @bicycle @oneway
|
@routing @bicycle @oneway
|
||||||
Feature: Bike - Oneway streets
|
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
|
||||||
|
Usually we can push bikes against oneways, but we use foot=no to prevent this in these tests
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the profile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Simple oneway
|
Scenario: Bike - Simple oneway
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| highway | oneway | forw | backw |
|
| highway | foot | oneway | forw | backw |
|
||||||
| primary | yes | x | |
|
| primary | no | yes | x | |
|
||||||
|
|
||||||
Scenario: Simple reverse oneway
|
Scenario: Simple reverse oneway
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| highway | oneway | forw | backw |
|
| highway | foot | oneway | forw | backw |
|
||||||
| primary | -1 | | x |
|
| primary | no | -1 | | x |
|
||||||
|
|
||||||
Scenario: Bike - Around the Block
|
Scenario: Bike - Around the Block
|
||||||
Given the node map
|
Given the node map
|
||||||
@ -21,11 +22,11 @@ Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tag
|
|||||||
| d | c |
|
| d | c |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| ab | yes |
|
| ab | yes | no |
|
||||||
| bc | |
|
| bc | | no |
|
||||||
| cd | |
|
| cd | | no |
|
||||||
| da | |
|
| da | | no |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route |
|
| from | to | route |
|
||||||
@ -34,80 +35,80 @@ Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tag
|
|||||||
|
|
||||||
Scenario: Bike - Handle various oneway tag values
|
Scenario: Bike - Handle various oneway tag values
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| oneway | forw | backw |
|
| foot | oneway | forw | backw |
|
||||||
| | x | x |
|
| no | | x | x |
|
||||||
| nonsense | x | x |
|
| no | nonsense | x | x |
|
||||||
| no | x | x |
|
| no | no | x | x |
|
||||||
| false | x | x |
|
| no | false | x | x |
|
||||||
| 0 | x | x |
|
| no | 0 | x | x |
|
||||||
| yes | x | |
|
| no | yes | x | |
|
||||||
| true | x | |
|
| no | true | x | |
|
||||||
| 1 | x | |
|
| no | 1 | x | |
|
||||||
| -1 | | x |
|
| no | -1 | | x |
|
||||||
|
|
||||||
Scenario: Bike - Implied oneways
|
Scenario: Bike - Implied oneways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| highway | bicycle | junction | forw | backw |
|
| highway | foot | bicycle | junction | forw | backw |
|
||||||
| | | | x | x |
|
| | no | | | x | x |
|
||||||
| | | roundabout | x | |
|
| | no | | roundabout | x | |
|
||||||
| motorway | yes | | x | |
|
| motorway | no | yes | | x | |
|
||||||
| motorway_link | yes | | x | |
|
| motorway_link | no | yes | | x | |
|
||||||
| motorway | yes | roundabout | x | |
|
| motorway | no | yes | roundabout | x | |
|
||||||
| motorway_link | yes | roundabout | x | |
|
| motorway_link | no | yes | roundabout | x | |
|
||||||
|
|
||||||
Scenario: Bike - Overriding implied oneways
|
Scenario: Bike - Overriding implied oneways
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| highway | junction | oneway | forw | backw |
|
| highway | foot | junction | oneway | forw | backw |
|
||||||
| primary | roundabout | no | x | x |
|
| primary | no | roundabout | no | x | x |
|
||||||
| primary | roundabout | yes | x | |
|
| primary | no | roundabout | yes | x | |
|
||||||
| motorway_link | | -1 | | |
|
| motorway_link | no | | -1 | | |
|
||||||
| trunk_link | | -1 | | |
|
| trunk_link | no | | -1 | | |
|
||||||
| primary | roundabout | -1 | | x |
|
| primary | no | roundabout | -1 | | x |
|
||||||
|
|
||||||
Scenario: Bike - Oneway:bicycle should override normal oneways tags
|
Scenario: Bike - Oneway:bicycle should override normal oneways tags
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| oneway:bicycle | oneway | junction | forw | backw |
|
| foot | oneway:bicycle | oneway | junction | forw | backw |
|
||||||
| yes | | | x | |
|
| no | yes | | | x | |
|
||||||
| yes | yes | | x | |
|
| no | yes | yes | | x | |
|
||||||
| yes | no | | x | |
|
| no | yes | no | | x | |
|
||||||
| yes | -1 | | x | |
|
| no | yes | -1 | | x | |
|
||||||
| yes | | roundabout | x | |
|
| no | yes | | roundabout | x | |
|
||||||
| no | | | x | x |
|
| no | no | | | x | x |
|
||||||
| no | yes | | x | x |
|
| no | no | yes | | x | x |
|
||||||
| no | no | | x | x |
|
| no | no | no | | x | x |
|
||||||
| no | -1 | | x | x |
|
| no | no | -1 | | x | x |
|
||||||
| no | | roundabout | x | x |
|
| no | no | | roundabout | x | x |
|
||||||
| -1 | | | | x |
|
| no | -1 | | | | x |
|
||||||
| -1 | yes | | | x |
|
| no | -1 | yes | | | x |
|
||||||
| -1 | no | | | x |
|
| no | -1 | no | | | x |
|
||||||
| -1 | -1 | | | x |
|
| no | -1 | -1 | | | x |
|
||||||
| -1 | | roundabout | | x |
|
| no | -1 | | roundabout | | x |
|
||||||
|
|
||||||
Scenario: Bike - Contra flow
|
Scenario: Bike - Contra flow
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| oneway | cycleway | forw | backw |
|
| foot | oneway | cycleway | forw | backw |
|
||||||
| yes | opposite | x | x |
|
| no | yes | opposite | x | x |
|
||||||
| yes | opposite_track | x | x |
|
| no | yes | opposite_track | x | x |
|
||||||
| yes | opposite_lane | x | x |
|
| no | yes | opposite_lane | x | x |
|
||||||
| -1 | opposite | x | x |
|
| no | -1 | opposite | x | x |
|
||||||
| -1 | opposite_track | x | x |
|
| no | -1 | opposite_track | x | x |
|
||||||
| -1 | opposite_lane | x | x |
|
| no | -1 | opposite_lane | x | x |
|
||||||
| no | opposite | x | x |
|
| no | no | opposite | x | x |
|
||||||
| no | opposite_track | x | x |
|
| no | no | opposite_track | x | x |
|
||||||
| no | opposite_lane | x | x |
|
| no | no | opposite_lane | x | x |
|
||||||
|
|
||||||
Scenario: Bike - Should not be affected by car tags
|
Scenario: Bike - Should not be affected by car tags
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| junction | oneway | oneway:car | forw | backw |
|
| foot | junction | oneway | oneway:car | forw | backw |
|
||||||
| | yes | yes | x | |
|
| no | | yes | yes | x | |
|
||||||
| | yes | no | x | |
|
| no | | yes | no | x | |
|
||||||
| | yes | -1 | x | |
|
| no | | yes | -1 | x | |
|
||||||
| | no | yes | x | x |
|
| no | | no | yes | x | x |
|
||||||
| | no | no | x | x |
|
| no | | no | no | x | x |
|
||||||
| | no | -1 | x | x |
|
| no | | no | -1 | x | x |
|
||||||
| | -1 | yes | | x |
|
| no | | -1 | yes | | x |
|
||||||
| | -1 | no | | x |
|
| no | | -1 | no | | x |
|
||||||
| | -1 | -1 | | x |
|
| no | | -1 | -1 | | x |
|
||||||
| roundabout | | yes | x | |
|
| no | roundabout | | yes | x | |
|
||||||
| roundabout | | no | x | |
|
| no | roundabout | | no | x | |
|
||||||
| roundabout | | -1 | x | |
|
| no | roundabout | | -1 | x | |
|
||||||
|
72
features/bicycle/pushing.feature
Normal file
72
features/bicycle/pushing.feature
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
@routing @bicycle @pushing
|
||||||
|
Feature: Bike - Accessability of different way types
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given the profile "bicycle"
|
||||||
|
Given the shortcuts
|
||||||
|
| key | value |
|
||||||
|
| bike | 40s ~20% |
|
||||||
|
| foot | 180s ~20% |
|
||||||
|
|
||||||
|
Scenario: Bike - Pushing bikes on pedestrian-only ways
|
||||||
|
Then routability should be
|
||||||
|
| highway | oneway | forw | backw |
|
||||||
|
| (nil) | | | |
|
||||||
|
| cycleway | | bike | bike |
|
||||||
|
| primary | | bike | bike |
|
||||||
|
| pedestrian | | foot | foot |
|
||||||
|
| footway | | foot | foot |
|
||||||
|
| primary | yes | bike | foot |
|
||||||
|
|
||||||
|
Scenario: Bike - Pushing bikes against normal oneways
|
||||||
|
Then routability should be
|
||||||
|
| highway | oneway | forw | backw |
|
||||||
|
| (nil) | | | |
|
||||||
|
| primary | yes | bike | foot |
|
||||||
|
| pedestrian | yes | foot | foot |
|
||||||
|
|
||||||
|
Scenario: Bike - Pushing bikes against reverse oneways
|
||||||
|
Then routability should be
|
||||||
|
| highway | oneway | forw | backw |
|
||||||
|
| (nil) | | | |
|
||||||
|
| primary | -1 | foot | bike |
|
||||||
|
| pedestrian | -1 | foot | foot |
|
||||||
|
|
||||||
|
@square
|
||||||
|
Scenario: Bike - Push bikes on pedestrian areas
|
||||||
|
Given the node map
|
||||||
|
| x | |
|
||||||
|
| a | b |
|
||||||
|
| d | c |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | area | highway |
|
||||||
|
| xa | | primary |
|
||||||
|
| abcda | yes | pedestrian |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route |
|
||||||
|
| a | b | abcda |
|
||||||
|
| a | d | abcda |
|
||||||
|
| b | c | abcda |
|
||||||
|
| c | b | abcda |
|
||||||
|
| c | d | abcda |
|
||||||
|
| d | c | abcda |
|
||||||
|
| d | a | abcda |
|
||||||
|
| a | d | abcda |
|
||||||
|
|
||||||
|
Scenario: Bike - Pushing bikes on ways with foot=yes
|
||||||
|
Then routability should be
|
||||||
|
| highway | foot | bothw |
|
||||||
|
| motorway | | |
|
||||||
|
| motorway | yes | foot |
|
||||||
|
| runway | | |
|
||||||
|
| runway | yes | foot |
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Scenario: Bike - Pushing bikes on ways with foot=yes in one direction
|
||||||
|
Then routability should be
|
||||||
|
| highway | foot:forward | foot:backward | forw | backw |
|
||||||
|
| motorway | | | | |
|
||||||
|
| motorway | yes | | foot | |
|
||||||
|
| motorway | | yes | | foot |
|
@ -3,7 +3,7 @@ Feature: Bike - Turn restrictions
|
|||||||
Handle turn restrictions as defined by http://wiki.openstreetmap.org/wiki/Relation:restriction
|
Handle turn restrictions as defined by http://wiki.openstreetmap.org/wiki/Relation:restriction
|
||||||
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:
|
||||||
Given the profile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
@no_turning
|
@no_turning
|
||||||
@ -14,11 +14,11 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| nj | -1 |
|
| nj | -1 | no |
|
||||||
| wj | -1 |
|
| wj | -1 | no |
|
||||||
| ej | -1 |
|
| ej | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction |
|
| type | way:from | way:to | node:via | restriction |
|
||||||
@ -38,11 +38,11 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| nj | -1 |
|
| nj | -1 | no |
|
||||||
| wj | -1 |
|
| wj | -1 | no |
|
||||||
| ej | -1 |
|
| ej | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction |
|
| type | way:from | way:to | node:via | restriction |
|
||||||
@ -62,11 +62,11 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| nj | -1 |
|
| nj | -1 | no |
|
||||||
| wj | -1 |
|
| wj | -1 | no |
|
||||||
| ej | -1 |
|
| ej | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction |
|
| type | way:from | way:to | node:via | restriction |
|
||||||
@ -86,11 +86,11 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| nj | -1 |
|
| nj | -1 | no |
|
||||||
| wj | -1 |
|
| wj | -1 | no |
|
||||||
| ej | -1 |
|
| ej | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction |
|
| type | way:from | way:to | node:via | restriction |
|
||||||
@ -110,11 +110,11 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| nj | -1 |
|
| nj | -1 | no |
|
||||||
| wj | -1 |
|
| wj | -1 | no |
|
||||||
| ej | -1 |
|
| ej | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction |
|
| type | way:from | way:to | node:via | restriction |
|
||||||
@ -134,11 +134,11 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| nj | -1 |
|
| nj | -1 | no |
|
||||||
| wj | -1 |
|
| wj | -1 | no |
|
||||||
| ej | -1 |
|
| ej | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction |
|
| type | way:from | way:to | node:via | restriction |
|
||||||
@ -158,11 +158,11 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| nj | -1 |
|
| nj | -1 | no |
|
||||||
| wj | -1 |
|
| wj | -1 | no |
|
||||||
| ej | -1 |
|
| ej | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction |
|
| type | way:from | way:to | node:via | restriction |
|
||||||
@ -182,11 +182,11 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| nj | -1 |
|
| nj | -1 | no |
|
||||||
| wj | -1 |
|
| wj | -1 | no |
|
||||||
| ej | -1 |
|
| ej | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction |
|
| type | way:from | way:to | node:via | restriction |
|
||||||
@ -206,13 +206,13 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | no |
|
| sj | no | no |
|
||||||
| xj | -1 |
|
| xj | -1 | no |
|
||||||
| aj | -1 |
|
| aj | -1 | no |
|
||||||
| bj | no |
|
| bj | no | no |
|
||||||
| cj | -1 |
|
| cj | -1 | no |
|
||||||
| dj | -1 |
|
| dj | -1 | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction | except |
|
| type | way:from | way:to | node:via | restriction | except |
|
||||||
@ -236,10 +236,10 @@ Feature: Bike - Turn restrictions
|
|||||||
| | s | |
|
| | s | |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| aj | no |
|
| aj | no | no |
|
||||||
| bj | no |
|
| bj | no | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction | except |
|
| type | way:from | way:to | node:via | restriction | except |
|
||||||
@ -261,14 +261,14 @@ Feature: Bike - Turn restrictions
|
|||||||
| | | f |
|
| | | f |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | oneway |
|
| nodes | oneway | foot |
|
||||||
| sj | yes |
|
| sj | yes | no |
|
||||||
| ja | yes |
|
| ja | yes | no |
|
||||||
| jb | yes |
|
| jb | yes | no |
|
||||||
| jc | yes |
|
| jc | yes | no |
|
||||||
| jd | yes |
|
| jd | yes | no |
|
||||||
| je | yes |
|
| je | yes | no |
|
||||||
| jf | yes |
|
| jf | yes | no |
|
||||||
|
|
||||||
And the relations
|
And the relations
|
||||||
| type | way:from | way:to | node:via | restriction | except |
|
| type | way:from | way:to | node:via | restriction | except |
|
||||||
|
@ -4,32 +4,38 @@ Feature: Bike - Accessability of different way types
|
|||||||
Background:
|
Background:
|
||||||
Given the profile "bicycle"
|
Given the profile "bicycle"
|
||||||
|
|
||||||
Scenario: Bike - Basic access
|
Scenario: Bike - Routability of way types
|
||||||
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 profile "bicycle"
|
Pier is not allowed, since it's tagged using man_made=pier.
|
||||||
Then routability should be
|
Then routability should be
|
||||||
| highway | forw |
|
| highway | bothw |
|
||||||
| (nil) | |
|
| (nil) | |
|
||||||
| motorway | |
|
| motorway | |
|
||||||
| motorway_link | |
|
| motorway_link | |
|
||||||
| trunk | |
|
| trunk | |
|
||||||
| trunk_link | |
|
| trunk_link | |
|
||||||
| primary | x |
|
| primary | x |
|
||||||
| primary_link | x |
|
| primary_link | x |
|
||||||
| secondary | x |
|
| secondary | x |
|
||||||
| secondary_link | x |
|
| secondary_link | x |
|
||||||
| tertiary | x |
|
| tertiary | x |
|
||||||
| tertiary_link | x |
|
| tertiary_link | x |
|
||||||
| residential | x |
|
| residential | x |
|
||||||
| service | x |
|
| service | x |
|
||||||
| unclassified | x |
|
| unclassified | x |
|
||||||
| living_street | x |
|
| living_street | x |
|
||||||
| road | x |
|
| road | x |
|
||||||
| track | x |
|
| track | x |
|
||||||
| path | x |
|
| path | x |
|
||||||
| footway | x |
|
| footway | x |
|
||||||
| pedestrian | x |
|
| pedestrian | x |
|
||||||
| steps | x |
|
| steps | x |
|
||||||
| pier | x |
|
| cycleway | x |
|
||||||
| cycleway | x |
|
| bridleway | |
|
||||||
| bridleway | |
|
| pier | |
|
||||||
|
|
||||||
|
Scenario: Bike - Routability of man_made structures
|
||||||
|
Then routability should be
|
||||||
|
| highway | man_made | bothw |
|
||||||
|
| (nil) | (nil) | |
|
||||||
|
| (nil) | pier | x |
|
||||||
|
@ -10,9 +10,9 @@ Feature: Car - Max speed restrictions
|
|||||||
| a | b | c |
|
| a | b | c |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | highway | maxspeed |
|
| nodes | highway | maxspeed |
|
||||||
| ab | trunk | |
|
| ab | trunk | |
|
||||||
| bc | trunk | 10 |
|
| bc | trunk | 10 |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | time |
|
| from | to | route | time |
|
||||||
@ -32,3 +32,23 @@ Feature: Car - Max speed restrictions
|
|||||||
| from | to | route | time |
|
| from | to | route | time |
|
||||||
| a | b | ab | 144s ~10% |
|
| a | b | ab | 144s ~10% |
|
||||||
| b | c | bc | 63s ~10% |
|
| b | c | bc | 63s ~10% |
|
||||||
|
|
||||||
|
Scenario: Car - Forward/backward maxspeed
|
||||||
|
Given the shortcuts
|
||||||
|
| key | value |
|
||||||
|
| car | 12s ~10% |
|
||||||
|
| run | 73s ~10% |
|
||||||
|
| walk | 146s ~10% |
|
||||||
|
| snail | 720s ~10% |
|
||||||
|
|
||||||
|
And a grid size of 100 meters
|
||||||
|
|
||||||
|
Then routability should be
|
||||||
|
| maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
|
||||||
|
| | | | car | car |
|
||||||
|
| 10 | | | run | run |
|
||||||
|
| | 10 | | run | car |
|
||||||
|
| | | 10 | car | run |
|
||||||
|
| 1 | 10 | | run | snail |
|
||||||
|
| 1 | | 10 | snail | run |
|
||||||
|
| 1 | 5 | 10 | walk | run |
|
||||||
|
0
features/car/permissive.feature
Normal file
0
features/car/permissive.feature
Normal file
@ -46,6 +46,9 @@ When /^I route I should get$/ do |table|
|
|||||||
if table.headers.include? 'turns'
|
if table.headers.include? 'turns'
|
||||||
got['turns'] = turns
|
got['turns'] = turns
|
||||||
end
|
end
|
||||||
|
if table.headers.include? '#' # comment column
|
||||||
|
got['#'] = row['#'] # copy value so it always match
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
ok = true
|
ok = true
|
||||||
@ -74,4 +77,4 @@ When /^I route (\d+) times I should get$/ do |n,table|
|
|||||||
ok = false unless step "I route I should get", table
|
ok = false unless step "I route I should get", table
|
||||||
end
|
end
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
|
@ -71,14 +71,15 @@ def build_ways_from_table table
|
|||||||
way << node5
|
way << node5
|
||||||
|
|
||||||
tags = row.dup
|
tags = row.dup
|
||||||
#remove tags that describe expected test result
|
|
||||||
|
# remove tags that describe expected test result
|
||||||
tags.reject! do |k,v|
|
tags.reject! do |k,v|
|
||||||
k =~ /^forw\b/ ||
|
k =~ /^forw\b/ ||
|
||||||
k =~ /^backw\b/ ||
|
k =~ /^backw\b/ ||
|
||||||
k =~ /^bothw\b/
|
k =~ /^bothw\b/
|
||||||
end
|
end
|
||||||
|
|
||||||
#remove empty tags
|
##remove empty tags
|
||||||
tags.reject! { |k,v| v=='' }
|
tags.reject! { |k,v| v=='' }
|
||||||
|
|
||||||
# sort tag keys in the form of 'node/....'
|
# sort tag keys in the form of 'node/....'
|
||||||
|
52
features/testbot/maxspeed.feature
Normal file
52
features/testbot/maxspeed.feature
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
@routing @maxspeed @testbot
|
||||||
|
Feature: Car - Max speed restrictions
|
||||||
|
|
||||||
|
Background: Use specific speeds
|
||||||
|
Given the profile "testbot"
|
||||||
|
|
||||||
|
Scenario: Testbot - Respect maxspeeds when lower that way type speed
|
||||||
|
Given the node map
|
||||||
|
| a | b | c | d |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | maxspeed |
|
||||||
|
| ab | |
|
||||||
|
| bc | 24 |
|
||||||
|
| cd | 18 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route | time |
|
||||||
|
| a | b | ab | 10s +-1 |
|
||||||
|
| b | a | ab | 10s +-1 |
|
||||||
|
| b | c | bc | 15s +-1 |
|
||||||
|
| c | b | bc | 15s +-1 |
|
||||||
|
| c | d | cd | 20s +-1 |
|
||||||
|
| d | c | cd | 20s +-1 |
|
||||||
|
|
||||||
|
Scenario: Testbot - Ignore maxspeed when higher than way speed
|
||||||
|
Given the node map
|
||||||
|
| a | b | c |
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | maxspeed |
|
||||||
|
| ab | |
|
||||||
|
| bc | 200 |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | route | time |
|
||||||
|
| a | b | ab | 10s +-1 |
|
||||||
|
| b | a | ab | 10s +-1 |
|
||||||
|
| b | c | bc | 10s +-1 |
|
||||||
|
| c | b | bc | 10s +-1 |
|
||||||
|
|
||||||
|
@opposite
|
||||||
|
Scenario: Testbot - Forward/backward maxspeed
|
||||||
|
Then routability should be
|
||||||
|
| maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
|
||||||
|
| | | | 20s +-1 | 20s +-1 |
|
||||||
|
| 18 | | | 40s +-1 | 40s +-1 |
|
||||||
|
| | 18 | | 40s +-1 | 20s +-1 |
|
||||||
|
| | | 18 | 20s +-1 | 40s +-1 |
|
||||||
|
| 9 | 18 | | 40s +-1 | 80s +-1 |
|
||||||
|
| 9 | | 18 | 80s +-1 | 40s +-1 |
|
||||||
|
| 9 | 24 | 18 | 30s +-1 | 40s +-1 |
|
@ -1,19 +1,18 @@
|
|||||||
@routing @opposite @todo
|
@routing @testbot @opposite
|
||||||
Feature: Separate settings for forward/backward direction
|
Feature: Separate settings for forward/backward direction
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
@smallest
|
Scenario: Testbot - Going against the flow
|
||||||
Scenario: Going against the flow
|
|
||||||
Given the node map
|
Given the node map
|
||||||
| a | b |
|
| a | b | c | d |
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
| nodes | highway |
|
| nodes | highway |
|
||||||
| ab | river |
|
| abcd | river |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | distance | time |
|
| from | to | route | distance | time |
|
||||||
| a | b | ab | 100m | 10s |
|
| a | d | abcd | 300 +- 1m | 30s |
|
||||||
| b | a | ab | 100m | 20s |
|
| d | a | abcd | 300 +- 1m | 68s |
|
@ -1 +0,0 @@
|
|||||||
profiles/car.lua
|
|
1
profile.lua
Normal file
1
profile.lua
Normal file
@ -0,0 +1 @@
|
|||||||
|
profiles/car.lua
|
@ -12,7 +12,9 @@ restriction_exception_tags = { "bicycle", "vehicle", "access" }
|
|||||||
|
|
||||||
default_speed = 16
|
default_speed = 16
|
||||||
|
|
||||||
main_speeds = {
|
walking_speed = 4
|
||||||
|
|
||||||
|
bicycle_speeds = {
|
||||||
["cycleway"] = 18,
|
["cycleway"] = 18,
|
||||||
["primary"] = 17,
|
["primary"] = 17,
|
||||||
["primary_link"] = 17,
|
["primary_link"] = 17,
|
||||||
@ -26,17 +28,14 @@ main_speeds = {
|
|||||||
["road"] = 16,
|
["road"] = 16,
|
||||||
["service"] = 16,
|
["service"] = 16,
|
||||||
["track"] = 13,
|
["track"] = 13,
|
||||||
["path"] = 13,
|
["path"] = 13
|
||||||
["footway"] = 12,
|
--["footway"] = 12,
|
||||||
["pedestrian"] = 12,
|
--["pedestrian"] = 12,
|
||||||
["pier"] = 12,
|
|
||||||
["steps"] = 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pedestrian_speeds = {
|
pedestrian_speeds = {
|
||||||
["footway"] = 5,
|
["footway"] = walking_speed,
|
||||||
["pedestrian"] = 5,
|
["pedestrian"] = walking_speed,
|
||||||
["pier"] = 5,
|
|
||||||
["steps"] = 2
|
["steps"] = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ railway_speeds = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
platform_speeds = {
|
platform_speeds = {
|
||||||
["platform"] = 5
|
["platform"] = walking_speed
|
||||||
}
|
}
|
||||||
|
|
||||||
amenity_speeds = {
|
amenity_speeds = {
|
||||||
@ -58,6 +57,10 @@ amenity_speeds = {
|
|||||||
["parking_entrance"] = 10
|
["parking_entrance"] = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
man_made_speeds = {
|
||||||
|
["pier"] = walking_speed
|
||||||
|
}
|
||||||
|
|
||||||
route_speeds = {
|
route_speeds = {
|
||||||
["ferry"] = 5
|
["ferry"] = 5
|
||||||
}
|
}
|
||||||
@ -110,17 +113,38 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
if(numberOfNodesInWay < 2) then
|
if(numberOfNodesInWay < 2) then
|
||||||
return 0;
|
return 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
-- First, get the properties of each way that we come across
|
-- initial routability check, filters out buildings, boundaries, etc
|
||||||
local highway = way.tags:Find("highway")
|
local highway = way.tags:Find("highway")
|
||||||
|
local route = way.tags:Find("route")
|
||||||
|
local man_made = way.tags:Find("man_made")
|
||||||
|
local railway = way.tags:Find("railway")
|
||||||
|
local amenity = way.tags:Find("amenity")
|
||||||
|
local public_transport = way.tags:Find("public_transport")
|
||||||
|
if (not highway or highway == '') and
|
||||||
|
(not route or route == '') and
|
||||||
|
(not railway or railway=='') and
|
||||||
|
(not amenity or amenity=='') and
|
||||||
|
(not man_made or man_made=='') and
|
||||||
|
(not public_transport or public_transport=='')
|
||||||
|
then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- access
|
||||||
|
local access = Access.find_access_tag(way, access_tags_hierachy)
|
||||||
|
if access_tag_blacklist[access] then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- other tags
|
||||||
local name = way.tags:Find("name")
|
local name = way.tags:Find("name")
|
||||||
local ref = way.tags:Find("ref")
|
local ref = way.tags:Find("ref")
|
||||||
local junction = way.tags:Find("junction")
|
local junction = way.tags:Find("junction")
|
||||||
local route = way.tags:Find("route")
|
|
||||||
local railway = way.tags:Find("railway")
|
|
||||||
local public_transport = way.tags:Find("public_transport")
|
|
||||||
local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") )
|
local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") )
|
||||||
local man_made = way.tags:Find("man_made")
|
local maxspeed_forward = parseMaxspeed(way.tags:Find( "maxspeed:forward"))
|
||||||
|
local maxspeed_backward = parseMaxspeed(way.tags:Find( "maxspeed:backward"))
|
||||||
local barrier = way.tags:Find("barrier")
|
local barrier = way.tags:Find("barrier")
|
||||||
local oneway = way.tags:Find("oneway")
|
local oneway = way.tags:Find("oneway")
|
||||||
local onewayClass = way.tags:Find("oneway:bicycle")
|
local onewayClass = way.tags:Find("oneway:bicycle")
|
||||||
@ -130,23 +154,7 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
local duration = way.tags:Find("duration")
|
local duration = way.tags:Find("duration")
|
||||||
local service = way.tags:Find("service")
|
local service = way.tags:Find("service")
|
||||||
local area = way.tags:Find("area")
|
local area = way.tags:Find("area")
|
||||||
local amenity = way.tags:Find("amenity")
|
local foot = way.tags:Find("foot")
|
||||||
local access = Access.find_access_tag(way, access_tags_hierachy)
|
|
||||||
|
|
||||||
-- initial routability check, filters out buildings, boundaries, etc
|
|
||||||
if (not highway or highway == '') and
|
|
||||||
(not route or route == '') and
|
|
||||||
(not railway or railway=='') and
|
|
||||||
(not amenity or amenity=='') and
|
|
||||||
(not public_transport or public_transport=='')
|
|
||||||
then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- access
|
|
||||||
if access_tag_blacklist[access] then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- name
|
-- name
|
||||||
if "" ~= ref then
|
if "" ~= ref then
|
||||||
@ -157,8 +165,9 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
way.name = highway -- if no name exists, use way type
|
way.name = highway -- if no name exists, use way type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- speed
|
||||||
if route_speeds[route] then
|
if route_speeds[route] then
|
||||||
-- ferries
|
-- ferries (doesn't cover routes tagged using relations)
|
||||||
way.direction = Way.bidirectional
|
way.direction = Way.bidirectional
|
||||||
way.ignore_in_grid = true
|
way.ignore_in_grid = true
|
||||||
if durationIsValid(duration) then
|
if durationIsValid(duration) then
|
||||||
@ -178,34 +187,32 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
way.speed = railway_speeds[railway]
|
way.speed = railway_speeds[railway]
|
||||||
way.direction = Way.bidirectional
|
way.direction = Way.bidirectional
|
||||||
end
|
end
|
||||||
elseif pedestrian_speeds[highway] and main_speeds[highway] then
|
|
||||||
-- pedestrian areas
|
|
||||||
if access_tag_whitelist[access] then
|
|
||||||
way.speed = main_speeds[highway] -- biking
|
|
||||||
else
|
|
||||||
way.speed = pedestrian_speeds[highway] -- pushing bikes
|
|
||||||
end
|
|
||||||
elseif amenity and amenity_speeds[amenity] then
|
elseif amenity and amenity_speeds[amenity] then
|
||||||
-- parking areas
|
-- parking areas
|
||||||
way.speed = amenity_speeds[amenity]
|
way.speed = amenity_speeds[amenity]
|
||||||
else
|
elseif bicycle_speeds[highway] then
|
||||||
-- regular ways
|
-- regular ways
|
||||||
if main_speeds[highway] then
|
way.speed = bicycle_speeds[highway]
|
||||||
way.speed = main_speeds[highway]
|
elseif access and access_tag_whitelist[access] then
|
||||||
elseif main_speeds[man_made] then
|
-- unknown way, but valid access tag
|
||||||
way.speed = main_speeds[man_made]
|
way.speed = default_speed
|
||||||
elseif access_tag_whitelist[access] then
|
else
|
||||||
way.speed = default_speed
|
-- biking not allowed, maybe we can push our bike?
|
||||||
end
|
-- essentially requires pedestrian profiling, for example foot=no mean we can't push a bike
|
||||||
end
|
-- TODO: if we can push, the way should be marked as pedestrion mode, but there's no way to do it yet from lua..
|
||||||
|
if foot ~= 'no' then
|
||||||
-- maxspeed
|
if pedestrian_speeds[highway] then
|
||||||
if take_minimum_of_speeds then
|
-- pedestrian-only ways and areas
|
||||||
if maxspeed and maxspeed>0 then
|
way.speed = pedestrian_speeds[highway]
|
||||||
way.speed = math.min(way.speed, maxspeed)
|
elseif man_made and man_made_speeds[man_made] then
|
||||||
end
|
-- man made structures
|
||||||
end
|
way.speed = man_made_speeds[man_made]
|
||||||
|
elseif foot == 'yes' then
|
||||||
|
way.speed = walking_speed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- direction
|
-- direction
|
||||||
way.direction = Way.bidirectional
|
way.direction = Way.bidirectional
|
||||||
local impliedOneway = false
|
local impliedOneway = false
|
||||||
@ -248,15 +255,53 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
way.direction = Way.oneway
|
way.direction = Way.oneway
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- pushing bikes
|
||||||
|
if bicycle_speeds[highway] or pedestrian_speeds[highway] then
|
||||||
|
if foot ~= 'no' then
|
||||||
|
if way.direction == Way.oneway then
|
||||||
|
way.backward_speed = walking_speed
|
||||||
|
elseif way.direction == Way.opposite then
|
||||||
|
way.backward_speed = walking_speed
|
||||||
|
way.speed = way.speed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if way.backward_speed == way.speed then
|
||||||
|
-- TODO: no way yet to mark a way as pedestrian mode if forward/backward speeds are equal
|
||||||
|
way.direction = Way.bidirectional
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- cycleways
|
-- cycleways
|
||||||
if cycleway and cycleway_tags[cycleway] then
|
if cycleway and cycleway_tags[cycleway] then
|
||||||
way.speed = main_speeds["cycleway"]
|
way.speed = bicycle_speeds["cycleway"]
|
||||||
elseif cycleway_left and cycleway_tags[cycleway_left] then
|
elseif cycleway_left and cycleway_tags[cycleway_left] then
|
||||||
way.speed = main_speeds["cycleway"]
|
way.speed = bicycle_speeds["cycleway"]
|
||||||
elseif cycleway_right and cycleway_tags[cycleway_right] then
|
elseif cycleway_right and cycleway_tags[cycleway_right] then
|
||||||
way.speed = main_speeds["cycleway"]
|
way.speed = bicycle_speeds["cycleway"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- maxspeed
|
||||||
|
-- TODO: maxspeed of backward direction
|
||||||
|
if take_minimum_of_speeds then
|
||||||
|
if maxspeed and maxspeed>0 then
|
||||||
|
way.speed = math.min(way.speed, maxspeed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Override speed settings if explicit forward/backward maxspeeds are given
|
||||||
|
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
|
||||||
|
if Way.bidirectional == way.direction then
|
||||||
|
way.backward_speed = way.speed
|
||||||
|
end
|
||||||
|
way.speed = maxspeed_forward
|
||||||
|
end
|
||||||
|
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
|
||||||
|
way.backward_speed = maxspeed_backward
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
way.type = 1
|
way.type = 1
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
287
profiles/car.lua
287
profiles/car.lua
@ -12,24 +12,24 @@ ignore_in_grid = { ["ferry"] = true }
|
|||||||
restriction_exception_tags = { "motorcar", "motor_vehicle", "vehicle" }
|
restriction_exception_tags = { "motorcar", "motor_vehicle", "vehicle" }
|
||||||
|
|
||||||
speed_profile = {
|
speed_profile = {
|
||||||
["motorway"] = 90,
|
["motorway"] = 90,
|
||||||
["motorway_link"] = 75,
|
["motorway_link"] = 75,
|
||||||
["trunk"] = 85,
|
["trunk"] = 85,
|
||||||
["trunk_link"] = 70,
|
["trunk_link"] = 70,
|
||||||
["primary"] = 65,
|
["primary"] = 65,
|
||||||
["primary_link"] = 60,
|
["primary_link"] = 60,
|
||||||
["secondary"] = 55,
|
["secondary"] = 55,
|
||||||
["secondary_link"] = 50,
|
["secondary_link"] = 50,
|
||||||
["tertiary"] = 40,
|
["tertiary"] = 40,
|
||||||
["tertiary_link"] = 30,
|
["tertiary_link"] = 30,
|
||||||
["unclassified"] = 25,
|
["unclassified"] = 25,
|
||||||
["residential"] = 25,
|
["residential"] = 25,
|
||||||
["living_street"] = 10,
|
["living_street"] = 10,
|
||||||
["service"] = 15,
|
["service"] = 15,
|
||||||
-- ["track"] = 5,
|
-- ["track"] = 5,
|
||||||
["ferry"] = 5,
|
["ferry"] = 5,
|
||||||
["shuttle_train"] = 10,
|
["shuttle_train"] = 10,
|
||||||
["default"] = 50
|
["default"] = 50
|
||||||
}
|
}
|
||||||
|
|
||||||
take_minimum_of_speeds = false
|
take_minimum_of_speeds = false
|
||||||
@ -43,85 +43,101 @@ u_turn_penalty = 20
|
|||||||
-- End of globals
|
-- End of globals
|
||||||
|
|
||||||
function get_exceptions(vector)
|
function get_exceptions(vector)
|
||||||
for i,v in ipairs(restriction_exception_tags) do
|
for i,v in ipairs(restriction_exception_tags) do
|
||||||
vector:Add(v)
|
vector:Add(v)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function parse_maxspeed(source)
|
||||||
|
if source == nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
local n = tonumber(source:match("%d*"))
|
||||||
|
if n == nil then
|
||||||
|
n = 0
|
||||||
|
end
|
||||||
|
if string.match(source, "mph") or string.match(source, "mp/h") then
|
||||||
|
n = (n*1609)/1000;
|
||||||
|
end
|
||||||
|
return math.abs(n)
|
||||||
end
|
end
|
||||||
|
|
||||||
function node_function (node)
|
function node_function (node)
|
||||||
local barrier = node.tags:Find ("barrier")
|
local barrier = node.tags:Find ("barrier")
|
||||||
local access = Access.find_access_tag(node, access_tags_hierachy)
|
local access = Access.find_access_tag(node, access_tags_hierachy)
|
||||||
local traffic_signal = node.tags:Find("highway")
|
local traffic_signal = node.tags:Find("highway")
|
||||||
|
|
||||||
--flag node if it carries a traffic light
|
--flag node if it carries a traffic light
|
||||||
|
|
||||||
if traffic_signal == "traffic_signals" then
|
if traffic_signal == "traffic_signals" then
|
||||||
node.traffic_light = true;
|
node.traffic_light = true;
|
||||||
end
|
|
||||||
|
|
||||||
-- parse access and barrier tags
|
|
||||||
if access and access ~= "" then
|
|
||||||
if access_tag_blacklist[access] then
|
|
||||||
node.bollard = true
|
|
||||||
end
|
|
||||||
elseif barrier and barrier ~= "" then
|
|
||||||
if barrier_whitelist[barrier] then
|
|
||||||
return
|
|
||||||
else
|
|
||||||
node.bollard = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return 1
|
|
||||||
|
-- parse access and barrier tags
|
||||||
|
if access and access ~= "" then
|
||||||
|
if access_tag_blacklist[access] then
|
||||||
|
node.bollard = true
|
||||||
|
end
|
||||||
|
elseif barrier and barrier ~= "" then
|
||||||
|
if barrier_whitelist[barrier] then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
node.bollard = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function way_function (way, numberOfNodesInWay)
|
function way_function (way, numberOfNodesInWay)
|
||||||
|
|
||||||
-- A way must have two nodes or more
|
-- A way must have two nodes or more
|
||||||
if(numberOfNodesInWay < 2) then
|
if(numberOfNodesInWay < 2) then
|
||||||
return 0;
|
return 0;
|
||||||
end
|
|
||||||
|
|
||||||
-- First, get the properties of each way that we come across
|
|
||||||
local highway = way.tags:Find("highway")
|
|
||||||
local name = way.tags:Find("name")
|
|
||||||
local ref = way.tags:Find("ref")
|
|
||||||
local junction = way.tags:Find("junction")
|
|
||||||
local route = way.tags:Find("route")
|
|
||||||
local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") )
|
|
||||||
local barrier = way.tags:Find("barrier")
|
|
||||||
local oneway = way.tags:Find("oneway")
|
|
||||||
local cycleway = way.tags:Find("cycleway")
|
|
||||||
local duration = way.tags:Find("duration")
|
|
||||||
local service = way.tags:Find("service")
|
|
||||||
local area = way.tags:Find("area")
|
|
||||||
local access = Access.find_access_tag(way, access_tags_hierachy)
|
|
||||||
|
|
||||||
-- Second, parse the way according to these properties
|
|
||||||
|
|
||||||
if ignore_areas and ("yes" == area) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if we are allowed to access the way
|
|
||||||
if access_tag_blacklist[access] then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set the name that will be used for instructions
|
|
||||||
if "" ~= ref then
|
|
||||||
way.name = ref
|
|
||||||
elseif "" ~= name then
|
|
||||||
way.name = name
|
|
||||||
-- else
|
|
||||||
-- way.name = highway -- if no name exists, use way type
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if "roundabout" == junction then
|
-- First, get the properties of each way that we come across
|
||||||
way.roundabout = true;
|
local highway = way.tags:Find("highway")
|
||||||
end
|
local name = way.tags:Find("name")
|
||||||
|
local ref = way.tags:Find("ref")
|
||||||
|
local junction = way.tags:Find("junction")
|
||||||
|
local route = way.tags:Find("route")
|
||||||
|
local maxspeed = parse_maxspeed(way.tags:Find ( "maxspeed") )
|
||||||
|
local maxspeed_forward = tonumber(way.tags:Find( "maxspeed:forward"))
|
||||||
|
local maxspeed_backward = tonumber(way.tags:Find( "maxspeed:backward"))
|
||||||
|
local barrier = way.tags:Find("barrier")
|
||||||
|
local oneway = way.tags:Find("oneway")
|
||||||
|
local cycleway = way.tags:Find("cycleway")
|
||||||
|
local duration = way.tags:Find("duration")
|
||||||
|
local service = way.tags:Find("service")
|
||||||
|
local area = way.tags:Find("area")
|
||||||
|
local access = Access.find_access_tag(way, access_tags_hierachy)
|
||||||
|
|
||||||
-- Handling ferries and piers
|
-- Second, parse the way according to these properties
|
||||||
|
|
||||||
|
if ignore_areas and ("yes" == area) then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if we are allowed to access the way
|
||||||
|
if access_tag_blacklist[access] then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set the name that will be used for instructions
|
||||||
|
if "" ~= ref then
|
||||||
|
way.name = ref
|
||||||
|
elseif "" ~= name then
|
||||||
|
way.name = name
|
||||||
|
-- else
|
||||||
|
-- way.name = highway -- if no name exists, use way type
|
||||||
|
end
|
||||||
|
|
||||||
|
if "roundabout" == junction then
|
||||||
|
way.roundabout = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handling ferries and piers
|
||||||
if (speed_profile[route] ~= nil and speed_profile[route] > 0) then
|
if (speed_profile[route] ~= nil and speed_profile[route] > 0) then
|
||||||
if durationIsValid(duration) then
|
if durationIsValid(duration) then
|
||||||
way.duration = math.max( parseDuration(duration), 1 );
|
way.duration = math.max( parseDuration(duration), 1 );
|
||||||
@ -134,9 +150,9 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
way.speed = speed_profile[highway]
|
way.speed = speed_profile[highway]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set the avg speed on the way if it is accessible by road class
|
-- Set the avg speed on the way if it is accessible by road class
|
||||||
if (speed_profile[highway] ~= nil and way.speed == -1 ) then
|
if (speed_profile[highway] ~= nil and way.speed == -1 ) then
|
||||||
if maxspeed > speed_profile[highway] then
|
if maxspeed > speed_profile[highway] then
|
||||||
way.speed = maxspeed
|
way.speed = maxspeed
|
||||||
else
|
else
|
||||||
@ -146,55 +162,64 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
way.speed = math.min(speed_profile[highway], maxspeed)
|
way.speed = math.min(speed_profile[highway], maxspeed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set the avg speed on ways that are marked accessible
|
|
||||||
if "" ~= highway and access_tag_whitelist[access] and way.speed == -1 then
|
|
||||||
if 0 == maxspeed then
|
|
||||||
maxspeed = math.huge
|
|
||||||
end
|
|
||||||
way.speed = math.min(speed_profile["default"], maxspeed)
|
|
||||||
end
|
|
||||||
|
|
||||||
if durationIsValid(duration) then
|
|
||||||
way.duration = math.max( parseDuration(duration), 1 );
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set access restriction flag if access is allowed under certain restrictions only
|
-- Set the avg speed on ways that are marked accessible
|
||||||
if access ~= "" and access_tag_restricted[access] then
|
if "" ~= highway and access_tag_whitelist[access] and way.speed == -1 then
|
||||||
way.is_access_restricted = true
|
if 0 == maxspeed then
|
||||||
end
|
maxspeed = math.huge
|
||||||
|
end
|
||||||
|
way.speed = math.min(speed_profile["default"], maxspeed)
|
||||||
|
end
|
||||||
|
|
||||||
-- Set access restriction flag if service is allowed under certain restrictions only
|
-- Set access restriction flag if access is allowed under certain restrictions only
|
||||||
if service ~= "" and service_tag_restricted[service] then
|
if access ~= "" and access_tag_restricted[access] then
|
||||||
way.is_access_restricted = true
|
way.is_access_restricted = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Set access restriction flag if service is allowed under certain restrictions only
|
||||||
|
if service ~= "" and service_tag_restricted[service] then
|
||||||
|
way.is_access_restricted = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set direction according to tags on way
|
||||||
|
if obey_oneway then
|
||||||
|
if oneway == "no" or oneway == "0" or oneway == "false" then
|
||||||
|
way.direction = Way.bidirectional
|
||||||
|
elseif oneway == "-1" then
|
||||||
|
way.direction = Way.opposite
|
||||||
|
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" or highway == "motorway_link" or highway == "motorway" then
|
||||||
|
way.direction = Way.oneway
|
||||||
|
else
|
||||||
|
way.direction = Way.bidirectional
|
||||||
|
end
|
||||||
|
else
|
||||||
|
way.direction = Way.bidirectional
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Override speed settings if explicit forward/backward maxspeeds are given
|
||||||
|
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
|
||||||
|
if Way.bidirectional == way.direction then
|
||||||
|
way.backward_speed = way.speed
|
||||||
|
end
|
||||||
|
way.speed = maxspeed_forward
|
||||||
|
end
|
||||||
|
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
|
||||||
|
way.backward_speed = maxspeed_backward
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Override general direction settings of there is a specific one for our mode of travel
|
||||||
|
|
||||||
-- Set direction according to tags on way
|
if ignore_in_grid[highway] ~= nil and ignore_in_grid[highway] then
|
||||||
if obey_oneway then
|
way.ignore_in_grid = true
|
||||||
if oneway == "no" or oneway == "0" or oneway == "false" then
|
end
|
||||||
way.direction = Way.bidirectional
|
way.type = 1
|
||||||
elseif oneway == "-1" then
|
return 1
|
||||||
way.direction = Way.opposite
|
|
||||||
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" or highway == "motorway_link" or highway == "motorway" then
|
|
||||||
way.direction = Way.oneway
|
|
||||||
else
|
|
||||||
way.direction = Way.bidirectional
|
|
||||||
end
|
|
||||||
else
|
|
||||||
way.direction = Way.bidirectional
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Override general direction settings of there is a specific one for our mode of travel
|
|
||||||
if ignore_in_grid[highway] ~= nil and ignore_in_grid[highway] then
|
|
||||||
way.ignore_in_grid = true
|
|
||||||
end
|
|
||||||
way.type = 1
|
|
||||||
return 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT
|
-- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT
|
||||||
|
|
||||||
function node_vector_function(vector)
|
function node_vector_function(vector)
|
||||||
for v in vector.nodes do
|
for v in vector.nodes do
|
||||||
node_function(v)
|
node_function(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -23,6 +23,18 @@ ignore_areas = true -- future feature
|
|||||||
traffic_signal_penalty = 7 -- seconds
|
traffic_signal_penalty = 7 -- seconds
|
||||||
u_turn_penalty = 20
|
u_turn_penalty = 20
|
||||||
|
|
||||||
|
function limit_speed(speed, limits)
|
||||||
|
-- don't use ipairs(), since it stops at the first nil value
|
||||||
|
for i=1, #limits do
|
||||||
|
limit = limits[i]
|
||||||
|
if limit ~= nil and limit > 0 then
|
||||||
|
if limit < speed then
|
||||||
|
return limit -- stop at first speedlimit that's smaller than speed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return speed
|
||||||
|
end
|
||||||
|
|
||||||
function node_function (node)
|
function node_function (node)
|
||||||
local traffic_signal = node.tags:Find("highway")
|
local traffic_signal = node.tags:Find("highway")
|
||||||
@ -45,13 +57,44 @@ function way_function (way, numberOfNodesInWay)
|
|||||||
local oneway = way.tags:Find("oneway")
|
local oneway = way.tags:Find("oneway")
|
||||||
local route = way.tags:Find("route")
|
local route = way.tags:Find("route")
|
||||||
local duration = way.tags:Find("duration")
|
local duration = way.tags:Find("duration")
|
||||||
|
local maxspeed = tonumber(way.tags:Find ( "maxspeed"))
|
||||||
|
local maxspeed_forward = tonumber(way.tags:Find( "maxspeed:forward"))
|
||||||
|
local maxspeed_backward = tonumber(way.tags:Find( "maxspeed:backward"))
|
||||||
|
|
||||||
way.name = name
|
way.name = name
|
||||||
|
|
||||||
if route ~= nil and durationIsValid(duration) then
|
if route ~= nil and durationIsValid(duration) then
|
||||||
way.duration = math.max( 1, parseDuration(duration) )
|
way.duration = math.max( 1, parseDuration(duration) )
|
||||||
else
|
else
|
||||||
way.speed = speed_profile[highway] or speed_profile['default']
|
local speed_forw = speed_profile[highway] or speed_profile['default']
|
||||||
|
local speed_back = speed_forw
|
||||||
|
|
||||||
|
if highway == "river" then
|
||||||
|
local temp_speed = speed_forw;
|
||||||
|
speed_forw = temp_speed*1.5
|
||||||
|
speed_back = temp_speed/1.5
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
|
||||||
|
speed_forw = maxspeed_forward
|
||||||
|
else
|
||||||
|
if maxspeed ~= nil and maxspeed > 0 and speed_forw > maxspeed then
|
||||||
|
speed_forw = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
|
||||||
|
speed_back = maxspeed_backward
|
||||||
|
else
|
||||||
|
if maxspeed ~=nil and maxspeed > 0 and speed_back > maxspeed then
|
||||||
|
speed_back = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
way.speed = speed_forw
|
||||||
|
if speed_back ~= way_forw then
|
||||||
|
way.backward_speed = speed_back
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if oneway == "no" or oneway == "0" or oneway == "false" then
|
if oneway == "no" or oneway == "0" or oneway == "false" then
|
||||||
|
Loading…
Reference in New Issue
Block a user