diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index a6e9d0a46..f5c2fcc48 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -103,6 +103,7 @@ void EdgeBasedGraphFactory::Run() { Percent p(_nodeBasedGraph->GetNumberOfNodes()); int numberOfResolvedRestrictions(0); int nodeBasedEdgeCounter(0); + //Loop over all nodes u. Three nested loop look super-linear, but we are dealing with a number linear in the turns only. for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { //loop over all adjacent edge (u,v) @@ -189,24 +190,30 @@ short EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const N double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]); - if(data1.middleName.nameID == data2.middleName.nameID) - return TurnInstructions.NoTurn; - - //Is turn on roundabout? + //roundabouts need to be handled explicitely + if(data1.roundabout && data2.roundabout) { + //Is a turn possible? If yes, we stay on the roundabout! + if( 1 == (_nodeBasedGraph->EndEdges(v) - _nodeBasedGraph->BeginEdges(v)) ) { + //No turn possible. + return TurnInstructions.NoTurn; + } else { + return TurnInstructions.StayOnRoundAbout; + } + } + //Does turn start or end on roundabout? if(data1.roundabout || data2.roundabout) { //We are entering the roundabout - if(!data1.roundabout && data2.roundabout) + if( (!data1.roundabout) && data2.roundabout) return TurnInstructions.EnterRoundAbout; //We are leaving the roundabout - if(data1.roundabout && !data2.roundabout) + if(data1.roundabout && (!data2.roundabout) ) return TurnInstructions.LeaveRoundAbout; - //Is a turn possible? If yes, we stay on the roundabout! - if(_nodeBasedGraph->EndEdges(v) - _nodeBasedGraph->BeginEdges(v) > 1) - return TurnInstructions.StayOnRoundAbout; - //No turn possible. - return TurnInstructions.NoTurn; } + //If street names stay the same and if we are certain that it is not a roundabout, we skip it. + if(data1.middleName.nameID == data2.middleName.nameID) + return TurnInstructions.NoTurn; + return TurnInstructions.GetTurnDirectionOfInstruction(angle); } diff --git a/DataStructures/ExtractorCallBacks.h b/DataStructures/ExtractorCallBacks.h index e2e31d301..c4b857663 100644 --- a/DataStructures/ExtractorCallBacks.h +++ b/DataStructures/ExtractorCallBacks.h @@ -112,6 +112,10 @@ public: if ( 0 < name.length() ) w.name = name; + if(junction == "roundabout") { + w.roundabout = true; + } + //Is the highway tag listed as usable way? if(0 < settings[highway]) { @@ -134,9 +138,6 @@ public: else if("no" == accessClass) w.access = false; - if(junction == "roundabout") { - w.roundabout = true; - } //Let's process oneway property, if speed profile obeys to it if(oneway != "no" && oneway != "false" && oneway != "0" && settings.obeyOneways) { //if oneway tag is in forward direction or if actually roundabout @@ -157,7 +158,7 @@ public: } } if ( w.useful && w.access && (1 < w.path.size()) ) { //Only true if the way is specified by the speed profile - //Hack: type is not set, perhaps use a bimap'ed speed profile to do set the type correctly? + //TODO: type is not set, perhaps use a bimap'ed speed profile to do set the type correctly? w.type = 1; //Get the unique identifier for the street name diff --git a/DataStructures/TurnInstructions.h b/DataStructures/TurnInstructions.h index 5a6b86412..c421fc0b8 100644 --- a/DataStructures/TurnInstructions.h +++ b/DataStructures/TurnInstructions.h @@ -42,6 +42,7 @@ struct TurnInstructionsClass { const static short StayOnRoundAbout = 13; std::string TurnStrings[14]; + std::string Ordinals[11]; //This is a hack until c++0x is available enough to use initializer lists. TurnInstructionsClass(){ @@ -59,6 +60,18 @@ struct TurnInstructionsClass { TurnStrings[11] = "Enter round-about"; TurnStrings[12] = "Leave round-about"; TurnStrings[13] = "Stay on round-about"; + + 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"; }; static inline double GetTurnDirectionOfInstruction( const double angle ) { diff --git a/Descriptors/JSONDescriptor.h b/Descriptors/JSONDescriptor.h index d349ac873..2f6795ac9 100644 --- a/Descriptors/JSONDescriptor.h +++ b/Descriptors/JSONDescriptor.h @@ -105,16 +105,14 @@ public: if(0 != prefixSumOfNecessarySegments) reply.content += ","; reply.content += "[\""; - INFO("INstruction: " << segment.turnInstruction); - if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction){ - INFO("Staying on roundabout"); - ++leaveAtExit; - } + INFO("Instruction: " << segment.turnInstruction); + reply.content += TurnInstructions.TurnStrings[segment.turnInstruction]; if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) { - INFO("Exiting at exit " << leaveAtExit); + reply.content += " at "; + reply.content += TurnInstructions.Ordinals[leaveAtExit+1]; + reply.content += " exit"; leaveAtExit = 0; } - reply.content += TurnInstructions.TurnStrings[segment.turnInstruction]; reply.content += "\",\""; reply.content += sEngine.GetEscapedNameForNameID(segment.nameID); reply.content += "\","; @@ -130,6 +128,8 @@ public: //TODO: fix heading reply.content += "\",\"NE\",22.5"; reply.content += "]"; + } else if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction) { + ++leaveAtExit; } if(segment.necessary) ++prefixSumOfNecessarySegments;