From a5aefb7d7044760c314795907f1a57819a20ae33 Mon Sep 17 00:00:00 2001 From: Phil Kingston Date: Tue, 11 Dec 2012 10:26:44 +0000 Subject: [PATCH] Consider mini roundabouts and traffic calming nodes when calculating a duration for a route. --- Algorithms/StronglyConnectedComponents.h | 10 +++++++++- Contractor/EdgeBasedGraphFactory.cpp | 16 ++++++++++++++-- Contractor/EdgeBasedGraphFactory.h | 8 ++++++-- DataStructures/ImportNode.h | 12 +++++++----- Extractor/ScriptingEnvironment.cpp | 2 ++ Tools/componentAnalysis.cpp | 10 +++++++--- Util/GraphLoader.h | 8 +++++++- createHierarchy.cpp | 24 +++++++++++++++++++++--- profile.lua | 4 +++- profiles/bicycle.lua | 2 ++ profiles/car.lua | 4 +++- profiles/foot.lua | 4 +++- profiles/testbot.lua | 2 ++ 13 files changed, 86 insertions(+), 20 deletions(-) diff --git a/Algorithms/StronglyConnectedComponents.h b/Algorithms/StronglyConnectedComponents.h index f9790568b..a5041eb04 100644 --- a/Algorithms/StronglyConnectedComponents.h +++ b/Algorithms/StronglyConnectedComponents.h @@ -76,6 +76,8 @@ private: boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph; boost::unordered_map _barrierNodes; boost::unordered_map _trafficLights; + boost::unordered_map _miniRoundabouts; + boost::unordered_map _trafficCalmingNodes; typedef std::pair RestrictionSource; typedef std::pair RestrictionTarget; @@ -120,7 +122,7 @@ private: NodeID parent; }; public: - TarjanSCC(int nodes, std::vector & inputEdges, std::vector & bn, std::vector & tl, std::vector<_Restriction> & irs, std::vector & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) { + TarjanSCC(int nodes, std::vector & inputEdges, std::vector & bn, std::vector & tl, std::vector & mrl, std::vector & tcl, std::vector<_Restriction> & irs, std::vector & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) { BOOST_FOREACH(_Restriction & restriction, irs) { std::pair restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); 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 ) { diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index 82ab09f11..7bb86e8fd 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -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 & inputEdges, std::vector & bn, std::vector & tl, std::vector<_Restriction> & irs, std::vector & nI, SpeedProfileProperties sp) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()), speedProfile(sp) { +EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector & inputEdges, std::vector & bn, std::vector & tl, std::vector & mrl, std::vector & tcl, std::vector<_Restriction> & irs, std::vector & nI, SpeedProfileProperties sp) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()), speedProfile(sp) { BOOST_FOREACH(_Restriction & restriction, irs) { std::pair restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); unsigned index; @@ -50,6 +50,12 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector 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; diff --git a/Contractor/EdgeBasedGraphFactory.h b/Contractor/EdgeBasedGraphFactory.h index 0fa0bb252..4e9675883 100644 --- a/Contractor/EdgeBasedGraphFactory.h +++ b/Contractor/EdgeBasedGraphFactory.h @@ -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 _barrierNodes; boost::unordered_map _trafficLights; + boost::unordered_map _miniRoundabouts; + boost::unordered_map _trafficCalmingNodes; typedef std::pair RestrictionSource; typedef std::pair RestrictionTarget; @@ -132,7 +136,7 @@ private: public: template< class InputEdgeT > - explicit EdgeBasedGraphFactory(int nodes, std::vector & inputEdges, std::vector & _bollardNodes, std::vector & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector & nI, SpeedProfileProperties speedProfile); + explicit EdgeBasedGraphFactory(int nodes, std::vector & inputEdges, std::vector & _bollardNodes, std::vector & trafficLights, std::vector & miniRoundabouts, std::vector & trafficCalmingNodes, std::vector<_Restriction> & inputRestrictions, std::vector & nI, SpeedProfileProperties speedProfile); void Run(const char * originalEdgeDataFilename); void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges ); diff --git a/DataStructures/ImportNode.h b/DataStructures/ImportNode.h index b9c27beff..3a81725bb 100644 --- a/DataStructures/ImportNode.h +++ b/DataStructures/ImportNode.h @@ -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::max)(), (std::numeric_limits::max)(), (std::numeric_limits::max)(), false, false); + return _Node((std::numeric_limits::max)(), (std::numeric_limits::max)(), (std::numeric_limits::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; } }; diff --git a/Extractor/ScriptingEnvironment.cpp b/Extractor/ScriptingEnvironment.cpp index ffba75a65..ea7b7b014 100644 --- a/Extractor/ScriptingEnvironment.cpp +++ b/Extractor/ScriptingEnvironment.cpp @@ -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) ]; diff --git a/Tools/componentAnalysis.cpp b/Tools/componentAnalysis.cpp index f1abd8ed2..3eaf50ce7 100644 --- a/Tools/componentAnalysis.cpp +++ b/Tools/componentAnalysis.cpp @@ -55,6 +55,8 @@ std::vector internalToExternalNodeMapping; std::vector<_Restriction> inputRestrictions; std::vector bollardNodes; std::vector trafficLightNodes; +std::vector miniRoundaboutNodes; +std::vector trafficCalmingNodes; int main (int argc, char *argv[]) { if(argc < 3) { @@ -81,21 +83,23 @@ int main (int argc, char *argv[]) { } std::vector 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().swap(edgeList); tarjan->Run(); std::vector<_Restriction>().swap(inputRestrictions); std::vector().swap(bollardNodes); std::vector().swap(trafficLightNodes); + std::vector().swap(miniRoundaboutNodes); + std::vector().swap(trafficCalmingNodes); INFO("finished component analysis"); return 0; } diff --git a/Util/GraphLoader.h b/Util/GraphLoader.h index ef04f8d8f..7aa96b518 100644 --- a/Util/GraphLoader.h +++ b/Util/GraphLoader.h @@ -48,7 +48,7 @@ struct _ExcessRemover { }; template -NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector& edgeList, std::vector &bollardNodes, std::vector &trafficLightNodes, std::vector * int2ExtNodeMap, std::vector<_Restriction> & inputRestrictions) { +NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector& edgeList, std::vector &bollardNodes, std::vector &trafficLightNodes, std::vector &miniRoundaboutNodes, std::vector &trafficCalmingNodes, std::vector * 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& 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(bollardNodes).swap(bollardNodes); std::vector(trafficLightNodes).swap(trafficLightNodes); + std::vector(miniRoundaboutNodes).swap(miniRoundaboutNodes); + std::vector(trafficCalmingNodes).swap(trafficCalmingNodes); in.read((char*)&m, sizeof(unsigned)); DEBUG(" and " << m << " edges "); diff --git a/createHierarchy.cpp b/createHierarchy.cpp index 44df57953..dd3206904 100644 --- a/createHierarchy.cpp +++ b/createHierarchy.cpp @@ -67,6 +67,8 @@ std::vector internalToExternalNodeMapping; std::vector<_Restriction> inputRestrictions; std::vector bollardNodes; std::vector trafficLightNodes; +std::vector miniRoundaboutNodes; +std::vector 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 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().swap(edgeList); edgeBasedGraphFactory->Run(edgeOut); std::vector<_Restriction>().swap(inputRestrictions); std::vector().swap(bollardNodes); std::vector().swap(trafficLightNodes); + std::vector().swap(miniRoundaboutNodes); + std::vector().swap(trafficCalmingNodes); NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes(); DeallocatingVector edgeBasedEdgeList; edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList); diff --git a/profile.lua b/profile.lua index b2291c1b0..ebc147897 100644 --- a/profile.lua +++ b/profile.lua @@ -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 diff --git a/profiles/bicycle.lua b/profiles/bicycle.lua index d2372afe6..e8d8df0d9 100644 --- a/profiles/bicycle.lua +++ b/profiles/bicycle.lua @@ -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 diff --git a/profiles/car.lua b/profiles/car.lua index b2291c1b0..351caad73 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -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 diff --git a/profiles/foot.lua b/profiles/foot.lua index 596917aa5..5627b3a33 100644 --- a/profiles/foot.lua +++ b/profiles/foot.lua @@ -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 diff --git a/profiles/testbot.lua b/profiles/testbot.lua index 3eb1ff339..9c78f80fe 100644 --- a/profiles/testbot.lua +++ b/profiles/testbot.lua @@ -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