Consider mini roundabouts and traffic calming nodes when calculating a

duration for a route.
This commit is contained in:
Phil Kingston 2012-12-11 10:26:44 +00:00
parent 824724630f
commit a5aefb7d70
13 changed files with 86 additions and 20 deletions

View File

@ -76,6 +76,8 @@ private:
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
boost::unordered_map<NodeID, bool> _miniRoundabouts;
boost::unordered_map<NodeID, bool> _trafficCalmingNodes;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
@ -120,7 +122,7 @@ private:
NodeID parent;
};
public:
TarjanSCC(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) {
TarjanSCC(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<NodeID> & mrl, std::vector<NodeID> & tcl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) {
BOOST_FOREACH(_Restriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode);
unsigned index;
@ -149,6 +151,12 @@ public:
BOOST_FOREACH(NodeID id, tl) {
_trafficLights[id] = true;
}
BOOST_FOREACH(NodeID id, mrl) {
_miniRoundabouts[id] = true;
}
BOOST_FOREACH(NodeID id, tcl) {
_trafficCalmingNodes[id] = true;
}
DeallocatingVector< _NodeBasedEdge > edges;
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {

View File

@ -1,5 +1,5 @@
/*
open source routing machine
/// open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
@ -21,7 +21,7 @@
#include "EdgeBasedGraphFactory.h"
template<>
EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI, SpeedProfileProperties sp) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()), speedProfile(sp) {
EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<NodeID> & mrl, std::vector<NodeID> & tcl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI, SpeedProfileProperties sp) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()), speedProfile(sp) {
BOOST_FOREACH(_Restriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode);
unsigned index;
@ -50,6 +50,12 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
BOOST_FOREACH(NodeID id, tl) {
_trafficLights[id] = true;
}
BOOST_FOREACH(NodeID id, mrl) {
_miniRoundabouts[id] = true;
}
BOOST_FOREACH(NodeID id, tcl) {
_trafficCalmingNodes[id] = true;
}
DeallocatingVector< _NodeBasedEdge > edges;
// edges.reserve( 2 * inputEdges.size() );
@ -280,6 +286,12 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
if(_trafficLights.find(v) != _trafficLights.end()) {
distance += speedProfile.trafficSignalPenalty;
}
if(_miniRoundabouts.find(v) != _miniRoundabouts.end()) {
distance += speedProfile.miniRoundaboutPenalty;
}
if(_trafficCalmingNodes.find(v) != _trafficCalmingNodes.end()) {
distance += speedProfile.trafficCalmingPenalty;
}
short turnInstruction = AnalyzeTurn(u, v, w);
if(turnInstruction == TurnInstructions.UTurn)
distance += speedProfile.uTurnPenalty;

View File

@ -97,14 +97,18 @@ public:
struct SpeedProfileProperties{
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0) {}
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0), miniRoundaboutPenalty(0), trafficCalmingPenalty(0) {}
int trafficSignalPenalty;
int uTurnPenalty;
int miniRoundaboutPenalty;
int trafficCalmingPenalty;
} speedProfile;
private:
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
boost::unordered_map<NodeID, bool> _miniRoundabouts;
boost::unordered_map<NodeID, bool> _trafficCalmingNodes;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
@ -132,7 +136,7 @@ private:
public:
template< class InputEdgeT >
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, SpeedProfileProperties speedProfile);
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<NodeID> & miniRoundabouts, std::vector<NodeID> & trafficCalmingNodes, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, SpeedProfileProperties speedProfile);
void Run(const char * originalEdgeDataFilename);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );

View File

@ -26,20 +26,22 @@ or see http://www.gnu.org/licenses/agpl.txt.
struct _Node : NodeInfo{
_Node(int _lat, int _lon, unsigned int _id, bool _bollard, bool _trafficLight) : NodeInfo(_lat, _lon, _id), bollard(_bollard), trafficLight(_trafficLight) {}
_Node() : bollard(false), trafficLight(false) {}
_Node(int _lat, int _lon, unsigned int _id, bool _bollard, bool _trafficLight, bool _miniRoundabout, bool _trafficCalming) : NodeInfo(_lat, _lon, _id), bollard(_bollard), trafficLight(_trafficLight), miniRoundabout(_miniRoundabout), trafficCalming(_trafficCalming) {}
_Node() : bollard(false), trafficLight(false), miniRoundabout(false), trafficCalming(false) {}
static _Node min_value() {
return _Node(0,0,0, false, false);
return _Node(0,0,0, false, false, false, false);
}
static _Node max_value() {
return _Node((std::numeric_limits<int>::max)(), (std::numeric_limits<int>::max)(), (std::numeric_limits<unsigned int>::max)(), false, false);
return _Node((std::numeric_limits<int>::max)(), (std::numeric_limits<int>::max)(), (std::numeric_limits<unsigned int>::max)(), false, false, false, false);
}
NodeID key() const {
return id;
}
bool bollard;
bool trafficLight;
bool miniRoundabout;
bool trafficCalming;
};
struct ImportNode : public _Node {
@ -47,7 +49,7 @@ struct ImportNode : public _Node {
inline void Clear() {
keyVals.EraseAll();
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false;
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false, miniRoundabout = false, trafficCalming = false;
}
};

View File

@ -77,6 +77,8 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
.def_readwrite("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("mini_roundabout", &ImportNode::miniRoundabout)
.def_readwrite("traffic_calming", &ImportNode::trafficCalming)
.def_readwrite("tags", &ImportNode::keyVals)
];

View File

@ -55,6 +55,8 @@ std::vector<NodeInfo> internalToExternalNodeMapping;
std::vector<_Restriction> inputRestrictions;
std::vector<NodeID> bollardNodes;
std::vector<NodeID> trafficLightNodes;
std::vector<NodeID> miniRoundaboutNodes;
std::vector<NodeID> trafficCalmingNodes;
int main (int argc, char *argv[]) {
if(argc < 3) {
@ -81,21 +83,23 @@ int main (int argc, char *argv[]) {
}
std::vector<ImportEdge> edgeList;
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, miniRoundaboutNodes, trafficCalmingNodes, &internalToExternalNodeMapping, inputRestrictions);
in.close();
INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");
INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights, " << miniRoundaboutNodes.size() << " mini roundabouts, " << trafficCalmingNodes.size() << " traffic calming nodes");
/***
* Building an edge-expanded graph from node-based input an turn restrictions
*/
INFO("Starting SCC graph traversal");
TarjanSCC * tarjan = new TarjanSCC (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping);
TarjanSCC * tarjan = new TarjanSCC (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, miniRoundaboutNodes, trafficCalmingNodes, inputRestrictions, internalToExternalNodeMapping);
std::vector<ImportEdge>().swap(edgeList);
tarjan->Run();
std::vector<_Restriction>().swap(inputRestrictions);
std::vector<NodeID>().swap(bollardNodes);
std::vector<NodeID>().swap(trafficLightNodes);
std::vector<NodeID>().swap(miniRoundaboutNodes);
std::vector<NodeID>().swap(trafficCalmingNodes);
INFO("finished component analysis");
return 0;
}

View File

@ -48,7 +48,7 @@ struct _ExcessRemover {
};
template<typename EdgeT>
NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, std::vector<NodeID> &bollardNodes, std::vector<NodeID> &trafficLightNodes, std::vector<NodeInfo> * int2ExtNodeMap, std::vector<_Restriction> & inputRestrictions) {
NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, std::vector<NodeID> &bollardNodes, std::vector<NodeID> &trafficLightNodes, std::vector<NodeID> &miniRoundaboutNodes, std::vector<NodeID> &trafficCalmingNodes, std::vector<NodeInfo> * int2ExtNodeMap, std::vector<_Restriction> & inputRestrictions) {
NodeID n, source, target;
EdgeID m;
short dir;// direction (0 = open, 1 = forward, 2+ = open)
@ -64,11 +64,17 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
bollardNodes.push_back(i);
if(node.trafficLight)
trafficLightNodes.push_back(i);
if(node.miniRoundabout)
miniRoundaboutNodes.push_back(i);
if(node.trafficCalming)
trafficCalmingNodes.push_back(i);
}
//tighten vector sizes
std::vector<NodeID>(bollardNodes).swap(bollardNodes);
std::vector<NodeID>(trafficLightNodes).swap(trafficLightNodes);
std::vector<NodeID>(miniRoundaboutNodes).swap(miniRoundaboutNodes);
std::vector<NodeID>(trafficCalmingNodes).swap(trafficCalmingNodes);
in.read((char*)&m, sizeof(unsigned));
DEBUG(" and " << m << " edges ");

View File

@ -67,6 +67,8 @@ std::vector<NodeInfo> internalToExternalNodeMapping;
std::vector<_Restriction> inputRestrictions;
std::vector<NodeID> bollardNodes;
std::vector<NodeID> trafficLightNodes;
std::vector<NodeID> miniRoundaboutNodes;
std::vector<NodeID> trafficCalmingNodes;
int main (int argc, char *argv[]) {
if(argc < 3) {
@ -138,12 +140,26 @@ int main (int argc, char *argv[]) {
}
speedProfile.uTurnPenalty = 10*lua_tointeger(myLuaState, -1);
if(0 != luaL_dostring( myLuaState, "return mini_roundabout_penalty\n")) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block");
}
speedProfile.miniRoundaboutPenalty = 10*lua_tointeger(myLuaState, -1);
if(0 != luaL_dostring( myLuaState, "return traffic_calming_penalty\n")) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block");
}
speedProfile.trafficCalmingPenalty = 10*lua_tointeger(myLuaState, -1);
std::vector<ImportEdge> edgeList;
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, miniRoundaboutNodes, trafficCalmingNodes, &internalToExternalNodeMapping, inputRestrictions);
in.close();
INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");
INFO(inputRestrictions.size() << " restrictions");
INFO(bollardNodes.size() << " bollard nodes");
INFO(trafficLightNodes.size() << " traffic lights");
INFO(miniRoundaboutNodes.size() << " mini roundabouts");
INFO(trafficCalmingNodes.size() << " traffic calming nodes");
if(0 == edgeList.size())
ERR("The input data is broken. It is impossible to do any turns in this graph");
@ -153,12 +169,14 @@ int main (int argc, char *argv[]) {
*/
INFO("Generating edge-expanded graph representation");
EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile);
EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, miniRoundaboutNodes, trafficCalmingNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile);
std::vector<ImportEdge>().swap(edgeList);
edgeBasedGraphFactory->Run(edgeOut);
std::vector<_Restriction>().swap(inputRestrictions);
std::vector<NodeID>().swap(bollardNodes);
std::vector<NodeID>().swap(trafficLightNodes);
std::vector<NodeID>().swap(miniRoundaboutNodes);
std::vector<NodeID>().swap(trafficCalmingNodes);
NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes();
DeallocatingVector<EdgeBasedEdge> edgeBasedEdgeList;
edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);

View File

@ -34,7 +34,9 @@ obey_oneway = true
obey_bollards = true
use_restrictions = true
ignore_areas = true -- future feature
traffic_signal_penalty = 2
traffic_signal_penalty = 20
mini_roundabout_penalty = 5
traffic_calming_penalty = 5
u_turn_penalty = 20
-- End of globals

View File

@ -65,6 +65,8 @@ obey_bollards = false
use_restrictions = true
ignore_areas = true -- future feature
traffic_signal_penalty = 2
mini_roundabout_penalty = 2
traffic_calming_penalty = 0
u_turn_penalty = 20
-- End of globals

View File

@ -34,7 +34,9 @@ obey_oneway = true
obey_bollards = true
use_restrictions = true
ignore_areas = true -- future feature
traffic_signal_penalty = 2
traffic_signal_penalty = 10
mini_roundabout_penalty = 5
traffic_calming_penalty = 5
u_turn_penalty = 20
-- End of globals

View File

@ -38,7 +38,9 @@ obey_oneway = true
obey_bollards = false
use_restrictions = false
ignore_areas = true -- future feature
traffic_signal_penalty = 2
traffic_signal_penalty = 0
mini_roundabout_penalty = 0
traffic_calming_penalty = 0
u_turn_penalty = 2
-- End of globals

View File

@ -21,6 +21,8 @@ obey_bollards = true
use_restrictions = true
ignore_areas = true -- future feature
traffic_signal_penalty = 7 -- seconds
mini_roundabout_penalty = 0
traffic_calming_penalty = 0
u_turn_penalty = 20