Exits of roundabouts get handled

This commit is contained in:
DennisOSRM 2011-11-23 18:40:54 +01:00
parent 885d45e9b8
commit fb1857f7cc
4 changed files with 43 additions and 22 deletions

View File

@ -103,6 +103,7 @@ void EdgeBasedGraphFactory::Run() {
Percent p(_nodeBasedGraph->GetNumberOfNodes()); Percent p(_nodeBasedGraph->GetNumberOfNodes());
int numberOfResolvedRestrictions(0); int numberOfResolvedRestrictions(0);
int nodeBasedEdgeCounter(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. //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 ) { for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
//loop over all adjacent edge (u,v) //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]); double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
if(data1.middleName.nameID == data2.middleName.nameID) //roundabouts need to be handled explicitely
return TurnInstructions.NoTurn; if(data1.roundabout && data2.roundabout) {
//Is a turn possible? If yes, we stay on the roundabout!
//Is turn on 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) { if(data1.roundabout || data2.roundabout) {
//We are entering the roundabout //We are entering the roundabout
if(!data1.roundabout && data2.roundabout) if( (!data1.roundabout) && data2.roundabout)
return TurnInstructions.EnterRoundAbout; return TurnInstructions.EnterRoundAbout;
//We are leaving the roundabout //We are leaving the roundabout
if(data1.roundabout && !data2.roundabout) if(data1.roundabout && (!data2.roundabout) )
return TurnInstructions.LeaveRoundAbout; 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); return TurnInstructions.GetTurnDirectionOfInstruction(angle);
} }

View File

@ -112,6 +112,10 @@ public:
if ( 0 < name.length() ) if ( 0 < name.length() )
w.name = name; w.name = name;
if(junction == "roundabout") {
w.roundabout = true;
}
//Is the highway tag listed as usable way? //Is the highway tag listed as usable way?
if(0 < settings[highway]) { if(0 < settings[highway]) {
@ -134,9 +138,6 @@ public:
else if("no" == accessClass) else if("no" == accessClass)
w.access = false; w.access = false;
if(junction == "roundabout") {
w.roundabout = true;
}
//Let's process oneway property, if speed profile obeys to it //Let's process oneway property, if speed profile obeys to it
if(oneway != "no" && oneway != "false" && oneway != "0" && settings.obeyOneways) { if(oneway != "no" && oneway != "false" && oneway != "0" && settings.obeyOneways) {
//if oneway tag is in forward direction or if actually roundabout //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 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; w.type = 1;
//Get the unique identifier for the street name //Get the unique identifier for the street name

View File

@ -42,6 +42,7 @@ struct TurnInstructionsClass {
const static short StayOnRoundAbout = 13; const static short StayOnRoundAbout = 13;
std::string TurnStrings[14]; std::string TurnStrings[14];
std::string Ordinals[11];
//This is a hack until c++0x is available enough to use initializer lists. //This is a hack until c++0x is available enough to use initializer lists.
TurnInstructionsClass(){ TurnInstructionsClass(){
@ -59,6 +60,18 @@ struct TurnInstructionsClass {
TurnStrings[11] = "Enter round-about"; TurnStrings[11] = "Enter round-about";
TurnStrings[12] = "Leave round-about"; TurnStrings[12] = "Leave round-about";
TurnStrings[13] = "Stay on 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 ) { static inline double GetTurnDirectionOfInstruction( const double angle ) {

View File

@ -105,16 +105,14 @@ public:
if(0 != prefixSumOfNecessarySegments) if(0 != prefixSumOfNecessarySegments)
reply.content += ","; reply.content += ",";
reply.content += "[\""; reply.content += "[\"";
INFO("INstruction: " << segment.turnInstruction); INFO("Instruction: " << segment.turnInstruction);
if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction){ reply.content += TurnInstructions.TurnStrings[segment.turnInstruction];
INFO("Staying on roundabout");
++leaveAtExit;
}
if(TurnInstructions.LeaveRoundAbout == 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; leaveAtExit = 0;
} }
reply.content += TurnInstructions.TurnStrings[segment.turnInstruction];
reply.content += "\",\""; reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID); reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\","; reply.content += "\",";
@ -130,6 +128,8 @@ public:
//TODO: fix heading //TODO: fix heading
reply.content += "\",\"NE\",22.5"; reply.content += "\",\"NE\",22.5";
reply.content += "]"; reply.content += "]";
} else if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction) {
++leaveAtExit;
} }
if(segment.necessary) if(segment.necessary)
++prefixSumOfNecessarySegments; ++prefixSumOfNecessarySegments;