Skip to content

Commit

Permalink
Merge pull request #1609 from Karry/lane-suggestions-improvements
Browse files Browse the repository at this point in the history
suggest route lanes even when its count is not changing
  • Loading branch information
Framstag authored Sep 30, 2024
2 parents af2408d + af66af3 commit e77b2e4
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 40 deletions.
68 changes: 42 additions & 26 deletions Tests/src/RoutePostprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <filesystem>

#include <osmscout/routing/RoutePostprocessor.h>
#include <osmscout/log/Logger.h>

#include <TestMain.h>

Expand Down Expand Up @@ -327,7 +328,7 @@ class MockContext: public osmscout::PostprocessorContext
assert(false);
}

if (fromNodeIndex>0) {
if (fromNodeIndex==0) {
return false;
}

Expand Down Expand Up @@ -463,6 +464,7 @@ TEST_CASE("Suggest lanes on simple junction")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 1);
REQUIRE(suggestedLanes->GetTo() == 1);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Unknown);
}

{
Expand All @@ -483,6 +485,7 @@ TEST_CASE("Suggest lanes on simple junction")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 0);
REQUIRE(suggestedLanes->GetTo() == 0);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Unknown);
}
}

Expand All @@ -491,6 +494,8 @@ TEST_CASE("Suggest lanes on slightly complex junction")
{
using namespace osmscout;

::osmscout::log.Debug(true);

// https://www.openstreetmap.org/#map=19/50.077838/14.511968
MockDatabaseBuilder databaseBuilder;
// street Dřevčická to south https://www.openstreetmap.org/way/1308678203
Expand Down Expand Up @@ -552,28 +557,28 @@ TEST_CASE("Suggest lanes on slightly complex junction")

RouteDescription description;

RoutePostprocessor::LanesPostprocessor lanesPostprocessor;
lanesPostprocessor.Process(context, description);
RoutePostprocessor::LanesPostprocessor lanesPostproc;
lanesPostproc.Process(context, description);

RoutePostprocessor::SuggestedLanesPostprocessor postprocessor;
postprocessor.Process(context, description);
RoutePostprocessor::SuggestedLanesPostprocessor suggestedLanesPostproc;
suggestedLanesPostproc.Process(context, description);

{ // route is going from west to east on Cernokostelecka
description.Clear();
description.AddNode(0, 0, {southCernokostelecka1Ref}, southCernokostelecka1Ref, 1);
description.AddNode(0, 0, {southCernokostelecka1Ref, southCernokostelecka2Ref, drevcicka2Ref}, southCernokostelecka2Ref, 1);
description.AddNode(0, 1, {southCernokostelecka2Ref}, ObjectFileRef(), 0);

lanesPostprocessor.Process(context, description);
postprocessor.Process(context, description);
lanesPostproc.Process(context, description);
suggestedLanesPostproc.Process(context, description);

// TODO: should suggest right lane, through
auto nodeIt = description.Nodes().begin();
auto suggestedLanes = std::dynamic_pointer_cast<RouteDescription::SuggestedLaneDescription>(
nodeIt->GetDescription(RouteDescription::SUGGESTED_LANES_DESC));
// REQUIRE(suggestedLanes);
// REQUIRE(suggestedLanes->GetFrom() == 1);
// REQUIRE(suggestedLanes->GetTo() == 1);
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 1);
REQUIRE(suggestedLanes->GetTo() == 1);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Through);
}

{ // route is going from west on Cernokostelecka to north on Drevcicka
Expand All @@ -583,8 +588,8 @@ TEST_CASE("Suggest lanes on slightly complex junction")
description.AddNode(0, 1, {northCernokostelecka1Ref, drevcicka1Ref, drevcicka2Ref, northCernokostelecka2Ref}, drevcicka1Ref, 0);
description.AddNode(0, 1, {drevcicka1Ref}, ObjectFileRef(), 0);

lanesPostprocessor.Process(context, description);
postprocessor.Process(context, description);
lanesPostproc.Process(context, description);
suggestedLanesPostproc.Process(context, description);

// should suggest left lane, left turn
auto nodeIt = description.Nodes().begin();
Expand All @@ -593,6 +598,7 @@ TEST_CASE("Suggest lanes on slightly complex junction")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 0);
REQUIRE(suggestedLanes->GetTo() == 0);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Left);
}

{ // route is going from the east to west on Cernokostelecka
Expand All @@ -601,14 +607,17 @@ TEST_CASE("Suggest lanes on slightly complex junction")
description.AddNode(0, 0, {northCernokostelecka1Ref, drevcicka1Ref, drevcicka2Ref, northCernokostelecka2Ref}, northCernokostelecka2Ref, 1);
description.AddNode(0, 0, {northCernokostelecka2Ref}, ObjectFileRef(), 0);

lanesPostprocessor.Process(context, description);
postprocessor.Process(context, description);
lanesPostproc.Process(context, description);
suggestedLanesPostproc.Process(context, description);

// both lanes are usable, should provide no suggestion
// both lanes are usable, we don't need suggestion as going through, but let's provide it
auto nodeIt = description.Nodes().begin();
auto suggestedLanes = std::dynamic_pointer_cast<RouteDescription::SuggestedLaneDescription>(
nodeIt->GetDescription(RouteDescription::SUGGESTED_LANES_DESC));
REQUIRE(suggestedLanes==nullptr);
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 0);
REQUIRE(suggestedLanes->GetTo() == 1);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Through);
}

{ // route is going from the east on Cernokostelecka to north on Drevcicka
Expand All @@ -617,8 +626,8 @@ TEST_CASE("Suggest lanes on slightly complex junction")
description.AddNode(0, 1, {northCernokostelecka1Ref, drevcicka1Ref, drevcicka2Ref, northCernokostelecka2Ref}, drevcicka1Ref, 0);
description.AddNode(0, 0, {drevcicka1Ref}, ObjectFileRef(), 0);

lanesPostprocessor.Process(context, description);
postprocessor.Process(context, description);
lanesPostproc.Process(context, description);
suggestedLanesPostproc.Process(context, description);

// should suggest right lane to the right
auto nodeIt = description.Nodes().begin();
Expand All @@ -627,6 +636,7 @@ TEST_CASE("Suggest lanes on slightly complex junction")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 1);
REQUIRE(suggestedLanes->GetTo() == 1);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Right);
}

{ // route is going from the north from Drevcicka to the west on Cernokostelecka
Expand All @@ -635,16 +645,17 @@ TEST_CASE("Suggest lanes on slightly complex junction")
description.AddNode(0, 0, {northCernokostelecka1Ref, drevcicka1Ref, drevcicka2Ref, northCernokostelecka2Ref}, northCernokostelecka2Ref, 1);
description.AddNode(0, 0, {northCernokostelecka2Ref}, ObjectFileRef(), 0);

lanesPostprocessor.Process(context, description);
postprocessor.Process(context, description);
lanesPostproc.Process(context, description);
suggestedLanesPostproc.Process(context, description);

// TODO: should suggest right lane to the right
auto nodeIt = description.Nodes().begin();
auto suggestedLanes = std::dynamic_pointer_cast<RouteDescription::SuggestedLaneDescription>(
nodeIt->GetDescription(RouteDescription::SUGGESTED_LANES_DESC));
// REQUIRE(suggestedLanes);
// REQUIRE(suggestedLanes->GetFrom() == 1);
// REQUIRE(suggestedLanes->GetTo() == 1);
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 1);
REQUIRE(suggestedLanes->GetTo() == 1);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Right);
}

{ // route is going from the north from Drevcicka to the east on Cernokostelecka
Expand All @@ -654,8 +665,8 @@ TEST_CASE("Suggest lanes on slightly complex junction")
description.AddNode(0, 0, {southCernokostelecka1Ref, southCernokostelecka2Ref, drevcicka2Ref}, southCernokostelecka2Ref, 1);
description.AddNode(0, 0, {southCernokostelecka2Ref}, ObjectFileRef(), 0);

lanesPostprocessor.Process(context, description);
postprocessor.Process(context, description);
lanesPostproc.Process(context, description);
suggestedLanesPostproc.Process(context, description);

// should suggest left lane to the left
auto nodeIt = description.Nodes().begin();
Expand All @@ -664,6 +675,7 @@ TEST_CASE("Suggest lanes on slightly complex junction")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 0);
REQUIRE(suggestedLanes->GetTo() == 0);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Left);
}
}

Expand Down Expand Up @@ -728,6 +740,7 @@ TEST_CASE("Suggest lanes on A3/A4 highway split")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 2);
REQUIRE(suggestedLanes->GetTo() == 2);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::SlightRight);
}

{
Expand All @@ -748,6 +761,7 @@ TEST_CASE("Suggest lanes on A3/A4 highway split")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 0);
REQUIRE(suggestedLanes->GetTo() == 1);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Through);
}
}

Expand Down Expand Up @@ -813,6 +827,7 @@ TEST_CASE("Suggest lanes on A3/A4 highway near Zurich")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 0);
REQUIRE(suggestedLanes->GetTo() == 0);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::SlightLeft);
}

{
Expand All @@ -833,6 +848,7 @@ TEST_CASE("Suggest lanes on A3/A4 highway near Zurich")
REQUIRE(suggestedLanes);
REQUIRE(suggestedLanes->GetFrom() == 1);
REQUIRE(suggestedLanes->GetTo() == 2);
REQUIRE(suggestedLanes->GetTurn() == LaneTurn::Through);
}

}
8 changes: 7 additions & 1 deletion libosmscout/include/osmscout/routing/RouteDescription.h
Original file line number Diff line number Diff line change
Expand Up @@ -640,9 +640,10 @@ namespace osmscout {
private:
uint8_t from = uint8_t(-1); //!< left-most suggested lane, inclusive
uint8_t to = uint8_t(-1); //!< right-most suggested lane, inclusive
LaneTurn turn{LaneTurn::None};

public:
SuggestedLaneDescription(uint8_t from, uint8_t to);
SuggestedLaneDescription(uint8_t from, uint8_t to, LaneTurn turn);

std::string GetDebugString() const override;

Expand All @@ -655,6 +656,11 @@ namespace osmscout {
{
return to;
}

LaneTurn GetTurn() const
{
return turn;
}
};

using SuggestedLaneDescriptionRef = std::shared_ptr<SuggestedLaneDescription>;
Expand Down
8 changes: 5 additions & 3 deletions libosmscout/src/osmscout/routing/RouteDescription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,14 +512,16 @@ namespace osmscout {
return !((*this)==o);
}

RouteDescription::SuggestedLaneDescription::SuggestedLaneDescription(uint8_t from, uint8_t to):
from(from), to(to)
RouteDescription::SuggestedLaneDescription::SuggestedLaneDescription(uint8_t from, uint8_t to, LaneTurn turn):
from(from), to(to), turn(turn)
{}

std::string RouteDescription::SuggestedLaneDescription::GetDebugString() const
{
std::stringstream ss;
ss << "Suggested lanes: <";
ss << "Suggested lanes: ";
ss << LaneTurnString(turn);
ss << " <";
ss << (int)from;
ss << ", ";
ss << (int)to;
Expand Down
Loading

0 comments on commit e77b2e4

Please sign in to comment.