handling of roundabouts (simple version)
This commit is contained in:
parent
bcf7741f95
commit
bc252ea110
@ -24,7 +24,7 @@ namespace guidance
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
// FIXME move implementation to cpp
|
// FIXME move implementation to cpp
|
||||||
inline StepManeuver stepManeuverFromGeometry(const TurnInstruction instruction,
|
inline StepManeuver stepManeuverFromGeometry(TurnInstruction instruction,
|
||||||
const LegGeometry &leg_geometry,
|
const LegGeometry &leg_geometry,
|
||||||
const std::size_t segment_index,
|
const std::size_t segment_index,
|
||||||
const unsigned exit)
|
const unsigned exit)
|
||||||
@ -45,8 +45,10 @@ inline StepManeuver stepManeuverFromGeometry(const TurnInstruction instruction,
|
|||||||
|
|
||||||
return StepManeuver{turn_coordinate, pre_turn_bearing, post_turn_bearing, instruction, exit};
|
return StepManeuver{turn_coordinate, pre_turn_bearing, post_turn_bearing, instruction, exit};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename DataFacadeT>
|
template <typename DataFacadeT>
|
||||||
std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||||
const std::vector<PathData> &leg_data,
|
const std::vector<PathData> &leg_data,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_
|
#ifndef OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_
|
||||||
#define OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_
|
#define OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_
|
||||||
|
|
||||||
|
#include "util/bearing.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
|
|
||||||
@ -42,8 +43,7 @@ getCoordinateFromCompressedRange(util::Coordinate current_coordinate,
|
|||||||
const util::Coordinate final_coordinate,
|
const util::Coordinate final_coordinate,
|
||||||
const std::vector<extractor::QueryNode> &query_nodes)
|
const std::vector<extractor::QueryNode> &query_nodes)
|
||||||
{
|
{
|
||||||
const auto extractCoordinateFromNode = [](
|
const auto extractCoordinateFromNode = [](const extractor::QueryNode &node) -> util::Coordinate
|
||||||
const extractor::QueryNode &node) -> util::Coordinate
|
|
||||||
{
|
{
|
||||||
return {node.lon, node.lat};
|
return {node.lon, node.lat};
|
||||||
};
|
};
|
||||||
@ -105,8 +105,7 @@ getRepresentativeCoordinate(const NodeID from_node,
|
|||||||
const extractor::CompressedEdgeContainer &compressed_geometries,
|
const extractor::CompressedEdgeContainer &compressed_geometries,
|
||||||
const std::vector<extractor::QueryNode> &query_nodes)
|
const std::vector<extractor::QueryNode> &query_nodes)
|
||||||
{
|
{
|
||||||
const auto extractCoordinateFromNode = [](
|
const auto extractCoordinateFromNode = [](const extractor::QueryNode &node) -> util::Coordinate
|
||||||
const extractor::QueryNode &node) -> util::Coordinate
|
|
||||||
{
|
{
|
||||||
return {node.lon, node.lat};
|
return {node.lon, node.lat};
|
||||||
};
|
};
|
||||||
@ -170,7 +169,9 @@ inline DirectionModifier shiftCW(const DirectionModifier modifier)
|
|||||||
inline bool entersRoundabout(const TurnInstruction instruction)
|
inline bool entersRoundabout(const TurnInstruction instruction)
|
||||||
{
|
{
|
||||||
return (instruction.type == TurnType::EnterRoundabout ||
|
return (instruction.type == TurnType::EnterRoundabout ||
|
||||||
instruction.type == TurnType::EnterRotary);
|
instruction.type == TurnType::EnterRotary ||
|
||||||
|
instruction.type == TurnType::EnterRoundaboutAtExit ||
|
||||||
|
instruction.type == TurnType::EnterRotaryAtExit);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool leavesRoundabout(const TurnInstruction instruction)
|
inline bool leavesRoundabout(const TurnInstruction instruction)
|
||||||
@ -381,6 +382,11 @@ inline DirectionModifier bearingToDirectionModifier(const std::string &bearing)
|
|||||||
return hash.find(bearing)->second;
|
return hash.find(bearing)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline DirectionModifier bearingToDirectionModifier(const double angle)
|
||||||
|
{
|
||||||
|
return bearingToDirectionModifier( util::bearing::get(angle) );
|
||||||
|
}
|
||||||
|
|
||||||
inline bool isHighway(FunctionalRoadClass road_class)
|
inline bool isHighway(FunctionalRoadClass road_class)
|
||||||
{
|
{
|
||||||
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
|
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
|
||||||
|
@ -49,46 +49,85 @@ PathData mergeInto(PathData destination, const PathData &source)
|
|||||||
if (source.turn_instruction == TurnType::Suppressed &&
|
if (source.turn_instruction == TurnType::Suppressed &&
|
||||||
detail::canMergeTrivially(destination, source))
|
detail::canMergeTrivially(destination, source))
|
||||||
{
|
{
|
||||||
return detail::accumulateInto(destination, source);
|
return detail::forwardInto(destination, source);
|
||||||
}
|
}
|
||||||
if (source.turn_instruction.type == TurnType::StayOnRoundabout)
|
if (source.turn_instruction.type == TurnType::StayOnRoundabout)
|
||||||
{
|
{
|
||||||
return detail::accumulateInto(destination, source);
|
return detail::forwardInto(destination, source);
|
||||||
|
}
|
||||||
|
if (entersRoundabout(source.turn_instruction))
|
||||||
|
{
|
||||||
|
return detail::forwardInto(destination, source);
|
||||||
}
|
}
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
void print( const std::vector<std::vector<PathData>> & leg_data )
|
void print(const std::vector<std::vector<PathData>> &leg_data)
|
||||||
{
|
{
|
||||||
std::cout << "Path\n";
|
std::cout << "Path\n";
|
||||||
int legnr = 0;
|
int legnr = 0;
|
||||||
for( const auto & leg : leg_data )
|
for (const auto &leg : leg_data)
|
||||||
{
|
{
|
||||||
std::cout << "\tLeg: " << ++legnr << "\n";
|
std::cout << "\tLeg: " << ++legnr << "\n";
|
||||||
int segment = 0;
|
int segment = 0;
|
||||||
for( const auto &data : leg ){
|
for (const auto &data : leg)
|
||||||
std::cout << "\t\t[" << ++segment << "]: " << (int) data.turn_instruction.type << " " << (int)data.turn_instruction.direction_modifier << " exit: " << data.exit << "\n";
|
{
|
||||||
|
std::cout << "\t\t[" << ++segment << "]: " << (int)data.turn_instruction.type << " "
|
||||||
|
<< (int)data.turn_instruction.direction_modifier << " exit: " << data.exit
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
std::cout << std::endl;
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>> leg_data)
|
std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>> leg_data)
|
||||||
{
|
{
|
||||||
std::cout << "[POSTPROCESSING ITERATION]" << std::endl;
|
if( leg_data.empty() )
|
||||||
|
return leg_data;
|
||||||
|
|
||||||
|
#define PRINT_DEBUG 0
|
||||||
unsigned carry_exit = 0;
|
unsigned carry_exit = 0;
|
||||||
|
#if PRINT_DEBUG
|
||||||
|
std::cout << "[POSTPROCESSING ITERATION]" << std::endl;
|
||||||
|
std::cout << "Input\n";
|
||||||
|
print(leg_data);
|
||||||
|
#endif
|
||||||
// Count Street Exits forward
|
// Count Street Exits forward
|
||||||
print( leg_data );
|
bool on_roundabout = false;
|
||||||
for (auto &path_data : leg_data)
|
for (auto &path_data : leg_data)
|
||||||
{
|
{
|
||||||
path_data[0].exit = carry_exit;
|
path_data[0].exit = carry_exit;
|
||||||
for (std::size_t data_index = 0; data_index + 1 < path_data.size(); ++data_index)
|
for (std::size_t data_index = 0; data_index + 1 < path_data.size(); ++data_index)
|
||||||
{
|
{
|
||||||
|
if (entersRoundabout(path_data[data_index].turn_instruction) )
|
||||||
|
{
|
||||||
|
path_data[data_index].exit += 1;
|
||||||
|
on_roundabout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSilent(path_data[data_index].turn_instruction) &&
|
||||||
|
path_data[data_index].turn_instruction != TurnInstruction::NO_TURN())
|
||||||
|
{
|
||||||
|
path_data[data_index].exit += 1;
|
||||||
|
}
|
||||||
|
if (leavesRoundabout(path_data[data_index].turn_instruction))
|
||||||
|
{
|
||||||
|
if (!on_roundabout)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(leg_data[0][0].turn_instruction.type == TurnType::NO_TURN() );
|
||||||
|
if (path_data[data_index].turn_instruction.type == ExitRoundabout)
|
||||||
|
leg_data[0][0].turn_instruction.type = TurnType::EnterRoundabout;
|
||||||
|
if (path_data[data_index].turn_instruction.type == ExitRotary)
|
||||||
|
leg_data[0][0].turn_instruction.type = TurnType::EnterRotary;
|
||||||
|
path_data[data_index].exit += 1;
|
||||||
|
}
|
||||||
|
on_roundabout = false;
|
||||||
|
}
|
||||||
if (path_data[data_index].turn_instruction.type == TurnType::EnterRoundaboutAtExit)
|
if (path_data[data_index].turn_instruction.type == TurnType::EnterRoundaboutAtExit)
|
||||||
{
|
{
|
||||||
path_data[data_index].exit += 1; // Count the exit
|
path_data[data_index].exit += 1;
|
||||||
path_data[data_index].turn_instruction.type = TurnType::EnterRoundabout;
|
path_data[data_index].turn_instruction.type = TurnType::EnterRoundabout;
|
||||||
}
|
}
|
||||||
else if (path_data[data_index].turn_instruction.type == TurnType::EnterRotaryAtExit)
|
else if (path_data[data_index].turn_instruction.type == TurnType::EnterRotaryAtExit)
|
||||||
@ -97,7 +136,8 @@ std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>
|
|||||||
path_data[data_index].turn_instruction.type = TurnType::EnterRotary;
|
path_data[data_index].turn_instruction.type = TurnType::EnterRotary;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSilent(path_data[data_index].turn_instruction))
|
if (isSilent(path_data[data_index].turn_instruction) ||
|
||||||
|
entersRoundabout(path_data[data_index].turn_instruction))
|
||||||
{
|
{
|
||||||
path_data[data_index + 1] =
|
path_data[data_index + 1] =
|
||||||
detail::mergeInto(path_data[data_index + 1], path_data[data_index]);
|
detail::mergeInto(path_data[data_index + 1], path_data[data_index]);
|
||||||
@ -105,43 +145,58 @@ std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>
|
|||||||
carry_exit = path_data[data_index].exit;
|
carry_exit = path_data[data_index].exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if PRINT_DEBUG
|
||||||
print( leg_data );
|
std::cout << "Merged\n";
|
||||||
|
print(leg_data);
|
||||||
|
#endif
|
||||||
|
on_roundabout = false;
|
||||||
// Move Roundabout exit numbers to front
|
// Move Roundabout exit numbers to front
|
||||||
for (auto rev_itr = leg_data.rbegin(); rev_itr != leg_data.rend(); ++rev_itr)
|
for (auto rev_itr = leg_data.rbegin(); rev_itr != leg_data.rend(); ++rev_itr)
|
||||||
{
|
{
|
||||||
auto &path_data = *rev_itr;
|
auto &path_data = *rev_itr;
|
||||||
for (std::size_t data_index = path_data.size(); data_index > 1; --data_index)
|
for (std::size_t data_index = path_data.size(); data_index > 1; --data_index)
|
||||||
{
|
{
|
||||||
if (leavesRoundabout(path_data[data_index - 1].turn_instruction) ||
|
if (entersRoundabout(path_data[data_index - 1].turn_instruction))
|
||||||
staysOnRoundabout(path_data[data_index - 1].turn_instruction))
|
{
|
||||||
|
if( !on_roundabout )
|
||||||
|
path_data[data_index-1].exit = 0;
|
||||||
|
on_roundabout = false;
|
||||||
|
}
|
||||||
|
if (on_roundabout)
|
||||||
{
|
{
|
||||||
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
|
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
|
||||||
}
|
}
|
||||||
|
if (leavesRoundabout(path_data[data_index - 1].turn_instruction))
|
||||||
|
{
|
||||||
|
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
|
||||||
|
on_roundabout = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto prev_leg = std::next(rev_itr);
|
auto prev_leg = std::next(rev_itr);
|
||||||
if (!path_data.empty() && prev_leg != leg_data.rend())
|
if (!path_data.empty() && prev_leg != leg_data.rend())
|
||||||
{
|
{
|
||||||
if (staysOnRoundabout(path_data[0].turn_instruction) ||
|
if (on_roundabout && path_data[0].exit)
|
||||||
leavesRoundabout(path_data[0].turn_instruction))
|
|
||||||
{
|
|
||||||
prev_leg->back().exit = path_data[0].exit;
|
prev_leg->back().exit = path_data[0].exit;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print( leg_data );
|
#if PRINT_DEBUG
|
||||||
// silence turns for good
|
std::cout << "Move To Front\n";
|
||||||
|
print(leg_data);
|
||||||
|
#endif
|
||||||
|
// silence silent turns for good
|
||||||
for (auto &path_data : leg_data)
|
for (auto &path_data : leg_data)
|
||||||
{
|
{
|
||||||
for (auto &data : path_data)
|
for (auto &data : path_data)
|
||||||
{
|
{
|
||||||
if (isSilent(data.turn_instruction) || leavesRoundabout(data.turn_instruction))
|
if (isSilent(data.turn_instruction) || leavesRoundabout(data.turn_instruction))
|
||||||
|
{
|
||||||
data.turn_instruction = TurnInstruction::NO_TURN();
|
data.turn_instruction = TurnInstruction::NO_TURN();
|
||||||
|
data.exit = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print( leg_data );
|
|
||||||
return std::move(leg_data);
|
return std::move(leg_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user