Skip to content

Commit

Permalink
fixup! todo
Browse files Browse the repository at this point in the history
  • Loading branch information
Karry committed Jun 3, 2024
1 parent 1497b60 commit 445a0c1
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 34 deletions.
6 changes: 5 additions & 1 deletion libosmscout/include/osmscout/routing/RoutePostprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,9 @@ namespace osmscout {
* @param node
* @param backBuffer buffer of traveled nodes, recent node at back
*/
void EvaluateLaneSuggestion(const RouteDescription::Node &node, const std::list<RouteDescription::Node*> &backBuffer) const;
void EvaluateLaneSuggestion(const RoutePostprocessor& postprocessor,
const RouteDescription::Node &node,
const std::list<RouteDescription::Node*> &backBuffer) const;

private:
Distance distanceBefore;
Expand Down Expand Up @@ -466,6 +468,8 @@ namespace osmscout {

uint8_t GetMaxSpeed(const RouteDescription::Node& node) const;

RouteDescription::LaneDescription GetLanes(const DatabaseId& dbId, const WayRef& way, bool forward) const;

RouteDescription::LaneDescriptionRef GetLanes(const RouteDescription::Node& node) const;

Id GetNodeId(const RouteDescription::Node& node) const;
Expand Down
20 changes: 20 additions & 0 deletions libosmscout/include/osmscout/util/Bearing.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,26 @@ namespace osmscout {
return radians != o.radians;
}

bool operator<(const Bearing& o) const
{
return radians<o.radians;
}

bool operator>(const Bearing& o) const
{
return radians>o.radians;
}

bool operator<=(const Bearing& o) const
{
return radians<=o.radians;
}

bool operator>=(const Bearing& o) const
{
return radians>=o.radians;
}

inline static Bearing Radians(double radians)
{
return Bearing(radians);
Expand Down
143 changes: 110 additions & 33 deletions libosmscout/src/osmscout/routing/RoutePostprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1591,18 +1591,89 @@ namespace osmscout {
return true;
}

void RoutePostprocessor::SuggestedLanesPostprocessor::EvaluateLaneSuggestion(const RouteDescription::Node &node, const std::list<RouteDescription::Node*> &backBuffer) const
void RoutePostprocessor::SuggestedLanesPostprocessor::EvaluateLaneSuggestion(const RoutePostprocessor& postprocessor,
const RouteDescription::Node &node,
const std::list<RouteDescription::Node*> &backBuffer) const
{
if (node.GetPathObject().GetType()!=refWay) {
return; // areas not considered now
}

assert(!backBuffer.empty());
const RouteDescription::Node &prevNode=*backBuffer.back();
DatabaseId dbId = node.GetDatabaseId();
if (prevNode.GetDatabaseId() != dbId) {
return; // we consider nodes just from the same database for simplicity
}

assert(dbId<postprocessor.profiles.size() && postprocessor.profiles[dbId]);
auto profile=postprocessor.profiles[dbId];

auto lanes = GetLaneDescription(node);
assert(lanes);
auto prevLanes = GetLaneDescription(*backBuffer.back());
auto prevLanes = GetLaneDescription(prevNode);
assert(prevLanes);

if (node.GetPathObject().GetType()!=refWay) {
return;
// TODO: read lanes on the ALL junction ways, use heuristics what lanes we can use to move forward
Id nodeId = postprocessor.GetNodeId(node);

WayRef prevWay = postprocessor.GetWay(prevNode.GetDBFileOffset());
Id prevNodeId = prevWay->GetId(prevNode.GetCurrentNodeIndex());
// bearing from current node to previous
Bearing prevNodeBearing = GetSphericalBearingInitial(prevWay->nodes[prevNode.GetTargetNodeIndex()].GetCoord(),
prevWay->nodes[prevNode.GetCurrentNodeIndex()].GetCoord());

WayRef way = postprocessor.GetWay(node.GetDBFileOffset());
Id nextNodeId = way->GetId(node.GetTargetNodeIndex());
Bearing nextNodeBearing = GetSphericalBearingInitial(way->nodes[node.GetCurrentNodeIndex()].GetCoord(),
way->nodes[node.GetTargetNodeIndex()].GetCoord());

struct JunctionExit {
Id nextId;
Bearing bearing;
RouteDescription::LaneDescription lanes;
};
std::vector<JunctionExit> junctionExits; // excluding incoming and outgoing way
junctionExits.reserve(node.GetObjects().size());

for (const auto &o: node.GetObjects()){
if (!o.IsWay()) {
continue; // areas not considered now
}

way=postprocessor.GetWay(DBFileOffset(node.GetDatabaseId(), o.GetFileOffset()));
for (size_t i = 0; i < way->nodes.size(); i++) {
if (way->nodes[i].GetId() == nodeId) {
if (i < way->nodes.size()-1 && profile->CanUseForward(*way)) {
Id junctionNodeId = way->nodes[i+1].GetId();
if (junctionNodeId!=prevNodeId && junctionNodeId!=nextNodeId) {
auto bearing = GetSphericalBearingInitial(way->nodes[i].GetCoord(), way->nodes[i + 1].GetCoord());
auto wayLanes = postprocessor.GetLanes(node.GetDatabaseId(), way, true);
junctionExits.push_back({junctionNodeId, bearing, wayLanes});
}
}
if (i > 0 && profile->CanUseBackward(*way)) {
Id junctionNodeId = way->nodes[i-1].GetId();
if (junctionNodeId!=prevNodeId && junctionNodeId!=nextNodeId) {
auto bearing = GetSphericalBearingInitial(way->nodes[i].GetCoord(), way->nodes[i - 1].GetCoord());
auto wayLanes = postprocessor.GetLanes(node.GetDatabaseId(), way, false);
junctionExits.push_back({junctionNodeId, bearing, wayLanes});
}
}
break;
}
}
}

// TODO: read lanes on the ALL junction ways, use heuristics what lanes we can use to move forward
// sort by bearing
std::sort(junctionExits.begin(), junctionExits.end(), [](const JunctionExit &j1, const JunctionExit &j2) -> bool {
return j1.bearing < j2.bearing;
});







RouteDescription::DirectionDescriptionRef direction = std::dynamic_pointer_cast<RouteDescription::DirectionDescription>(node.GetDescription(RouteDescription::DIRECTION_DESC));
Expand Down Expand Up @@ -1720,7 +1791,7 @@ namespace osmscout {
return std::dynamic_pointer_cast<RouteDescription::LaneDescription>(node.GetDescription(RouteDescription::LANES_DESC));
}

bool RoutePostprocessor::SuggestedLanesPostprocessor::Process(const RoutePostprocessor& /*postprocessor*/,
bool RoutePostprocessor::SuggestedLanesPostprocessor::Process(const RoutePostprocessor& postprocessor,
RouteDescription& description)
{
using namespace std::string_view_literals;
Expand All @@ -1745,7 +1816,7 @@ namespace osmscout {
assert(prevLanes);
if (prevLanes->GetLaneCount() > lanes->GetLaneCount()) { // lane count was decreased

EvaluateLaneSuggestion(node, backBuffer);
EvaluateLaneSuggestion(postprocessor, node, backBuffer);

backBuffer.clear();
}
Expand Down Expand Up @@ -2144,40 +2215,46 @@ namespace osmscout {
return speed;
}

RouteDescription::LaneDescription RoutePostprocessor::GetLanes(const DatabaseId& dbId, const WayRef& way, bool forward) const
{
auto lanesReader=lanesReaders.find(dbId);
auto accessReader=accessReaders.find(dbId);
assert(lanesReader != lanesReaders.end());
assert(accessReader != accessReaders.end());

AccessFeatureValue *accessValue=accessReader->second->GetValue(way->GetFeatureValueBuffer());
bool oneway=accessValue!=nullptr && accessValue->IsOneway();

uint8_t laneCount;
std::vector<LaneTurn> laneTurns;
LanesFeatureValue *lanesValue=lanesReader->second->GetValue(way->GetFeatureValueBuffer());
if (lanesValue!=nullptr) {
laneCount=std::max((uint8_t)1,forward ? lanesValue->GetForwardLanes() : lanesValue->GetBackwardLanes());
laneTurns=forward ? lanesValue->GetTurnForward() : lanesValue->GetTurnBackward();
while (laneTurns.size() < laneCount) {
laneTurns.push_back(LaneTurn::None);
}
} else {
// default lane count by object type
if (oneway) {
laneCount=way->GetType()->GetOnewayLanes();
} else {
laneCount=std::max(1,way->GetType()->GetLanes()/2);
}
}

return RouteDescription::LaneDescription(oneway, laneCount, laneTurns);
}

RouteDescription::LaneDescriptionRef RoutePostprocessor::GetLanes(const RouteDescription::Node& node) const
{
RouteDescription::LaneDescriptionRef lanes;
if (node.GetPathObject().GetType()==refWay) {
auto lanesReader=lanesReaders.find(node.GetDatabaseId());
auto accessReader=accessReaders.find(node.GetDatabaseId());
assert(lanesReader != lanesReaders.end());
assert(accessReader != accessReaders.end());

WayRef way=GetWay(node.GetDBFileOffset());

bool forward = node.GetCurrentNodeIndex() < node.GetTargetNodeIndex();

AccessFeatureValue *accessValue=accessReader->second->GetValue(way->GetFeatureValueBuffer());
bool oneway=accessValue!=nullptr && accessValue->IsOneway();

uint8_t laneCount;
std::vector<LaneTurn> laneTurns;
LanesFeatureValue *lanesValue=lanesReader->second->GetValue(way->GetFeatureValueBuffer());
if (lanesValue!=nullptr) {
laneCount=std::max((uint8_t)1,forward ? lanesValue->GetForwardLanes() : lanesValue->GetBackwardLanes());
laneTurns=forward ? lanesValue->GetTurnForward() : lanesValue->GetTurnBackward();
while (laneTurns.size() < laneCount) {
laneTurns.push_back(LaneTurn::None);
}
} else {
// default lane count by object type
if (oneway) {
laneCount=way->GetType()->GetOnewayLanes();
} else {
laneCount=std::max(1,way->GetType()->GetLanes()/2);
}
}
lanes=std::make_shared<RouteDescription::LaneDescription>(oneway, laneCount, laneTurns);
lanes=std::make_shared<RouteDescription::LaneDescription>(GetLanes(node.GetDatabaseId(), way, forward));
}
return lanes;
}
Expand Down

0 comments on commit 445a0c1

Please sign in to comment.