From 7f69857376fd9b3a7c2eb9d267d57c03bace1410 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 18 Jan 2013 16:40:12 +0100 Subject: [PATCH 01/12] Support for backward speed in extractor --- Extractor/ExtractorCallbacks.cpp | 99 +++++++++++++++++++----------- Extractor/ExtractorStructs.h | 14 +++-- Extractor/ScriptingEnvironment.cpp | 1 + 3 files changed, 75 insertions(+), 39 deletions(-) diff --git a/Extractor/ExtractorCallbacks.cpp b/Extractor/ExtractorCallbacks.cpp index 3db1d8d8b..75da55032 100644 --- a/Extractor/ExtractorCallbacks.cpp +++ b/Extractor/ExtractorCallbacks.cpp @@ -44,8 +44,8 @@ or see http://www.gnu.org/licenses/agpl.txt. ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; } ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) { - externalMemory = ext; - stringMap = strMap; + externalMemory = ext; + stringMap = strMap; } ExtractorCallbacks::~ExtractorCallbacks() { @@ -64,42 +64,71 @@ bool ExtractorCallbacks::restrictionFunction(_RawRestrictionContainer &r) { } /** warning: caller needs to take care of synchronization! */ -bool ExtractorCallbacks::wayFunction(_Way &w) { - /*** Store name of way and split it into edge segments ***/ +bool ExtractorCallbacks::wayFunction(_Way &parsed_way) { + if ( parsed_way.speed > 0 ) { //Only true if the way is specified by the speed profile + if(parsed_way.id == UINT_MAX){ + 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 + const StringMap::const_iterator string_map_iterator = stringMap->find(parsed_way.name); + if(string_map_iterator == stringMap->end()) { + parsed_way.nameID = externalMemory->nameVector.size(); + externalMemory->nameVector.push_back(parsed_way.name); + stringMap->insert(StringMap::value_type(parsed_way.name, parsed_way.nameID)); + } else { + parsed_way.nameID = string_map_iterator->second; + } - if ( w.speed > 0 ) { //Only true if the way is specified by the speed profile + if ( parsed_way.direction == _Way::opposite ){ + std::reverse( parsed_way.path.begin(), parsed_way.path.end() ); + } - //Get the unique identifier for the street name - const StringMap::const_iterator strit = stringMap->find(w.name); - if(strit == stringMap->end()) { - w.nameID = externalMemory->nameVector.size(); - externalMemory->nameVector.push_back(w.name); - stringMap->insert(StringMap::value_type(w.name, w.nameID)); - } else { - w.nameID = strit->second; - } + if( parsed_way.backward_speed > 0 && parsed_way.direction == _Way::bidirectional) { + parsed_way.direction == _Way::oneway; + } - if(fabs(-1. - w.speed) < FLT_EPSILON){ - WARN("found way with bogus speed, id: " << w.id); - return true; - } - if(w.id == UINT_MAX) { - WARN("found way with unknown type: " << w.id); - return true; - } + for(std::vector< NodeID >::size_type n = 0; n < parsed_way.path.size()-1; ++n) { + externalMemory->allEdges.push_back( + _Edge(parsed_way.path[n], + parsed_way.path[n+1], + parsed_way.type, + (_Way::bidirectional == parsed_way.direction && parsed_way.backward_speed > 0 ? _Way::oneway : parsed_way.direction), + parsed_way.speed, + parsed_way.nameID, + parsed_way.roundabout, + parsed_way.ignoreInGrid, + parsed_way.isDurationSet, + parsed_way.isAccessRestricted + ) + ); + externalMemory->usedNodeIDs.push_back(parsed_way.path[n]); + } + externalMemory->usedNodeIDs.push_back(parsed_way.path.back()); - if ( w.direction == _Way::opposite ){ - std::reverse( w.path.begin(), w.path.end() ); - } + //The following information is needed to identify start and end segments of restrictions + 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())); - for(std::vector< NodeID >::size_type n = 0; n < w.path.size()-1; ++n) { - 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.isDurationSet, w.isAccessRestricted)); - externalMemory->usedNodeIDs.push_back(w.path[n]); - } - externalMemory->usedNodeIDs.push_back(w.path.back()); - - //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])); - } - return true; + if ( parsed_way.backward_speed > 0 ) { //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( + _Edge(parsed_way.path[n], + parsed_way.path[n+1], + parsed_way.type, + _Way::oneway, + parsed_way.backward_speed, + parsed_way.nameID, + parsed_way.roundabout, + parsed_way.ignoreInGrid, + parsed_way.isDurationSet, + parsed_way.isAccessRestricted, + (_Way::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; } diff --git a/Extractor/ExtractorStructs.h b/Extractor/ExtractorStructs.h index fe5dd1b40..ad508fdaf 100644 --- a/Extractor/ExtractorStructs.h +++ b/Extractor/ExtractorStructs.h @@ -52,6 +52,7 @@ struct _Way { keyVals.EraseAll(); direction = _Way::notSure; speed = -1; + backward_speed = -1; type = -1; access = true; roundabout = false; @@ -67,6 +68,7 @@ struct _Way { unsigned nameID; std::string name; double speed; + double backward_speed; short type; bool access; bool roundabout; @@ -86,10 +88,13 @@ struct _Relation { }; struct _Edge { - _Edge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(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) { } - _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) { } - _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) { + _Edge() : 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), 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), 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), isContraFlow(false) { + assert(0 <= type); + } + _Edge(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); } NodeID start; @@ -102,6 +107,7 @@ struct _Edge { bool ignoreInGrid; bool isDurationSet; bool isAccessRestricted; + bool isContraFlow; _Coordinate startCoord; _Coordinate targetCoord; diff --git a/Extractor/ScriptingEnvironment.cpp b/Extractor/ScriptingEnvironment.cpp index c2f42d79d..b4b6af54e 100644 --- a/Extractor/ScriptingEnvironment.cpp +++ b/Extractor/ScriptingEnvironment.cpp @@ -68,6 +68,7 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { luabind::class_<_Way>("Way") .def(luabind::constructor<>()) .def_readwrite("name", &_Way::name) + .def_readwrite("backward_speed", &_Way::backward_speed) .def_readwrite("speed", &_Way::speed) .def_readwrite("type", &_Way::type) .def_readwrite("access", &_Way::access) From b19e2fbafedd4600b60bfa4bce7364899b94d2b0 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 18 Jan 2013 16:42:04 +0100 Subject: [PATCH 02/12] Fixing test for opposite directions --- features/testbot/opposite.feature | 12 ++++++------ profiles/testbot.lua | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/features/testbot/opposite.feature b/features/testbot/opposite.feature index 176974965..9b5df779d 100644 --- a/features/testbot/opposite.feature +++ b/features/testbot/opposite.feature @@ -1,4 +1,4 @@ -@routing @opposite @todo +@routing @opposite Feature: Separate settings for forward/backward direction Background: @@ -7,13 +7,13 @@ Feature: Separate settings for forward/backward direction @smallest Scenario: Going against the flow Given the node map - | a | b | + | a | b | c | d | And the ways | nodes | highway | - | ab | river | + | abcd | river | When I route I should get - | from | to | route | distance | time | - | a | b | ab | 100m | 10s | - | b | a | ab | 100m | 20s | + | from | to | route | distance | time | + | a | d | abcd | 300 +- 1m | 30s | + | d | a | abcd | 300 +- 1m | 55s | diff --git a/profiles/testbot.lua b/profiles/testbot.lua index 3eb1ff339..341cb6d23 100644 --- a/profiles/testbot.lua +++ b/profiles/testbot.lua @@ -56,6 +56,12 @@ function way_function (way, numberOfNodesInWay) way.speed = speed_profile[highway] or speed_profile['default'] end + if(highway == "river") then + local temp_speed = way.speed; + way.speed = temp_speed*3/2 + way.backward_speed = temp_speed*2/3 + end + if oneway == "no" or oneway == "0" or oneway == "false" then way.direction = Way.bidirectional elseif oneway == "-1" then From 1a6c01769ea990babcdde1e7a29cc9036d06f820 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 18 Jan 2013 16:40:12 +0100 Subject: [PATCH 03/12] Support for backward speed in extractor --- Extractor/ExtractorCallbacks.cpp | 99 +++++++++++++++++++----------- Extractor/ExtractorStructs.h | 14 +++-- Extractor/ScriptingEnvironment.cpp | 1 + 3 files changed, 75 insertions(+), 39 deletions(-) diff --git a/Extractor/ExtractorCallbacks.cpp b/Extractor/ExtractorCallbacks.cpp index 3db1d8d8b..75da55032 100644 --- a/Extractor/ExtractorCallbacks.cpp +++ b/Extractor/ExtractorCallbacks.cpp @@ -44,8 +44,8 @@ or see http://www.gnu.org/licenses/agpl.txt. ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; } ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) { - externalMemory = ext; - stringMap = strMap; + externalMemory = ext; + stringMap = strMap; } ExtractorCallbacks::~ExtractorCallbacks() { @@ -64,42 +64,71 @@ bool ExtractorCallbacks::restrictionFunction(_RawRestrictionContainer &r) { } /** warning: caller needs to take care of synchronization! */ -bool ExtractorCallbacks::wayFunction(_Way &w) { - /*** Store name of way and split it into edge segments ***/ +bool ExtractorCallbacks::wayFunction(_Way &parsed_way) { + if ( parsed_way.speed > 0 ) { //Only true if the way is specified by the speed profile + if(parsed_way.id == UINT_MAX){ + 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 + const StringMap::const_iterator string_map_iterator = stringMap->find(parsed_way.name); + if(string_map_iterator == stringMap->end()) { + parsed_way.nameID = externalMemory->nameVector.size(); + externalMemory->nameVector.push_back(parsed_way.name); + stringMap->insert(StringMap::value_type(parsed_way.name, parsed_way.nameID)); + } else { + parsed_way.nameID = string_map_iterator->second; + } - if ( w.speed > 0 ) { //Only true if the way is specified by the speed profile + if ( parsed_way.direction == _Way::opposite ){ + std::reverse( parsed_way.path.begin(), parsed_way.path.end() ); + } - //Get the unique identifier for the street name - const StringMap::const_iterator strit = stringMap->find(w.name); - if(strit == stringMap->end()) { - w.nameID = externalMemory->nameVector.size(); - externalMemory->nameVector.push_back(w.name); - stringMap->insert(StringMap::value_type(w.name, w.nameID)); - } else { - w.nameID = strit->second; - } + if( parsed_way.backward_speed > 0 && parsed_way.direction == _Way::bidirectional) { + parsed_way.direction == _Way::oneway; + } - if(fabs(-1. - w.speed) < FLT_EPSILON){ - WARN("found way with bogus speed, id: " << w.id); - return true; - } - if(w.id == UINT_MAX) { - WARN("found way with unknown type: " << w.id); - return true; - } + for(std::vector< NodeID >::size_type n = 0; n < parsed_way.path.size()-1; ++n) { + externalMemory->allEdges.push_back( + _Edge(parsed_way.path[n], + parsed_way.path[n+1], + parsed_way.type, + (_Way::bidirectional == parsed_way.direction && parsed_way.backward_speed > 0 ? _Way::oneway : parsed_way.direction), + parsed_way.speed, + parsed_way.nameID, + parsed_way.roundabout, + parsed_way.ignoreInGrid, + parsed_way.isDurationSet, + parsed_way.isAccessRestricted + ) + ); + externalMemory->usedNodeIDs.push_back(parsed_way.path[n]); + } + externalMemory->usedNodeIDs.push_back(parsed_way.path.back()); - if ( w.direction == _Way::opposite ){ - std::reverse( w.path.begin(), w.path.end() ); - } + //The following information is needed to identify start and end segments of restrictions + 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())); - for(std::vector< NodeID >::size_type n = 0; n < w.path.size()-1; ++n) { - 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.isDurationSet, w.isAccessRestricted)); - externalMemory->usedNodeIDs.push_back(w.path[n]); - } - externalMemory->usedNodeIDs.push_back(w.path.back()); - - //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])); - } - return true; + if ( parsed_way.backward_speed > 0 ) { //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( + _Edge(parsed_way.path[n], + parsed_way.path[n+1], + parsed_way.type, + _Way::oneway, + parsed_way.backward_speed, + parsed_way.nameID, + parsed_way.roundabout, + parsed_way.ignoreInGrid, + parsed_way.isDurationSet, + parsed_way.isAccessRestricted, + (_Way::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; } diff --git a/Extractor/ExtractorStructs.h b/Extractor/ExtractorStructs.h index fe5dd1b40..ad508fdaf 100644 --- a/Extractor/ExtractorStructs.h +++ b/Extractor/ExtractorStructs.h @@ -52,6 +52,7 @@ struct _Way { keyVals.EraseAll(); direction = _Way::notSure; speed = -1; + backward_speed = -1; type = -1; access = true; roundabout = false; @@ -67,6 +68,7 @@ struct _Way { unsigned nameID; std::string name; double speed; + double backward_speed; short type; bool access; bool roundabout; @@ -86,10 +88,13 @@ struct _Relation { }; struct _Edge { - _Edge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(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) { } - _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) { } - _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) { + _Edge() : 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), 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), 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), isContraFlow(false) { + assert(0 <= type); + } + _Edge(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); } NodeID start; @@ -102,6 +107,7 @@ struct _Edge { bool ignoreInGrid; bool isDurationSet; bool isAccessRestricted; + bool isContraFlow; _Coordinate startCoord; _Coordinate targetCoord; diff --git a/Extractor/ScriptingEnvironment.cpp b/Extractor/ScriptingEnvironment.cpp index c2f42d79d..b4b6af54e 100644 --- a/Extractor/ScriptingEnvironment.cpp +++ b/Extractor/ScriptingEnvironment.cpp @@ -68,6 +68,7 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { luabind::class_<_Way>("Way") .def(luabind::constructor<>()) .def_readwrite("name", &_Way::name) + .def_readwrite("backward_speed", &_Way::backward_speed) .def_readwrite("speed", &_Way::speed) .def_readwrite("type", &_Way::type) .def_readwrite("access", &_Way::access) From 7f311551ddfa8a5cc8fc21c13c1d5dcbed1775f9 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 18 Jan 2013 16:42:04 +0100 Subject: [PATCH 04/12] Fixing test for opposite directions --- features/testbot/opposite.feature | 12 ++++++------ profiles/testbot.lua | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/features/testbot/opposite.feature b/features/testbot/opposite.feature index 176974965..9b5df779d 100644 --- a/features/testbot/opposite.feature +++ b/features/testbot/opposite.feature @@ -1,4 +1,4 @@ -@routing @opposite @todo +@routing @opposite Feature: Separate settings for forward/backward direction Background: @@ -7,13 +7,13 @@ Feature: Separate settings for forward/backward direction @smallest Scenario: Going against the flow Given the node map - | a | b | + | a | b | c | d | And the ways | nodes | highway | - | ab | river | + | abcd | river | When I route I should get - | from | to | route | distance | time | - | a | b | ab | 100m | 10s | - | b | a | ab | 100m | 20s | + | from | to | route | distance | time | + | a | d | abcd | 300 +- 1m | 30s | + | d | a | abcd | 300 +- 1m | 55s | diff --git a/profiles/testbot.lua b/profiles/testbot.lua index 3eb1ff339..341cb6d23 100644 --- a/profiles/testbot.lua +++ b/profiles/testbot.lua @@ -56,6 +56,12 @@ function way_function (way, numberOfNodesInWay) way.speed = speed_profile[highway] or speed_profile['default'] end + if(highway == "river") then + local temp_speed = way.speed; + way.speed = temp_speed*3/2 + way.backward_speed = temp_speed*2/3 + end + if oneway == "no" or oneway == "0" or oneway == "false" then way.direction = Way.bidirectional elseif oneway == "-1" then From fc24dbf9b7e423384aceefa5b058b80bf209f0fd Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 18 Jan 2013 19:06:03 +0100 Subject: [PATCH 05/12] Added new TurnInstruction that indicates when to go against oneway streets. It's important for cycling. --- DataStructures/TurnInstructions.h | 41 +++---------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/DataStructures/TurnInstructions.h b/DataStructures/TurnInstructions.h index 2e709831d..66188f923 100644 --- a/DataStructures/TurnInstructions.h +++ b/DataStructures/TurnInstructions.h @@ -21,12 +21,12 @@ #ifndef TURNINSTRUCTIONS_H_ #define TURNINSTRUCTIONS_H_ -#include +#include typedef unsigned char TurnInstruction; //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 GoStraight = 1; //Tell user to go straight! @@ -44,48 +44,13 @@ struct TurnInstructionsClass { const static TurnInstruction StayOnRoundAbout = 13; const static TurnInstruction StartAtEndOfStreet = 14; const static TurnInstruction ReachedYourDestination = 15; + const static TurnInstruction GoAgainstAllowedDirection = 32; const static TurnInstruction AccessRestrictionFlag = 128; const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning. const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag -// 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 ) { if(angle >= 23 && angle < 67) { return TurnSharpRight; From 9961172d70c9494807f4692e9cbd8d977a54a62e Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 18 Jan 2013 19:33:51 +0100 Subject: [PATCH 06/12] Fixing constant --- DataStructures/TurnInstructions.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DataStructures/TurnInstructions.h b/DataStructures/TurnInstructions.h index 66188f923..3284d9bbe 100644 --- a/DataStructures/TurnInstructions.h +++ b/DataStructures/TurnInstructions.h @@ -44,7 +44,8 @@ struct TurnInstructionsClass : boost::noncopyable { const static TurnInstruction StayOnRoundAbout = 13; const static TurnInstruction StartAtEndOfStreet = 14; const static TurnInstruction ReachedYourDestination = 15; - const static TurnInstruction GoAgainstAllowedDirection = 32; + const static TurnInstruction EnterAgainstAllowedDirection = 16; + const static TurnInstruction LeaveAgainstAllowedDirection = 17; const static TurnInstruction AccessRestrictionFlag = 128; const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning. From cf5c776990486d878254a48109d69122e46bf836 Mon Sep 17 00:00:00 2001 From: DennisOSRM Date: Fri, 18 Jan 2013 21:28:13 +0100 Subject: [PATCH 07/12] Implementing logic when route is going against one-way flow (think bikes!) --- Contractor/EdgeBasedGraphFactory.cpp | 15 ++++++- Contractor/EdgeBasedGraphFactory.h | 63 ++++++++++++++-------------- DataStructures/ImportEdge.h | 16 ++++--- Extractor/ExtractionContainers.cpp | 9 ++-- Extractor/ExtractionContainers.h | 2 +- Extractor/ExtractorCallbacks.cpp | 18 ++++---- Extractor/ExtractorCallbacks.h | 2 +- Extractor/ExtractorStructs.h | 62 +++++++++++++-------------- Extractor/PBFParser.cpp | 8 ++-- Extractor/PBFParser.h | 2 +- Extractor/ScriptingEnvironment.cpp | 24 +++++------ Extractor/XMLParser.cpp | 6 +-- Extractor/XMLParser.h | 4 +- Util/GraphLoader.h | 5 ++- extractor.cpp | 4 +- 15 files changed, 125 insertions(+), 115 deletions(-) diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index 994c4cc07..b6bc1e437 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -79,6 +79,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vectortype(); edge.data.isAccessRestricted = i->isAccessRestricted(); edge.data.edgeBasedNodeID = edges.size(); + edge.data.contraFlow = i->isContraFlow(); edges.push_back( edge ); if( edge.data.backward ) { std::swap( edge.source, edge.target ); @@ -342,6 +343,13 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID _NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1); _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 if(data1.roundabout && data2.roundabout) { //Is a turn possible? If yes, we stay on the roundabout! @@ -363,10 +371,13 @@ 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( (data1.nameID == data2.nameID) && (0 != data1.nameID)) + if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) { 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) ) { + ERR("should not happen"); return TurnInstructions.NoTurn; + } double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]); return TurnInstructions.GetTurnDirectionOfInstruction(angle); diff --git a/Contractor/EdgeBasedGraphFactory.h b/Contractor/EdgeBasedGraphFactory.h index 2b4c18d7f..d4cc91888 100644 --- a/Contractor/EdgeBasedGraphFactory.h +++ b/Contractor/EdgeBasedGraphFactory.h @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -48,34 +49,7 @@ #include "../DataStructures/TurnInstructions.h" #include "../Util/BaseConfiguration.h" -class EdgeBasedGraphFactory { -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 inputNodeInfoList; - unsigned numberOfTurnRestrictions; +class EdgeBasedGraphFactory : boost::noncopyable { public: struct EdgeBasedNode { bool operator<(const EdgeBasedNode & other) const { @@ -95,13 +69,41 @@ public: bool ignoreInGrid:1; }; - struct SpeedProfileProperties{ SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0) {} int trafficSignalPenalty; int uTurnPenalty; } speedProfile; + 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 inputNodeInfoList; + unsigned numberOfTurnRestrictions; + boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph; boost::unordered_map _barrierNodes; boost::unordered_map _trafficLights; @@ -113,7 +115,6 @@ private: std::vector _restrictionBucketVector; RestrictionMap _restrictionMap; - DeallocatingVector edgeBasedEdges; DeallocatingVector edgeBasedNodes; std::vector originalEdgeData; @@ -127,8 +128,6 @@ private: bool belongsToTinyComponent); template double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const; -// SRTMLookup srtmLookup; - public: template< class InputEdgeT > diff --git a/DataStructures/ImportEdge.h b/DataStructures/ImportEdge.h index a90cd474d..1b5966c40 100644 --- a/DataStructures/ImportEdge.h +++ b/DataStructures/ImportEdge.h @@ -40,12 +40,8 @@ public: return (source() < e.source()); } - /** 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) { 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);}; } + explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar, bool cf) : + _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);}; } NodeID target() const {return _target; } NodeID source() const {return _source; } @@ -59,6 +55,7 @@ public: bool isRoundabout() const { return _roundabout; } bool ignoreInGrid() const { return _ignoreInGrid; } bool isAccessRestricted() const { return _accessRestricted; } + bool isContraFlow() const { return _contraFlow; } NodeID _source; NodeID _target; @@ -70,6 +67,13 @@ public: bool _roundabout; bool _ignoreInGrid; 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 { diff --git a/Extractor/ExtractionContainers.cpp b/Extractor/ExtractionContainers.cpp index 93a0fd674..b2476bc86 100644 --- a/Extractor/ExtractionContainers.cpp +++ b/Extractor/ExtractionContainers.cpp @@ -231,17 +231,17 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const fout.write((char*)&edgeIT->target, sizeof(unsigned)); fout.write((char*)&intDist, sizeof(int)); switch(edgeIT->direction) { - case _Way::notSure: + case ExtractionWay::notSure: fout.write((char*)&zero, sizeof(short)); break; - case _Way::oneway: + case ExtractionWay::oneway: fout.write((char*)&one, sizeof(short)); break; - case _Way::bidirectional: + case ExtractionWay::bidirectional: fout.write((char*)&zero, sizeof(short)); break; - case _Way::opposite: + case ExtractionWay::opposite: fout.write((char*)&one, sizeof(short)); break; default: @@ -256,6 +256,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const fout.write((char*)&edgeIT->isRoundabout, sizeof(bool)); fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool)); fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool)); + fout.write((char*)&edgeIT->isContraFlow, sizeof(bool)); } ++usedEdgeCounter; ++edgeIT; diff --git a/Extractor/ExtractionContainers.h b/Extractor/ExtractionContainers.h index 7e8a1d7be..abf718d5f 100644 --- a/Extractor/ExtractionContainers.h +++ b/Extractor/ExtractionContainers.h @@ -31,7 +31,7 @@ class ExtractionContainers { public: typedef stxxl::vector STXXLNodeIDVector; typedef stxxl::vector<_Node> STXXLNodeVector; - typedef stxxl::vector<_Edge> STXXLEdgeVector; + typedef stxxl::vector STXXLEdgeVector; typedef stxxl::vector STXXLStringVector; typedef stxxl::vector<_RawRestrictionContainer> STXXLRestrictionsVector; typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector; diff --git a/Extractor/ExtractorCallbacks.cpp b/Extractor/ExtractorCallbacks.cpp index 75da55032..6a5ee1c14 100644 --- a/Extractor/ExtractorCallbacks.cpp +++ b/Extractor/ExtractorCallbacks.cpp @@ -64,7 +64,7 @@ bool ExtractorCallbacks::restrictionFunction(_RawRestrictionContainer &r) { } /** warning: caller needs to take care of synchronization! */ -bool ExtractorCallbacks::wayFunction(_Way &parsed_way) { +bool ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) { if ( parsed_way.speed > 0 ) { //Only true if the way is specified by the speed profile if(parsed_way.id == UINT_MAX){ WARN("found bogus way with id: " << parsed_way.id << " of size " << parsed_way.path.size()); @@ -80,20 +80,20 @@ bool ExtractorCallbacks::wayFunction(_Way &parsed_way) { parsed_way.nameID = string_map_iterator->second; } - if ( parsed_way.direction == _Way::opposite ){ + if ( parsed_way.direction == ExtractionWay::opposite ){ std::reverse( parsed_way.path.begin(), parsed_way.path.end() ); } - if( parsed_way.backward_speed > 0 && parsed_way.direction == _Way::bidirectional) { - parsed_way.direction == _Way::oneway; + if( parsed_way.backward_speed > 0 && parsed_way.direction == ExtractionWay::bidirectional) { + parsed_way.direction = ExtractionWay::oneway; } for(std::vector< NodeID >::size_type n = 0; n < parsed_way.path.size()-1; ++n) { externalMemory->allEdges.push_back( - _Edge(parsed_way.path[n], + InternalExtractorEdge(parsed_way.path[n], parsed_way.path[n+1], parsed_way.type, - (_Way::bidirectional == parsed_way.direction && parsed_way.backward_speed > 0 ? _Way::oneway : parsed_way.direction), + (ExtractionWay::bidirectional == parsed_way.direction && parsed_way.backward_speed > 0 ? ExtractionWay::oneway : parsed_way.direction), parsed_way.speed, parsed_way.nameID, parsed_way.roundabout, @@ -113,17 +113,17 @@ bool ExtractorCallbacks::wayFunction(_Way &parsed_way) { 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( - _Edge(parsed_way.path[n], + InternalExtractorEdge(parsed_way.path[n], parsed_way.path[n+1], parsed_way.type, - _Way::oneway, + ExtractionWay::oneway, parsed_way.backward_speed, parsed_way.nameID, parsed_way.roundabout, parsed_way.ignoreInGrid, parsed_way.isDurationSet, parsed_way.isAccessRestricted, - (_Way::oneway == parsed_way.direction) + (ExtractionWay::oneway == parsed_way.direction) ) ); } diff --git a/Extractor/ExtractorCallbacks.h b/Extractor/ExtractorCallbacks.h index 70f812ec2..3ddbbe841 100644 --- a/Extractor/ExtractorCallbacks.h +++ b/Extractor/ExtractorCallbacks.h @@ -50,7 +50,7 @@ public: bool restrictionFunction(_RawRestrictionContainer &r); /** warning: caller needs to take care of synchronization! */ - bool wayFunction(_Way &w); + bool wayFunction(ExtractionWay &w); }; diff --git a/Extractor/ExtractorStructs.h b/Extractor/ExtractorStructs.h index ad508fdaf..c1ccbfe6e 100644 --- a/Extractor/ExtractorStructs.h +++ b/Extractor/ExtractorStructs.h @@ -40,8 +40,8 @@ or see http://www.gnu.org/licenses/agpl.txt. typedef boost::unordered_map StringMap; typedef boost::unordered_map > StringToIntPairMap; -struct _Way { - _Way() { +struct ExtractionWay { + ExtractionWay() { Clear(); } @@ -50,7 +50,7 @@ struct _Way { nameID = UINT_MAX; path.clear(); keyVals.EraseAll(); - direction = _Way::notSure; + direction = ExtractionWay::notSure; speed = -1; backward_speed = -1; type = -1; @@ -79,22 +79,22 @@ struct _Way { HashTable keyVals; }; -struct _Relation { - _Relation() : type(unknown){} +struct ExtractorRelation { + ExtractorRelation() : type(unknown){} enum { unknown = 0, ferry, turnRestriction } type; HashTable keyVals; }; -struct _Edge { - _Edge() : 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), 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), 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), isContraFlow(false) { +struct InternalExtractorEdge { + InternalExtractorEdge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(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) { } + 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) { } + 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); } - _Edge(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) { + 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); } NodeID start; @@ -112,15 +112,16 @@ struct _Edge { _Coordinate startCoord; _Coordinate targetCoord; - static _Edge min_value() { - return _Edge(0,0); + static InternalExtractorEdge min_value() { + return InternalExtractorEdge(0,0); } - static _Edge max_value() { - return _Edge((std::numeric_limits::max)(), (std::numeric_limits::max)()); + static InternalExtractorEdge max_value() { + return InternalExtractorEdge((std::numeric_limits::max)(), (std::numeric_limits::max)()); } - }; + + struct _WayIDStartAndEndEdge { unsigned wayID; NodeID firstStart; @@ -177,34 +178,29 @@ struct CmpNodeByID : public std::binary_function<_Node, _Node, bool> { } }; -struct CmpEdgeByStartID : public std::binary_function<_Edge, _Edge, bool> -{ - typedef _Edge value_type; - bool operator () (const _Edge & a, const _Edge & b) const { +struct CmpEdgeByStartID : public std::binary_function { + typedef InternalExtractorEdge value_type; + bool operator () (const InternalExtractorEdge & a, const InternalExtractorEdge & b) const { return a.start < b.start; } value_type max_value() { - return _Edge::max_value(); + return InternalExtractorEdge::max_value(); } value_type min_value() { - return _Edge::min_value(); + return InternalExtractorEdge::min_value(); } }; -struct CmpEdgeByTargetID : public std::binary_function<_Edge, _Edge, bool> -{ - typedef _Edge value_type; - bool operator () (const _Edge & a, const _Edge & b) const - { +struct CmpEdgeByTargetID : public std::binary_function { + typedef InternalExtractorEdge value_type; + bool operator () (const InternalExtractorEdge & a, const InternalExtractorEdge & b) const { return a.target < b.target; } - value_type max_value() - { - return _Edge::max_value(); + value_type max_value() { + return InternalExtractorEdge::max_value(); } - value_type min_value() - { - return _Edge::min_value(); + value_type min_value() { + return InternalExtractorEdge::min_value(); } }; diff --git a/Extractor/PBFParser.cpp b/Extractor/PBFParser.cpp index d86fbc457..222475db6 100644 --- a/Extractor/PBFParser.cpp +++ b/Extractor/PBFParser.cpp @@ -332,8 +332,8 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) { } inline void PBFParser::parseWay(_ThreadData * threadData) { - _Way w; - std::vector<_Way> waysToParse(threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size()); + ExtractionWay w; + std::vector 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) { w.Clear(); 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(); #pragma omp parallel for schedule ( guided ) 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 **/ try { luabind::call_function( @@ -376,7 +376,7 @@ inline void PBFParser::parseWay(_ThreadData * threadData) { // } } - BOOST_FOREACH(_Way & w, waysToParse) { + BOOST_FOREACH(ExtractionWay & w, waysToParse) { if(!externalMemory->wayFunction(w)) { std::cerr << "[PBFParser] way not parsed" << std::endl; } diff --git a/Extractor/PBFParser.h b/Extractor/PBFParser.h index ed469272d..d3da02706 100644 --- a/Extractor/PBFParser.h +++ b/Extractor/PBFParser.h @@ -41,7 +41,7 @@ #include "ExtractorStructs.h" #include "ScriptingEnvironment.h" -class PBFParser : public BaseParser { +class PBFParser : public BaseParser { enum EntityType { TypeNode = 1, diff --git a/Extractor/ScriptingEnvironment.cpp b/Extractor/ScriptingEnvironment.cpp index b4b6af54e..ca8d9a754 100644 --- a/Extractor/ScriptingEnvironment.cpp +++ b/Extractor/ScriptingEnvironment.cpp @@ -65,19 +65,19 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { ]; luabind::module(myLuaState) [ - luabind::class_<_Way>("Way") + luabind::class_("Way") .def(luabind::constructor<>()) - .def_readwrite("name", &_Way::name) - .def_readwrite("backward_speed", &_Way::backward_speed) - .def_readwrite("speed", &_Way::speed) - .def_readwrite("type", &_Way::type) - .def_readwrite("access", &_Way::access) - .def_readwrite("roundabout", &_Way::roundabout) - .def_readwrite("is_duration_set", &_Way::isDurationSet) - .def_readwrite("is_access_restricted", &_Way::isAccessRestricted) - .def_readwrite("ignore_in_grid", &_Way::ignoreInGrid) - .def_readwrite("tags", &_Way::keyVals) - .def_readwrite("direction", &_Way::direction) + .def_readwrite("name", &ExtractionWay::name) + .def_readwrite("backward_speed", &ExtractionWay::backward_speed) + .def_readwrite("speed", &ExtractionWay::speed) + .def_readwrite("type", &ExtractionWay::type) + .def_readwrite("access", &ExtractionWay::access) + .def_readwrite("roundabout", &ExtractionWay::roundabout) + .def_readwrite("is_duration_set", &ExtractionWay::isDurationSet) + .def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted) + .def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid) + .def_readwrite("tags", &ExtractionWay::keyVals) + .def_readwrite("direction", &ExtractionWay::direction) .enum_("constants") [ luabind::value("notSure", 0), diff --git a/Extractor/XMLParser.cpp b/Extractor/XMLParser.cpp index 6449add3f..5faa5a71e 100644 --- a/Extractor/XMLParser.cpp +++ b/Extractor/XMLParser.cpp @@ -100,7 +100,7 @@ bool XMLParser::Parse() { } if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) { - _Way way = _ReadXMLWay( ); + ExtractionWay way = _ReadXMLWay( ); /** Pass the unpacked way to the LUA call back **/ try { @@ -222,8 +222,8 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() { return restriction; } -_Way XMLParser::_ReadXMLWay() { - _Way way; +ExtractionWay XMLParser::_ReadXMLWay() { + ExtractionWay way; if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { const int depth = xmlTextReaderDepth( inputReader ); while ( xmlTextReaderRead( inputReader ) == 1 ) { diff --git a/Extractor/XMLParser.h b/Extractor/XMLParser.h index d87c50145..3bc54825d 100644 --- a/Extractor/XMLParser.h +++ b/Extractor/XMLParser.h @@ -28,7 +28,7 @@ #include "ExtractorCallbacks.h" #include "ScriptingEnvironment.h" -class XMLParser : public BaseParser { +class XMLParser : public BaseParser { public: XMLParser(const char * filename); virtual ~XMLParser(); @@ -39,7 +39,7 @@ public: private: _RawRestrictionContainer _ReadXMLRestriction(); - _Way _ReadXMLWay(); + ExtractionWay _ReadXMLWay(); ImportNode _ReadXMLNode( ); /* Input Reader */ xmlTextReaderPtr inputReader; diff --git a/Util/GraphLoader.h b/Util/GraphLoader.h index b22086c39..40bc98a9c 100644 --- a/Util/GraphLoader.h +++ b/Util/GraphLoader.h @@ -101,7 +101,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector& edgeL short type; NodeID nameID; int length; - bool isRoundabout, ignoreInGrid, isAccessRestricted; + bool isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow; for (EdgeID i=0; i& edgeL in.read((char*)&isRoundabout, sizeof(bool)); in.read((char*)&ignoreInGrid, sizeof(bool)); in.read((char*)&isAccessRestricted, sizeof(bool)); + in.read((char*)&isContraFlow, sizeof(bool)); GUARANTEE(length > 0, "loaded null length edge" ); GUARANTEE(weight > 0, "loaded null weight"); @@ -150,7 +151,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector& edgeL 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); } std::sort(edgeList.begin(), edgeList.end()); diff --git a/extractor.cpp b/extractor.cpp index d212a837e..1aa72f83b 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -58,7 +58,6 @@ int main (int argc, char *argv[]) { } omp_set_num_threads(numberOfThreads); - INFO("extracting data from input file " << argv[1]); bool isPBF(false); std::string outputFileName(argv[1]); @@ -93,10 +92,9 @@ int main (int argc, char *argv[]) { StringMap stringMap; ExtractionContainers externalMemory; - stringMap[""] = 0; extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap); - BaseParser * parser; + BaseParser * parser; if(isPBF) { parser = new PBFParser(argv[1]); } else { From 35255d052d70b8698534cff02c24c8cec09b9398 Mon Sep 17 00:00:00 2001 From: Emil Tin Date: Sat, 12 Jan 2013 19:15:08 +0100 Subject: [PATCH 08/12] support comments in test tables --- features/step_definitions/routing.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/features/step_definitions/routing.rb b/features/step_definitions/routing.rb index 32e6f60e5..17a3251c0 100644 --- a/features/step_definitions/routing.rb +++ b/features/step_definitions/routing.rb @@ -46,6 +46,9 @@ When /^I route I should get$/ do |table| if table.headers.include? 'turns' got['turns'] = turns end + if table.headers.include? '#' # comment column + got['#'] = row['#'] # copy value so it always match + end end ok = true From 7c8bf18cc6929db04b88acf6336979efa196d057 Mon Sep 17 00:00:00 2001 From: Emil Tin Date: Fri, 18 Jan 2013 22:10:11 +0100 Subject: [PATCH 09/12] test forward/backward maxspeed (car) --- features/car/maxspeed.feature | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/features/car/maxspeed.feature b/features/car/maxspeed.feature index cc31c6c13..abdb72a9e 100644 --- a/features/car/maxspeed.feature +++ b/features/car/maxspeed.feature @@ -32,3 +32,26 @@ Feature: Car - Max speed restrictions | from | to | route | time | | a | b | ab | 144s ~10% | | b | c | bc | 144s ~10% | + + @oppposite @todo + Scenario: Car - Forward/backward maxspeed + Given the node map + | a | b | c | d | e | + + And the ways + | nodes | highway | maxspeed:forward | maxspeed:backward | + | ab | primary | | | + | bc | primart | 18 | 9 | + | cd | primart | | 9 | + | de | primart | 9 | | + + When I route I should get + | from | to | route | time | + | a | b | ab | 10s | + | b | a | ab | 10s | + | b | c | bc | 20s | + | c | b | bc | 40s | + | c | d | cd | 10s | + | d | c | cd | 20s | + | d | e | de | 20s | + | e | d | de | 10s | From 46d1a87b89db7300ffe3ff5de9e8b84e91d71fc5 Mon Sep 17 00:00:00 2001 From: Emil Tin Date: Fri, 18 Jan 2013 22:11:22 +0100 Subject: [PATCH 10/12] fix tag on @opposite test --- features/testbot/opposite.feature | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/features/testbot/opposite.feature b/features/testbot/opposite.feature index 9b5df779d..bcc4567d3 100644 --- a/features/testbot/opposite.feature +++ b/features/testbot/opposite.feature @@ -4,8 +4,7 @@ Feature: Separate settings for forward/backward direction Background: Given the profile "testbot" - @smallest - Scenario: Going against the flow + Scenario: Testbot - Going against the flow Given the node map | a | b | c | d | @@ -16,4 +15,4 @@ Feature: Separate settings for forward/backward direction When I route I should get | from | to | route | distance | time | | a | d | abcd | 300 +- 1m | 30s | - | d | a | abcd | 300 +- 1m | 55s | + | d | a | abcd | 300 +- 1m | 55s | \ No newline at end of file From 384be58230fb36d8fbbbec519dd2b7582cdb8d05 Mon Sep 17 00:00:00 2001 From: Emil Tin Date: Sat, 19 Jan 2013 13:04:58 +0100 Subject: [PATCH 11/12] test maxspeed forward/backward --- features/car/maxspeed.feature | 31 ++------------ features/testbot/maxspeed.feature | 70 +++++++++++++++++++++++++++++++ features/testbot/opposite.feature | 2 +- profiles/testbot.lua | 41 +++++++++++++++--- 4 files changed, 110 insertions(+), 34 deletions(-) create mode 100644 features/testbot/maxspeed.feature diff --git a/features/car/maxspeed.feature b/features/car/maxspeed.feature index abdb72a9e..8e40e95bf 100644 --- a/features/car/maxspeed.feature +++ b/features/car/maxspeed.feature @@ -10,9 +10,9 @@ Feature: Car - Max speed restrictions | a | b | c | And the ways - | nodes | highway | maxspeed | - | ab | trunk | | - | bc | trunk | 10 | + | nodes | highway | maxspeed | + | ab | trunk | | + | bc | trunk | 10 | When I route I should get | from | to | route | time | @@ -31,27 +31,4 @@ Feature: Car - Max speed restrictions When I route I should get | from | to | route | time | | a | b | ab | 144s ~10% | - | b | c | bc | 144s ~10% | - - @oppposite @todo - Scenario: Car - Forward/backward maxspeed - Given the node map - | a | b | c | d | e | - - And the ways - | nodes | highway | maxspeed:forward | maxspeed:backward | - | ab | primary | | | - | bc | primart | 18 | 9 | - | cd | primart | | 9 | - | de | primart | 9 | | - - When I route I should get - | from | to | route | time | - | a | b | ab | 10s | - | b | a | ab | 10s | - | b | c | bc | 20s | - | c | b | bc | 40s | - | c | d | cd | 10s | - | d | c | cd | 20s | - | d | e | de | 20s | - | e | d | de | 10s | + | b | c | bc | 144s ~10% | diff --git a/features/testbot/maxspeed.feature b/features/testbot/maxspeed.feature new file mode 100644 index 000000000..4f454be70 --- /dev/null +++ b/features/testbot/maxspeed.feature @@ -0,0 +1,70 @@ +@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 | 20s +-1 | + | b | c | bc | 20s +-1 | + + @opposite + Scenario: Testbot - Forward/backward maxspeed + Given the node map + | a | b | c | d | e | f | g | h | + + And the ways + | nodes | maxspeed | maxspeed:forward | maxspeed:backward | + | ab | | | | + | bc | 18 | | | + | cd | | 18 | | + | de | | | 18 | + | ef | 9 | 18 | | + | fg | 9 | | 18 | + | gh | 9 | 24 | 18 | + + When I route I should get + | from | to | route | time | + | a | b | ab | 10s +-1 | + | b | a | ab | 10s +-1 | + | b | c | bc | 20s +-1 | + | c | b | bc | 20s +-1 | + | c | d | cd | 20s +-1 | + | d | c | cd | 10s +-1 | + | d | e | de | 10s +-1 | + | e | d | de | 20s +-1 | + | e | f | ef | 20s +-1 | + | f | e | ef | 10s +-1 | + | f | g | fg | 10s +-1 | + | g | f | fg | 20s +-1 | + | g | h | gh | 15s +-1 | + | h | g | gh | 10s +-1 | diff --git a/features/testbot/opposite.feature b/features/testbot/opposite.feature index bcc4567d3..fb73c6649 100644 --- a/features/testbot/opposite.feature +++ b/features/testbot/opposite.feature @@ -1,4 +1,4 @@ -@routing @opposite +@routing @testbot @opposite Feature: Separate settings for forward/backward direction Background: diff --git a/profiles/testbot.lua b/profiles/testbot.lua index 341cb6d23..2c13a4e5b 100644 --- a/profiles/testbot.lua +++ b/profiles/testbot.lua @@ -23,6 +23,18 @@ ignore_areas = true -- future feature traffic_signal_penalty = 7 -- seconds 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) local traffic_signal = node.tags:Find("highway") @@ -45,6 +57,15 @@ function way_function (way, numberOfNodesInWay) local oneway = way.tags:Find("oneway") local route = way.tags:Find("route") 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")) + + print('---') + print(name) + print(tostring(maxspeed)) + print(tostring(maxspeed_forward)) + print(tostring(maxspeed_backward)) way.name = name @@ -54,12 +75,20 @@ function way_function (way, numberOfNodesInWay) way.is_duration_set = true else way.speed = speed_profile[highway] or speed_profile['default'] - end - - if(highway == "river") then - local temp_speed = way.speed; - way.speed = temp_speed*3/2 - way.backward_speed = temp_speed*2/3 + + if highway == "river" then + local temp_speed = way.speed; + way.speed = temp_speed*3/2 + way.backward_speed = temp_speed*2/3 + else + way.backward_speed = way.speed + end + + way.speed = limit_speed( way.speed, {maxspeed_forward, maxspeed} ) + way.backward_speed = limit_speed( way.backward_speed, {maxspeed_backward, maxspeed} ) + + -- print( 'limit forw: ' .. tostring(way.speed)) + -- print( 'limit back: ' .. tostring(way.backward_speed)) end if oneway == "no" or oneway == "0" or oneway == "false" then From 43bb53e7891f632358d4db595424f9f6fceabde7 Mon Sep 17 00:00:00 2001 From: Emil Tin Date: Sat, 19 Jan 2013 16:00:36 +0100 Subject: [PATCH 12/12] better testbot maxspeed handling, fix test --- features/testbot/maxspeed.feature | 6 ++++-- profiles/testbot.lua | 22 +++++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/features/testbot/maxspeed.feature b/features/testbot/maxspeed.feature index 4f454be70..1d40233a5 100644 --- a/features/testbot/maxspeed.feature +++ b/features/testbot/maxspeed.feature @@ -34,8 +34,10 @@ Feature: Car - Max speed restrictions When I route I should get | from | to | route | time | - | a | b | ab | 20s +-1 | - | b | c | bc | 20s +-1 | + | 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 diff --git a/profiles/testbot.lua b/profiles/testbot.lua index 2c13a4e5b..82489850a 100644 --- a/profiles/testbot.lua +++ b/profiles/testbot.lua @@ -74,21 +74,25 @@ function way_function (way, numberOfNodesInWay) way.speed = math.max( 1, parseDuration(duration) / math.max(1, numberOfNodesInWay-1) ) way.is_duration_set = true 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 = way.speed; - way.speed = temp_speed*3/2 - way.backward_speed = temp_speed*2/3 - else - way.backward_speed = way.speed + speed_forw = temp_speed*3/2 + speed_back = temp_speed*2/3 end + + speed_forw = limit_speed( speed_forw, {maxspeed_forward, maxspeed} ) + speed_back = limit_speed( speed_back, {maxspeed_backward, maxspeed} ) - way.speed = limit_speed( way.speed, {maxspeed_forward, maxspeed} ) - way.backward_speed = limit_speed( way.backward_speed, {maxspeed_backward, maxspeed} ) + way.speed = speed_forw + if speed_back ~= way_forw then + way.backward_speed = speed_back + end - -- print( 'limit forw: ' .. tostring(way.speed)) - -- print( 'limit back: ' .. tostring(way.backward_speed)) + -- print( 'speed forw: ' .. tostring(way.speed)) + -- print( 'speed back: ' .. tostring(way.backward_speed)) end if oneway == "no" or oneway == "0" or oneway == "false" then