Big Restructuring / Cleanup

This commit is contained in:
Patrick Niklaus 2016-03-01 22:30:31 +01:00
parent ffb3578180
commit 8c71239e48
40 changed files with 419 additions and 511 deletions

View File

@ -55,12 +55,11 @@ configure_file(
${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp ${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp
) )
file(GLOB UtilGlob src/util/*.cpp) file(GLOB UtilGlob src/util/*.cpp)
file(GLOB ExtractorGlob src/extractor/*.cpp src/engine/guidance/classification_data.cpp) file(GLOB ExtractorGlob src/extractor/*.cpp src/extractor/*/*.cpp)
file(GLOB ContractorGlob src/contractor/*.cpp) file(GLOB ContractorGlob src/contractor/*.cpp)
file(GLOB StorageGlob src/storage/*.cpp) file(GLOB StorageGlob src/storage/*.cpp)
file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp) file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp)
file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp) file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp)
file(GLOB GuidanceGlob src/guidance/*.cpp src/guidance/**/*.cpp)
file(GLOB ExtractorTestsGlob unit_tests/extractor/*.cpp) file(GLOB ExtractorTestsGlob unit_tests/extractor/*.cpp)
file(GLOB EngineTestsGlob unit_tests/engine/*.cpp) file(GLOB EngineTestsGlob unit_tests/engine/*.cpp)
file(GLOB UtilTestsGlob unit_tests/util/*.cpp) file(GLOB UtilTestsGlob unit_tests/util/*.cpp)
@ -72,7 +71,6 @@ add_library(EXTRACTOR OBJECT ${ExtractorGlob})
add_library(CONTRACTOR OBJECT ${ContractorGlob}) add_library(CONTRACTOR OBJECT ${ContractorGlob})
add_library(STORAGE OBJECT ${StorageGlob}) add_library(STORAGE OBJECT ${StorageGlob})
add_library(ENGINE OBJECT ${EngineGlob}) add_library(ENGINE OBJECT ${EngineGlob})
add_library(GUIDANCE OBJECT ${GuidanceGlob})
add_library(SERVER OBJECT ${ServerGlob}) add_library(SERVER OBJECT ${ServerGlob})
add_dependencies(UTIL FingerPrintConfigure) add_dependencies(UTIL FingerPrintConfigure)
@ -82,8 +80,8 @@ add_executable(osrm-extract src/tools/extract.cpp)
add_executable(osrm-contract src/tools/contract.cpp) add_executable(osrm-contract src/tools/contract.cpp)
add_executable(osrm-routed src/tools/routed.cpp $<TARGET_OBJECTS:SERVER> $<TARGET_OBJECTS:UTIL>) add_executable(osrm-routed src/tools/routed.cpp $<TARGET_OBJECTS:SERVER> $<TARGET_OBJECTS:UTIL>)
add_executable(osrm-datastore src/tools/store.cpp $<TARGET_OBJECTS:UTIL>) add_executable(osrm-datastore src/tools/store.cpp $<TARGET_OBJECTS:UTIL>)
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:GUIDANCE> $<TARGET_OBJECTS:UTIL>) add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_extract $<TARGET_OBJECTS:EXTRACTOR> $<TARGET_OBJECTS:UTIL> $<TARGET_OBJECTS:GUIDANCE>) add_library(osrm_extract $<TARGET_OBJECTS:EXTRACTOR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_contract $<TARGET_OBJECTS:CONTRACTOR> $<TARGET_OBJECTS:UTIL>) add_library(osrm_contract $<TARGET_OBJECTS:CONTRACTOR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:UTIL>) add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:UTIL>)

View File

@ -1,7 +1,7 @@
#ifndef ENGINE_RESPONSE_OBJECTS_HPP_ #ifndef ENGINE_RESPONSE_OBJECTS_HPP_
#define ENGINE_RESPONSE_OBJECTS_HPP_ #define ENGINE_RESPONSE_OBJECTS_HPP_
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "engine/polyline_compressor.hpp" #include "engine/polyline_compressor.hpp"
#include "engine/guidance/route_step.hpp" #include "engine/guidance/route_step.hpp"
@ -32,8 +32,8 @@ namespace json
namespace detail namespace detail
{ {
std::string instructionTypeToString(guidance::TurnType type); std::string instructionTypeToString(extractor::guidance::TurnType type);
std::string instructionModifierToString(guidance::DirectionModifier modifier); std::string instructionModifierToString(extractor::guidance::DirectionModifier modifier);
util::json::Array coordinateToLonLat(const util::Coordinate coordinate); util::json::Array coordinateToLonLat(const util::Coordinate coordinate);

View File

@ -39,8 +39,7 @@ class MatchAPI final : public RouteAPI
auto route = MakeRoute(sub_routes[index].segment_end_coordinates, auto route = MakeRoute(sub_routes[index].segment_end_coordinates,
sub_routes[index].unpacked_path_segments, sub_routes[index].unpacked_path_segments,
sub_routes[index].source_traversed_in_reverse, sub_routes[index].source_traversed_in_reverse,
sub_routes[index].target_traversed_in_reverse, sub_routes[index].target_traversed_in_reverse, nullptr);
nullptr);
route.values["confidence"] = sub_matchings[index].confidence; route.values["confidence"] = sub_matchings[index].confidence;
routes.values.push_back(std::move(route)); routes.values.push_back(std::move(route));
} }

View File

@ -152,6 +152,7 @@ class RouteAPI : public BaseAPI
leg_geometry.locations.begin() + step.geometry_end)); leg_geometry.locations.begin() + step.geometry_end));
}); });
} }
return json::makeRoute(route, return json::makeRoute(route,
json::makeRouteLegs(std::move(legs), std::move(step_geometries)), json::makeRouteLegs(std::move(legs), std::move(step_geometries)),
std::move(json_overview)); std::move(json_overview));

View File

@ -29,7 +29,7 @@ class TripAPI final : public RouteAPI
const std::vector<InternalRouteResult> &sub_routes, const std::vector<InternalRouteResult> &sub_routes,
const std::vector<PhantomNode> &phantoms, const std::vector<PhantomNode> &phantoms,
util::json::Object &response, util::json::Object &response,
const std::vector<std::vector<util::Coordinate>> * const coordinates) const const std::vector<std::vector<util::Coordinate>> *const coordinates) const
{ {
auto number_of_routes = sub_trips.size(); auto number_of_routes = sub_trips.size();
util::json::Array routes; util::json::Array routes;

View File

@ -7,7 +7,7 @@
#include "extractor/external_memory_node.hpp" #include "extractor/external_memory_node.hpp"
#include "contractor/query_edge.hpp" #include "contractor/query_edge.hpp"
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "util/integer_range.hpp" #include "util/integer_range.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "util/string_util.hpp" #include "util/string_util.hpp"
@ -76,7 +76,7 @@ class BaseDataFacade
virtual void GetUncompressedWeights(const EdgeID id, virtual void GetUncompressedWeights(const EdgeID id,
std::vector<EdgeWeight> &result_weights) const = 0; std::vector<EdgeWeight> &result_weights) const = 0;
virtual guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0; virtual extractor::guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0;
virtual extractor::TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0; virtual extractor::TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0;

View File

@ -5,6 +5,8 @@
#include "engine/datafacade/datafacade_base.hpp" #include "engine/datafacade/datafacade_base.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/geospatial_query.hpp" #include "engine/geospatial_query.hpp"
#include "extractor/original_edge_data.hpp" #include "extractor/original_edge_data.hpp"
#include "extractor/query_node.hpp" #include "extractor/query_node.hpp"
@ -68,7 +70,7 @@ class InternalDataFacade final : public BaseDataFacade
std::shared_ptr<util::ShM<util::Coordinate, false>::vector> m_coordinate_list; std::shared_ptr<util::ShM<util::Coordinate, false>::vector> m_coordinate_list;
util::ShM<NodeID, false>::vector m_via_node_list; util::ShM<NodeID, false>::vector m_via_node_list;
util::ShM<unsigned, false>::vector m_name_ID_list; util::ShM<unsigned, false>::vector m_name_ID_list;
util::ShM<guidance::TurnInstruction, false>::vector m_turn_instruction_list; util::ShM<extractor::guidance::TurnInstruction, false>::vector m_turn_instruction_list;
util::ShM<extractor::TravelMode, false>::vector m_travel_mode_list; util::ShM<extractor::TravelMode, false>::vector m_travel_mode_list;
util::ShM<char, false>::vector m_names_char_list; util::ShM<char, false>::vector m_names_char_list;
util::ShM<unsigned, false>::vector m_geometry_indices; util::ShM<unsigned, false>::vector m_geometry_indices;
@ -327,7 +329,7 @@ class InternalDataFacade final : public BaseDataFacade
return m_coordinate_list->at(id); return m_coordinate_list->at(id);
} }
guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final extractor::guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final
{ {
return m_turn_instruction_list.at(id); return m_turn_instruction_list.at(id);
} }

View File

@ -7,6 +7,8 @@
#include "storage/shared_datatype.hpp" #include "storage/shared_datatype.hpp"
#include "storage/shared_memory.hpp" #include "storage/shared_memory.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/geospatial_query.hpp" #include "engine/geospatial_query.hpp"
#include "util/range_table.hpp" #include "util/range_table.hpp"
#include "util/static_graph.hpp" #include "util/static_graph.hpp"
@ -70,7 +72,7 @@ class SharedDataFacade final : public BaseDataFacade
std::shared_ptr<util::ShM<util::Coordinate, true>::vector> m_coordinate_list; std::shared_ptr<util::ShM<util::Coordinate, true>::vector> m_coordinate_list;
util::ShM<NodeID, true>::vector m_via_node_list; util::ShM<NodeID, true>::vector m_via_node_list;
util::ShM<unsigned, true>::vector m_name_ID_list; util::ShM<unsigned, true>::vector m_name_ID_list;
util::ShM<guidance::TurnInstruction, true>::vector m_turn_instruction_list; util::ShM<extractor::guidance::TurnInstruction, true>::vector m_turn_instruction_list;
util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list; util::ShM<extractor::TravelMode, true>::vector m_travel_mode_list;
util::ShM<char, true>::vector m_names_char_list; util::ShM<char, true>::vector m_names_char_list;
util::ShM<unsigned, true>::vector m_name_begin_indices; util::ShM<unsigned, true>::vector m_name_begin_indices;
@ -145,9 +147,9 @@ class SharedDataFacade final : public BaseDataFacade
travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]); travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]);
m_travel_mode_list = std::move(travel_mode_list); m_travel_mode_list = std::move(travel_mode_list);
auto turn_instruction_list_ptr = data_layout->GetBlockPtr<guidance::TurnInstruction>( auto turn_instruction_list_ptr = data_layout->GetBlockPtr<extractor::guidance::TurnInstruction>(
shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION); shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION);
typename util::ShM<guidance::TurnInstruction, true>::vector turn_instruction_list( typename util::ShM<extractor::guidance::TurnInstruction, true>::vector turn_instruction_list(
turn_instruction_list_ptr, turn_instruction_list_ptr,
data_layout->num_entries[storage::SharedDataLayout::TURN_INSTRUCTION]); data_layout->num_entries[storage::SharedDataLayout::TURN_INSTRUCTION]);
m_turn_instruction_list = std::move(turn_instruction_list); m_turn_instruction_list = std::move(turn_instruction_list);
@ -398,7 +400,7 @@ class SharedDataFacade final : public BaseDataFacade
return m_via_node_list.at(id); return m_via_node_list.at(id);
} }
guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final extractor::guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final
{ {
return m_turn_instruction_list.at(id); return m_turn_instruction_list.at(id);
} }

View File

@ -7,7 +7,7 @@
#include "engine/guidance/leg_geometry.hpp" #include "engine/guidance/leg_geometry.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include <vector> #include <vector>
@ -49,7 +49,7 @@ LegGeometry assembleGeometry(const DataFacadeT &facade,
current_distance += current_distance +=
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate); util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate);
if (path_point.turn_instruction != TurnInstruction::NO_TURN()) if (path_point.turn_instruction != extractor::guidance::TurnInstruction::NO_TURN())
{ {
geometry.segment_distances.push_back(current_distance); geometry.segment_distances.push_back(current_distance);
geometry.segment_offsets.push_back(geometry.locations.size()); geometry.segment_offsets.push_back(geometry.locations.size());

View File

@ -4,8 +4,8 @@
#include "engine/guidance/route_step.hpp" #include "engine/guidance/route_step.hpp"
#include "engine/guidance/step_maneuver.hpp" #include "engine/guidance/step_maneuver.hpp"
#include "engine/guidance/leg_geometry.hpp" #include "engine/guidance/leg_geometry.hpp"
#include "engine/guidance/guidance_toolkit.hpp" #include "engine/guidance/toolkit.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "engine/internal_route_result.hpp" #include "engine/internal_route_result.hpp"
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
@ -25,7 +25,7 @@ namespace guidance
namespace detail namespace detail
{ {
// FIXME move implementation to cpp // FIXME move implementation to cpp
inline StepManeuver stepManeuverFromGeometry(TurnInstruction instruction, inline StepManeuver stepManeuverFromGeometry(extractor::guidance::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)
@ -59,7 +59,6 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
boost::optional<util::Coordinate> source_location, boost::optional<util::Coordinate> source_location,
boost::optional<util::Coordinate> target_location) boost::optional<util::Coordinate> target_location)
{ {
(void) source_location;
const auto source_duration = const auto source_duration =
(source_traversed_in_reverse ? source_node.GetReverseWeightPlusOffset() (source_traversed_in_reverse ? source_node.GetReverseWeightPlusOffset()
: source_node.GetForwardWeightPlusOffset()) / : source_node.GetForwardWeightPlusOffset()) /
@ -80,22 +79,28 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
steps.reserve(number_of_segments); steps.reserve(number_of_segments);
std::size_t segment_index = 0; std::size_t segment_index = 0;
const auto initial_modifier =
(source_location && leg_geometry.locations.size() >= 2)
? angleToDirectionModifier(util::coordinate_calculation::computeAngle(
source_location.get(), *(leg_geometry.locations.begin()),
*(leg_geometry.locations.begin() + 1)))
: extractor::guidance::DirectionModifier::UTurn;
if (leg_data.size() > 0) if (leg_data.size() > 0)
{ {
StepManeuver maneuver = detail::stepManeuverFromGeometry( StepManeuver maneuver = detail::stepManeuverFromGeometry(
TurnInstruction{TurnType::Location, DirectionModifier::UTurn}, leg_geometry, extractor::guidance::TurnInstruction{extractor::guidance::TurnType::Location,
segment_index, INVALID_EXIT_NR); initial_modifier},
maneuver.instruction.direction_modifier = bearingToDirectionModifier(maneuver.bearing_before); leg_geometry, segment_index, INVALID_EXIT_NR);
// TODO fix this: it makes no sense
// PathData saves the information we need of the segment _before_ the turn, // PathData saves the information we need of the segment _before_ the turn,
// but a RouteStep is with regard to the segment after the turn. // but a RouteStep is with regard to the segment after the turn.
// We need to skip the first segment because it is already covered by the // We need to skip the first segment because it is already covered by the
// initial start of a route // initial start of a route
for (const auto &path_point : leg_data) for (const auto &path_point : leg_data)
{ {
if (path_point.turn_instruction != TurnInstruction::NO_TURN()) if (path_point.turn_instruction != extractor::guidance::TurnInstruction::NO_TURN())
{ {
const auto name = facade.get_name_for_id(path_point.name_id); const auto name = facade.get_name_for_id(path_point.name_id);
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
@ -108,7 +113,6 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
segment_index++; segment_index++;
} }
} }
// TODO remove this hack
const auto distance = leg_geometry.segment_distances[segment_index]; const auto distance = leg_geometry.segment_distances[segment_index];
steps.push_back(RouteStep{target_node.name_id, facade.get_name_for_id(target_node.name_id), steps.push_back(RouteStep{target_node.name_id, facade.get_name_for_id(target_node.name_id),
target_duration, distance, target_mode, maneuver, target_duration, distance, target_mode, maneuver,
@ -123,9 +127,9 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
// x---*---*---*---z compressed edge // x---*---*---*---z compressed edge
// |-------| duration // |-------| duration
StepManeuver maneuver = {source_node.location, 0., 0., StepManeuver maneuver = {source_node.location, 0., 0.,
TurnInstruction{TurnType::Location, DirectionModifier::UTurn}, extractor::guidance::TurnInstruction{
extractor::guidance::TurnType::Location, initial_modifier},
INVALID_EXIT_NR}; INVALID_EXIT_NR};
maneuver.instruction.direction_modifier = bearingToDirectionModifier(maneuver.bearing_before);
steps.push_back(RouteStep{source_node.name_id, facade.get_name_for_id(source_node.name_id), steps.push_back(RouteStep{source_node.name_id, facade.get_name_for_id(source_node.name_id),
target_duration - source_duration, target_duration - source_duration,
@ -136,15 +140,18 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
BOOST_ASSERT(segment_index == number_of_segments - 1); BOOST_ASSERT(segment_index == number_of_segments - 1);
const auto final_modifier = const auto final_modifier =
target_location ? angleToDirectionModifier(util::coordinate_calculation::computeAngle( (target_location && leg_geometry.locations.size() >= 2)
*(leg_geometry.locations.end() - 3), ? angleToDirectionModifier(util::coordinate_calculation::computeAngle(
*(leg_geometry.locations.end() - 1), target_location.get())) *(leg_geometry.locations.end() - 2), *(leg_geometry.locations.end() - 1),
: DirectionModifier::UTurn; target_location.get()))
: extractor::guidance::DirectionModifier::UTurn;
// This step has length zero, the only reason we need it is the target location // This step has length zero, the only reason we need it is the target location
steps.push_back(RouteStep{ steps.push_back(RouteStep{
target_node.name_id, facade.get_name_for_id(target_node.name_id), 0., 0., target_mode, target_node.name_id, facade.get_name_for_id(target_node.name_id), 0., 0., target_mode,
StepManeuver{target_node.location, 0., 0., StepManeuver{target_node.location, 0., 0.,
TurnInstruction{TurnType::Location, final_modifier}, INVALID_EXIT_NR}, extractor::guidance::TurnInstruction{extractor::guidance::TurnType::Location,
final_modifier},
INVALID_EXIT_NR},
leg_geometry.locations.size(), leg_geometry.locations.size()}); leg_geometry.locations.size(), leg_geometry.locations.size()});
return steps; return steps;

View File

@ -12,7 +12,7 @@ namespace engine
namespace guidance namespace guidance
{ {
std::vector<std::vector<PathData>> postProcess( std::vector<std::vector<PathData>> path_data ); std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>> path_data);
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace engine

View File

@ -2,7 +2,7 @@
#define ENGINE_GUIDANCE_STEP_MANEUVER_HPP #define ENGINE_GUIDANCE_STEP_MANEUVER_HPP
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
namespace osrm namespace osrm
{ {
@ -16,7 +16,7 @@ struct StepManeuver
util::Coordinate location; util::Coordinate location;
double bearing_before; double bearing_before;
double bearing_after; double bearing_after;
TurnInstruction instruction; extractor::guidance::TurnInstruction instruction;
unsigned exit; unsigned exit;
}; };
} // namespace guidance } // namespace guidance

View File

@ -0,0 +1,62 @@
#ifndef OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_
#define OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_
#include "extractor/guidance/turn_instruction.hpp"
#include "util/bearing.hpp"
namespace osrm
{
namespace engine
{
namespace guidance
{
// Silent Turn Instructions are not to be mentioned to the outside world but
inline bool isSilent(const extractor::guidance::TurnInstruction instruction)
{
return instruction.type == extractor::guidance::TurnType::NoTurn || instruction.type == extractor::guidance::TurnType::Suppressed ||
instruction.type == extractor::guidance::TurnType::StayOnRoundabout;
}
inline bool entersRoundabout(const extractor::guidance::TurnInstruction instruction)
{
return (instruction.type == extractor::guidance::TurnType::EnterRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterRotary ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRotaryAtExit ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary);
}
inline bool leavesRoundabout(const extractor::guidance::TurnInstruction instruction)
{
return (instruction.type == extractor::guidance::TurnType::ExitRoundabout ||
instruction.type == extractor::guidance::TurnType::ExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary);
}
inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruction)
{
return instruction.type == extractor::guidance::TurnType::StayOnRoundabout;
}
inline extractor::guidance::DirectionModifier angleToDirectionModifier(const double bearing)
{
if (bearing < 135)
{
return extractor::guidance::DirectionModifier::Right;
}
if (bearing <= 225)
{
return extractor::guidance::DirectionModifier::Straight;
}
return extractor::guidance::DirectionModifier::Left;
}
} // namespace guidance
} // namespace engine
} // namespace osrm
#endif /* OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ */

View File

@ -3,7 +3,7 @@
#include "engine/phantom_node.hpp" #include "engine/phantom_node.hpp"
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "osrm/coordinate.hpp" #include "osrm/coordinate.hpp"
@ -26,7 +26,7 @@ struct PathData
// duration that is traveled on the segment until the turn is reached // duration that is traveled on the segment until the turn is reached
EdgeWeight duration_until_turn; EdgeWeight duration_until_turn;
// instruction to execute at the turn // instruction to execute at the turn
guidance::TurnInstruction turn_instruction; extractor::guidance::TurnInstruction turn_instruction;
// travel mode of the street that leads to the turn // travel mode of the street that leads to the turn
extractor::TravelMode travel_mode : 4; extractor::TravelMode travel_mode : 4;
// exit ID of highway exit, roundabout exit, intersection nr // exit ID of highway exit, roundabout exit, intersection nr

View File

@ -203,7 +203,7 @@ class BasePlugin
} }
} }
// we didn't found a fitting node, return error // we didn't find a fitting node, return error
if (phantom_nodes[i].empty()) if (phantom_nodes[i].empty())
{ {
break; break;
@ -264,7 +264,7 @@ class BasePlugin
} }
} }
// we didn't found a fitting node, return error // we didn't find a fitting node, return error
if (!phantom_node_pairs[i].first.IsValid(facade.GetNumberOfNodes())) if (!phantom_node_pairs[i].first.IsValid(facade.GetNumberOfNodes()))
{ {
//TODO document why? //TODO document why?

View File

@ -4,7 +4,7 @@
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include "engine/internal_route_result.hpp" #include "engine/internal_route_result.hpp"
#include "engine/search_engine_data.hpp" #include "engine/search_engine_data.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -283,7 +283,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
{ {
BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut"); BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id); unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
const guidance::TurnInstruction turn_instruction = const auto turn_instruction =
facade->GetTurnInstructionForEdgeID(ed.id); facade->GetTurnInstructionForEdgeID(ed.id);
const extractor::TravelMode travel_mode = const extractor::TravelMode travel_mode =
(unpacked_path.empty() && start_traversed_in_reverse) (unpacked_path.empty() && start_traversed_in_reverse)
@ -320,9 +320,9 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
BOOST_ASSERT(start_index < end_index); BOOST_ASSERT(start_index < end_index);
for (std::size_t i = start_index; i < end_index; ++i) for (std::size_t i = start_index; i < end_index; ++i)
{ {
unpacked_path.push_back(PathData{id_vector[i], name_index, weight_vector[i], unpacked_path.push_back(PathData{id_vector[i], name_index, weight_vector[i],
guidance::TurnInstruction::NO_TURN(), extractor::guidance::TurnInstruction::NO_TURN(),
travel_mode, INVALID_EXIT_NR}); travel_mode, INVALID_EXIT_NR});
} }
BOOST_ASSERT(unpacked_path.size() > 0); BOOST_ASSERT(unpacked_path.size() > 0);
unpacked_path.back().turn_instruction = turn_instruction; unpacked_path.back().turn_instruction = turn_instruction;
@ -365,7 +365,7 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0); BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
unpacked_path.emplace_back(PathData{ unpacked_path.emplace_back(PathData{
id_vector[i], phantom_node_pair.target_phantom.name_id, 0, id_vector[i], phantom_node_pair.target_phantom.name_id, 0,
guidance::TurnInstruction::NO_TURN(), extractor::guidance::TurnInstruction::NO_TURN(),
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
: phantom_node_pair.target_phantom.forward_travel_mode, : phantom_node_pair.target_phantom.forward_travel_mode,
INVALID_EXIT_NR}); INVALID_EXIT_NR});

View File

@ -10,9 +10,9 @@
#include "extractor/edge_based_node.hpp" #include "extractor/edge_based_node.hpp"
#include "extractor/original_edge_data.hpp" #include "extractor/original_edge_data.hpp"
#include "extractor/query_node.hpp" #include "extractor/query_node.hpp"
#include "extractor/turn_analysis.hpp" #include "extractor/guidance/turn_analysis.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@ -71,12 +71,12 @@ class EdgeBasedGraphFactory
// with known angle. // with known angle.
// Handles special cases like u-turns and roundabouts // Handles special cases like u-turns and roundabouts
// For basic turns, the turn based on the angle-classification is returned // For basic turns, the turn based on the angle-classification is returned
engine::guidance::TurnInstruction AnalyzeTurn(const NodeID u, guidance::TurnInstruction AnalyzeTurn(const NodeID u,
const EdgeID e1, const EdgeID e1,
const NodeID v, const NodeID v,
const EdgeID e2, const EdgeID e2,
const NodeID w, const NodeID w,
const double angle) const; const double angle) const;
std::int32_t GetTurnPenalty(double angle, lua_State *lua_state) const; std::int32_t GetTurnPenalty(double angle, lua_State *lua_state) const;
@ -129,10 +129,6 @@ class EdgeBasedGraphFactory
void FlushVectorToStream(std::ofstream &edge_data_file, void FlushVectorToStream(std::ofstream &edge_data_file,
std::vector<OriginalEdgeData> &original_edge_data_vector) const; std::vector<OriginalEdgeData> &original_edge_data_vector) const;
// Use In Order to generate base turns
std::vector<TurnCandidate> getTurns(const NodeID from, const EdgeID via_edge);
// cannot be const due to the counters...
std::size_t restricted_turns_counter; std::size_t restricted_turns_counter;
std::size_t skipped_uturns_counter; std::size_t skipped_uturns_counter;
std::size_t skipped_barrier_turns_counter; std::size_t skipped_barrier_turns_counter;

View File

@ -3,7 +3,6 @@
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "engine/guidance/classification_data.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
@ -34,7 +33,6 @@ struct ExtractionWay
name.clear(); name.clear();
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE; forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE; backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
road_classification_data.invalidate();
} }
// These accessors exists because it's not possible to take the address of a bitfield, // These accessors exists because it's not possible to take the address of a bitfield,
@ -53,7 +51,6 @@ struct ExtractionWay
bool is_startpoint; bool is_startpoint;
TravelMode forward_travel_mode : 4; TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4; TravelMode backward_travel_mode : 4;
engine::guidance::RoadClassificationData road_classification_data;
}; };
} }
} }

View File

@ -1,13 +1,11 @@
#ifndef OSRM_GUIDANCE_CLASSIFICATION_DATA_HPP_ #ifndef OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
#define OSRM_GUIDANCE_CLASSIFICATION_DATA_HPP_ #define OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
#include "util/simple_logger.hpp"
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <iostream> //TODO remove
#include "util/simple_logger.hpp"
// Forward Declaration to allow usage of external osmium::Way // Forward Declaration to allow usage of external osmium::Way
namespace osmium namespace osmium
{ {
@ -16,13 +14,14 @@ class Way;
namespace osrm namespace osrm
{ {
namespace engine namespace extractor
{ {
namespace guidance namespace guidance
{ {
enum FunctionalRoadClass enum class FunctionalRoadClass : short
{ {
UNKNOWN = 0,
MOTORWAY, MOTORWAY,
MOTORWAY_LINK, MOTORWAY_LINK,
TRUNK, TRUNK,
@ -37,12 +36,12 @@ enum FunctionalRoadClass
RESIDENTIAL, RESIDENTIAL,
SERVICE, SERVICE,
LIVING_STREET, LIVING_STREET,
LOW_PRIORITY_ROAD, // a road simply included for connectivity. Should be avoided at all cost LOW_PRIORITY_ROAD // a road simply included for connectivity. Should be avoided at all cost
UNKNOWN
}; };
inline FunctionalRoadClass functionalRoadClassFromTag(std::string const &value) inline FunctionalRoadClass functionalRoadClassFromTag(std::string const &value)
{ {
//FIXME at some point this should be part of the profiles
const static auto initializeClassHash = []() const static auto initializeClassHash = []()
{ {
std::unordered_map<std::string, FunctionalRoadClass> hash; std::unordered_map<std::string, FunctionalRoadClass> hash;
@ -84,36 +83,25 @@ inline FunctionalRoadClass functionalRoadClassFromTag(std::string const &value)
inline bool isRampClass(const FunctionalRoadClass road_class) inline bool isRampClass(const FunctionalRoadClass road_class)
{ {
// Primary Roads and down are usually too small to announce their links as ramps // Primary Roads and down are usually too small to announce their links as ramps
return road_class == MOTORWAY_LINK || road_class == TRUNK_LINK; return road_class == FunctionalRoadClass::MOTORWAY_LINK ||
//|| road_class == PRIMARY_LINK || road_class == FunctionalRoadClass::TRUNK_LINK;
// road_class == SECONDARY_LINK || road_class == TERTIARY_LINK;
} }
// TODO augment this with all data required for guidance generation // TODO augment this with all data required for guidance generation
struct RoadClassificationData struct RoadClassificationData
{ {
FunctionalRoadClass road_class; FunctionalRoadClass road_class = FunctionalRoadClass::UNKNOWN;
void augment(const osmium::Way &way); void augment(const osmium::Way &way);
// reset to a defined but invalid state
void invalidate();
static RoadClassificationData INVALID()
{
RoadClassificationData tmp;
tmp.invalidate();
return tmp;
};
}; };
inline bool operator==( const RoadClassificationData lhs, const RoadClassificationData rhs ) inline bool operator==(const RoadClassificationData lhs, const RoadClassificationData rhs)
{ {
return lhs.road_class == rhs.road_class; return lhs.road_class == rhs.road_class;
} }
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace extractor
} // namespace osrm } // namespace osrm
#endif // OSRM_GUIDANCE_CLASSIFICATION_DATA_HPP_ #endif // OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_

View File

@ -0,0 +1,16 @@
#ifndef OSRM_EXTRACTOR_GUIDANCE_DISCRETE_ANGLE
#define OSRM_EXTRACTOR_GUIDANCE_DISCRETE_ANGLE
namespace osrm
{
namespace extractor
{
namespace guidance
{
typedef uint8_t DiscreteAngle;
} // namespace guidance
} // namespace extractor
} // namespace osrm
#endif /* OSRM_EXTRACTOR_GUIDANCE_DISCRETE_ANGLE */

View File

@ -1,5 +1,5 @@
#ifndef OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_ #ifndef OSRM_GUIDANCE_TOOLKIT_HPP_
#define OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_ #define OSRM_GUIDANCE_TOOLKIT_HPP_
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
@ -8,15 +8,16 @@
#include "extractor/compressed_edge_container.hpp" #include "extractor/compressed_edge_container.hpp"
#include "extractor/query_node.hpp" #include "extractor/query_node.hpp"
#include "engine/guidance/classification_data.hpp" #include "extractor/guidance/discrete_angle.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/classification_data.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include <map> #include <map>
#include <cmath> #include <cmath>
namespace osrm namespace osrm
{ {
namespace engine namespace extractor
{ {
namespace guidance namespace guidance
{ {
@ -26,15 +27,10 @@ namespace detail
const constexpr double DESIRED_SEGMENT_LENGTH = 10.0; const constexpr double DESIRED_SEGMENT_LENGTH = 10.0;
const constexpr bool shiftable_ccw[] = {false, true, true, false, false, true, true, false}; const constexpr bool shiftable_ccw[] = {false, true, true, false, false, true, true, false};
const constexpr bool shiftable_cw[] = {false, false, true, true, false, false, true, true}; const constexpr bool shiftable_cw[] = {false, false, true, true, false, false, true, true};
// direction modifier bounds in 360./256. degrees const constexpr uint8_t modifier_bounds[detail::num_direction_modifiers] = {
const constexpr uint8_t modifier_bounds[num_direction_modifiers] = {0, 36, 93, 121, 0, 36, 93, 121, 136, 163, 220, 255};
136, 163, 220, 255};
const constexpr double discrete_angle_step_size = 360. / 256.; const constexpr double discrete_angle_step_size = 360. / 256.;
} // namespace detail
namespace detail
{
template <typename IteratorType> template <typename IteratorType>
util::Coordinate util::Coordinate
getCoordinateFromCompressedRange(util::Coordinate current_coordinate, getCoordinateFromCompressedRange(util::Coordinate current_coordinate,
@ -136,13 +132,15 @@ getRepresentativeCoordinate(const NodeID from_node,
} }
// shift an instruction around the degree circle in CCW order // shift an instruction around the degree circle in CCW order
inline DirectionModifier forcedShiftCCW(const DirectionModifier modifier) inline DirectionModifier
forcedShiftCCW(const DirectionModifier modifier)
{ {
return static_cast<DirectionModifier>((static_cast<uint32_t>(modifier) + 1) % return static_cast<DirectionModifier>(
detail::num_direction_modifiers); (static_cast<uint32_t>(modifier) + 1) % detail::num_direction_modifiers);
} }
inline DirectionModifier shiftCCW(const DirectionModifier modifier) inline DirectionModifier
shiftCCW(const DirectionModifier modifier)
{ {
if (detail::shiftable_ccw[static_cast<int>(modifier)]) if (detail::shiftable_ccw[static_cast<int>(modifier)])
return forcedShiftCCW(modifier); return forcedShiftCCW(modifier);
@ -151,14 +149,16 @@ inline DirectionModifier shiftCCW(const DirectionModifier modifier)
} }
// shift an instruction around the degree circle in CW order // shift an instruction around the degree circle in CW order
inline DirectionModifier forcedShiftCW(const DirectionModifier modifier) inline DirectionModifier
forcedShiftCW(const DirectionModifier modifier)
{ {
return static_cast<DirectionModifier>( return static_cast<DirectionModifier>(
(static_cast<uint32_t>(modifier) + detail::num_direction_modifiers - 1) % (static_cast<uint32_t>(modifier) + detail::num_direction_modifiers - 1) %
detail::num_direction_modifiers); detail::num_direction_modifiers);
} }
inline DirectionModifier shiftCW(const DirectionModifier modifier) inline DirectionModifier
shiftCW(const DirectionModifier modifier)
{ {
if (detail::shiftable_cw[static_cast<int>(modifier)]) if (detail::shiftable_cw[static_cast<int>(modifier)])
return forcedShiftCW(modifier); return forcedShiftCW(modifier);
@ -166,60 +166,21 @@ inline DirectionModifier shiftCW(const DirectionModifier modifier)
return modifier; return modifier;
} }
inline bool entersRoundabout(const TurnInstruction instruction)
{
return (instruction.type == TurnType::EnterRoundabout ||
instruction.type == TurnType::EnterRotary ||
instruction.type == TurnType::EnterRoundaboutAtExit ||
instruction.type == TurnType::EnterRotaryAtExit ||
instruction.type == TurnType::EnterAndExitRoundabout ||
instruction.type == TurnType::EnterAndExitRotary);
}
inline bool leavesRoundabout(const TurnInstruction instruction)
{
return (instruction.type == TurnType::ExitRoundabout ||
instruction.type == TurnType::ExitRotary ||
instruction.type == TurnType::EnterAndExitRoundabout ||
instruction.type == TurnType::EnterAndExitRotary);
}
inline bool staysOnRoundabout(const TurnInstruction instruction)
{
return instruction.type == TurnType::StayOnRoundabout;
}
inline bool isOnRoundabout(const TurnInstruction instruction)
{
return staysOnRoundabout(instruction) || leavesRoundabout(instruction);
}
inline bool isTurnNecessary(const TurnInstruction instruction)
{
return instruction.type != TurnType::NoTurn && instruction.type != TurnType::Suppressed;
}
inline bool isLeftRight(const DirectionModifier modifier)
{
return DirectionModifier::Right == modifier || DirectionModifier::Left == modifier;
}
inline bool isSlightLeftRight(const DirectionModifier modifier)
{
return DirectionModifier::SlightRight == modifier || DirectionModifier::SlightLeft == modifier;
}
inline bool isBasic(const TurnType type) inline bool isBasic(const TurnType type)
{ {
return type == TurnType::Turn || type == TurnType::EndOfRoad; return type == TurnType::Turn ||
type == TurnType::EndOfRoad;
} }
inline bool isUturn(const TurnInstruction instruction) inline bool isUturn(const TurnInstruction instruction)
{ {
return isBasic(instruction.type) && instruction.direction_modifier == DirectionModifier::UTurn; return isBasic(instruction.type) &&
instruction.direction_modifier == DirectionModifier::UTurn;
} }
inline bool resolve(TurnInstruction &to_resolve, const TurnInstruction neighbor, bool resolve_cw) inline bool resolve(TurnInstruction &to_resolve,
const TurnInstruction neighbor,
bool resolve_cw)
{ {
const auto shifted_turn = resolve_cw ? shiftCW(to_resolve.direction_modifier) const auto shifted_turn = resolve_cw ? shiftCW(to_resolve.direction_modifier)
: shiftCCW(to_resolve.direction_modifier); : shiftCCW(to_resolve.direction_modifier);
@ -262,8 +223,9 @@ inline bool isSlightModifier(const DirectionModifier direction_modifier)
inline bool isSharpTurn(const TurnInstruction turn) inline bool isSharpTurn(const TurnInstruction turn)
{ {
return isBasic(turn.type) && (turn.direction_modifier == DirectionModifier::SharpLeft || return isBasic(turn.type) &&
turn.direction_modifier == DirectionModifier::SharpRight); (turn.direction_modifier == DirectionModifier::SharpLeft ||
turn.direction_modifier == DirectionModifier::SharpRight);
} }
inline bool isStraight(const TurnInstruction turn) inline bool isStraight(const TurnInstruction turn)
@ -272,30 +234,18 @@ inline bool isStraight(const TurnInstruction turn)
turn.direction_modifier == DirectionModifier::Straight; turn.direction_modifier == DirectionModifier::Straight;
} }
inline bool isConflict(const TurnInstruction first, const TurnInstruction second) inline bool isConflict(const TurnInstruction first,
const TurnInstruction second)
{ {
return (first.type == second.type && first.direction_modifier == second.direction_modifier) || return (first.type == second.type && first.direction_modifier == second.direction_modifier) ||
(isStraight(first) && isStraight(second)); (isStraight(first) && isStraight(second));
} }
inline DirectionModifier discreteAngleToDircetionModifier(const DiscreteAngle angle)
{
auto modifier = DirectionModifier::UTurn;
DiscreteAngle bound(detail::modifier_bounds[modifier]);
do
{
if (angle <= bound)
return modifier;
modifier = forcedShiftCW(modifier);
bound = static_cast<DiscreteAngle>(detail::modifier_bounds[modifier]);
} while (modifier != DirectionModifier::UTurn);
return modifier;
}
inline DiscreteAngle discretizeAngle(const double angle) inline DiscreteAngle discretizeAngle(const double angle)
{ {
BOOST_ASSERT(angle >= 0. && angle <= 360.); BOOST_ASSERT(angle >= 0. && angle <= 360.);
return DiscreteAngle(static_cast<uint8_t>(angle / detail::discrete_angle_step_size)); return DiscreteAngle(
static_cast<uint8_t>(angle / detail::discrete_angle_step_size));
} }
inline double angleFromDiscreteAngle(const DiscreteAngle angle) inline double angleFromDiscreteAngle(const DiscreteAngle angle)
@ -319,7 +269,8 @@ inline double getTurnConfidence(const double angle, TurnInstruction instruction)
{ {
// special handling of U-Turns and Roundabout // special handling of U-Turns and Roundabout
if (!isBasic(instruction.type) || instruction.direction_modifier == DirectionModifier::UTurn) if (!isBasic(instruction.type) ||
instruction.direction_modifier == DirectionModifier::UTurn)
return 1.0; return 1.0;
const double deviations[] = {0, 45, 50, 35, 10, 35, 50, 45}; const double deviations[] = {0, 45, 50, 35, 10, 35, 50, 45};
@ -352,57 +303,19 @@ inline DirectionModifier getTurnDirection(const double angle)
return DirectionModifier::UTurn; return DirectionModifier::UTurn;
} }
inline DirectionModifier angleToDirectionModifier(const double bearing)
{
if (bearing < 135)
{
return DirectionModifier::Right;
}
if (bearing <= 225)
{
return DirectionModifier::Straight;
}
return DirectionModifier::Left;
}
inline DirectionModifier bearingToDirectionModifier(const std::string &bearing)
{
const static auto buildHash = []()
{
std::map<std::string, DirectionModifier> hash;
hash["N"] = DirectionModifier::Straight;
hash["NE"] = DirectionModifier::SlightRight;
hash["E"] = DirectionModifier::Right;
hash["SE"] = DirectionModifier::SharpRight;
hash["S"] = DirectionModifier::UTurn;
hash["SW"] = DirectionModifier::SharpLeft;
hash["W"] = DirectionModifier::Left;
hash["NW"] = DirectionModifier::SlightLeft;
return hash;
};
const static std::map<std::string, DirectionModifier> hash = buildHash();
return hash.find(bearing)->second;
}
inline DirectionModifier bearingToDirectionModifier(const double angle)
{
return bearingToDirectionModifier(util::bearing::get(angle));
}
inline bool isHighway(FunctionalRoadClass road_class)
{
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
}
// swaps left <-> right modifier types // swaps left <-> right modifier types
inline DirectionModifier mirrorDirectionModifier(const DirectionModifier modifier) inline DirectionModifier
mirrorDirectionModifier(const DirectionModifier modifier)
{ {
const constexpr DirectionModifier results[] = { const constexpr DirectionModifier results[] = {
DirectionModifier::UTurn, DirectionModifier::SharpLeft, DirectionModifier::Left, DirectionModifier::UTurn,
DirectionModifier::SlightLeft, DirectionModifier::Straight, DirectionModifier::SlightRight, DirectionModifier::SharpLeft,
DirectionModifier::Right, DirectionModifier::SharpRight}; DirectionModifier::Left,
DirectionModifier::SlightLeft,
DirectionModifier::Straight,
DirectionModifier::SlightRight,
DirectionModifier::Right,
DirectionModifier::SharpRight};
return results[modifier]; return results[modifier];
} }
@ -420,7 +333,7 @@ inline bool isLowPriorityRoadClass(const FunctionalRoadClass road_class)
} }
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace extractor
} // namespace osrm } // namespace osrm
#endif // OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_ #endif // OSRM_GUIDANCE_TOOLKIT_HPP_

View File

@ -1,9 +1,8 @@
#ifndef OSRM_EXTRACTOR_TURN_ANALYSIS #ifndef OSRM_EXTRACTOR_TURN_ANALYSIS
#define OSRM_EXTRACTOR_TURN_ANALYSIS #define OSRM_EXTRACTOR_TURN_ANALYSIS
#include "engine/guidance/turn_classification.hpp" #include "extractor/guidance/turn_classification.hpp"
#include "engine/guidance/guidance_toolkit.hpp" #include "extractor/guidance/toolkit.hpp"
#include "extractor/restriction_map.hpp" #include "extractor/restriction_map.hpp"
#include "extractor/compressed_edge_container.hpp" #include "extractor/compressed_edge_container.hpp"
@ -13,14 +12,16 @@ namespace osrm
{ {
namespace extractor namespace extractor
{ {
namespace guidance
{
struct TurnCandidate struct TurnCandidate
{ {
EdgeID eid; // the id of the arc EdgeID eid; // the id of the arc
bool valid; // a turn may be relevant to good instructions, even if we cannot take the road bool valid; // a turn may be relevant to good instructions, even if we cannot take the road
double angle; // the approximated angle of the turn double angle; // the approximated angle of the turn
engine::guidance::TurnInstruction instruction; // a proposed instruction TurnInstruction instruction; // a proposed instruction
double confidence; // how close to the border is the turn? double confidence; // how close to the border is the turn?
std::string toString() const std::string toString() const
{ {
@ -38,8 +39,6 @@ struct TurnCandidate
return result; return result;
} }
}; };
namespace turn_analysis
{
// the entry into the turn analysis // the entry into the turn analysis
std::vector<TurnCandidate> std::vector<TurnCandidate>
@ -57,6 +56,7 @@ namespace detail
// Check for restrictions/barriers and generate a list of valid and invalid turns present at the // Check for restrictions/barriers and generate a list of valid and invalid turns present at the
// node reached // node reached
// from `from_node` via `via_eid` // from `from_node` via `via_eid`
// The resulting candidates have to be analysed for their actual instructions later on.
std::vector<TurnCandidate> std::vector<TurnCandidate>
getTurnCandidates(const NodeID from_node, getTurnCandidates(const NodeID from_node,
const EdgeID via_eid, const EdgeID via_eid,
@ -66,16 +66,27 @@ getTurnCandidates(const NodeID from_node,
const std::unordered_set<NodeID> &barrier_nodes, const std::unordered_set<NodeID> &barrier_nodes,
const CompressedEdgeContainer &compressed_edge_container); const CompressedEdgeContainer &compressed_edge_container);
// merge segregated roads to omit invalid turns in favor of treating segregated roads as one // Merge segregated roads to omit invalid turns in favor of treating segregated roads as one.
// This function combines roads the following way:
//
// * *
// * is converted to *
// v ^ +
// v ^ +
//
// The treatment results in a straight turn angle of 180º rather than a turn angle of approx 160
std::vector<TurnCandidate> std::vector<TurnCandidate>
mergeSegregatedRoads(const NodeID from_node, mergeSegregatedRoads(const NodeID from_node,
const EdgeID via_eid, const EdgeID via_eid,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// handle roundabouts
// TODO distinguish roundabouts and rotaries // TODO distinguish roundabouts and rotaries
// TODO handle bike/walk cases that allow crossing a roundabout! // TODO handle bike/walk cases that allow crossing a roundabout!
// Processing of roundabouts
// Produces instructions to enter/exit a roundabout or to stay on it.
// Performs the distinction between roundabout and rotaries.
std::vector<TurnCandidate> std::vector<TurnCandidate>
handleRoundabouts(const NodeID from, handleRoundabouts(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
@ -85,79 +96,100 @@ handleRoundabouts(const NodeID from,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// A Basic junction is a junction not requiring special treatment. It cannot contain anything
// but streets of lesser priority than trunks and ramps (of any type). No roundabouts or motorway
// like types.
bool isBasicJunction(const NodeID from, bool isBasicJunction(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
const std::vector<TurnCandidate> &turn_candidates, const std::vector<TurnCandidate> &turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Indicates a Junction containing a motoryway
bool isMotorwayJunction(const NodeID from, bool isMotorwayJunction(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
const std::vector<TurnCandidate> &turn_candidates, const std::vector<TurnCandidate> &turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Decide whether a turn is a turn or a ramp access // Decide whether a turn is a turn or a ramp access
engine::guidance::TurnType TurnType turnOrRamp(const NodeID from,
turnOrRamp(const NodeID from, const EdgeID via_edge,
const EdgeID via_edge, const TurnCandidate &candidate,
const TurnCandidate &candidate, const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Get the Instruction for an obvious turn // Get the Instruction for an obvious turn
engine::guidance::TurnInstruction // Instruction will be a silent instruction
TurnInstruction
getInstructionForObvious(const NodeID from, getInstructionForObvious(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
const TurnCandidate &candidate, const TurnCandidate &candidate,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
engine::guidance::TurnInstruction // Helper Function that decides between NoTurn or NewName
TurnInstruction
noTurnOrNewName(const NodeID from, noTurnOrNewName(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
const TurnCandidate &candidate, const TurnCandidate &candidate,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// handle basic intersections // Basic Turn Handling
// Dead end.
std::vector<TurnCandidate> std::vector<TurnCandidate>
handleOneWayTurn(const NodeID from, handleOneWayTurn(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Mode Changes, new names...
std::vector<TurnCandidate> std::vector<TurnCandidate>
handleTwoWayTurn(const NodeID from, handleTwoWayTurn(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Forks, T intersections and similar
std::vector<TurnCandidate> std::vector<TurnCandidate>
handleThreeWayTurn(const NodeID from, handleThreeWayTurn(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Normal Intersection. Can still contain forks...
std::vector<TurnCandidate> std::vector<TurnCandidate>
handleFourWayTurn(const NodeID from, handleFourWayTurn(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Fallback for turns of high complexion
std::vector<TurnCandidate> std::vector<TurnCandidate>
handleComplexTurn(const NodeID from, handleComplexTurn(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Any Junction containing motorways
std::vector<TurnCandidate> std::vector<TurnCandidate>
handleMotorwayJunction(const NodeID from, handleMotorwayJunction(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Utility function, setting basic turn types. Prepares for normal turn handling.
std::vector<TurnCandidate> std::vector<TurnCandidate>
setTurnTypes(const NodeID from, setTurnTypes(const NodeID from,
const EdgeID via_edge, const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Utility function to handle direction modifier conflicts if reasonably possible
std::vector<TurnCandidate>
handleConflicts(const NodeID from,
const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// Old fallbacks, to be removed
std::vector<TurnCandidate> std::vector<TurnCandidate>
optimizeRamps(const EdgeID via_edge, optimizeRamps(const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
@ -180,7 +212,7 @@ suppressTurns(const EdgeID via_eid,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
// node_u -- (edge_1) --> node_v -- (edge_2) --> node_w // node_u -- (edge_1) --> node_v -- (edge_2) --> node_w
engine::guidance::TurnInstruction TurnInstruction
AnalyzeTurn(const NodeID node_u, AnalyzeTurn(const NodeID node_u,
const EdgeID edge1, const EdgeID edge1,
const NodeID node_v, const NodeID node_v,
@ -189,13 +221,8 @@ AnalyzeTurn(const NodeID node_u,
const double angle, const double angle,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph); const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
std::vector<TurnCandidate>
handleConflicts(const NodeID from,
const EdgeID via_edge,
std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
} // namespace detail } // namespace detail
} // namespace turn_analysis } // namespace guidance
} // namespace extractor } // namespace extractor
} // namespace osrm } // namespace osrm

View File

@ -1,8 +1,7 @@
#ifndef OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_ #ifndef OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_
#define OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_ #define OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/toolkit.hpp"
#include "engine/guidance/guidance_toolkit.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
@ -17,7 +16,7 @@
namespace osrm namespace osrm
{ {
namespace engine namespace extractor
{ {
namespace guidance namespace guidance
{ {
@ -35,6 +34,26 @@ struct TurnPossibility
EdgeID edge_id; EdgeID edge_id;
}; };
struct CompareTurnPossibilities
{
bool operator()(const std::vector<TurnPossibility> &left,
const std::vector<TurnPossibility> &right) const
{
if (left.size() < right.size())
return true;
if (left.size() > right.size())
return false;
for (std::size_t i = 0; i < left.size(); ++i)
{
if ((((int)left[i].angle + 16) % 256) / 32 < (((int)right[i].angle + 16) % 256) / 32)
return true;
if ((((int)left[i].angle + 16) % 256) / 32 > (((int)right[i].angle + 16) % 256) / 32)
return false;
}
return false;
}
};
inline std::vector<TurnPossibility> inline std::vector<TurnPossibility>
classifyIntersection(NodeID nid, classifyIntersection(NodeID nid,
const util::NodeBasedDynamicGraph &graph, const util::NodeBasedDynamicGraph &graph,
@ -98,7 +117,7 @@ classifyIntersection(NodeID nid,
} }
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace extractor
} // namespace osrm } // namespace osrm
#endif // OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_ #endif // OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_

View File

@ -7,7 +7,7 @@
namespace osrm namespace osrm
{ {
namespace engine namespace extractor
{ {
namespace guidance namespace guidance
{ {
@ -33,17 +33,6 @@ enum DirectionModifier
SharpLeft SharpLeft
}; };
const constexpr char *modifier_names[detail::num_direction_modifiers] = {
"uturn", "sharp right", "right", "slight right",
"straight", "slight left", "left", "sharp left"};
enum LocationType
{
Start,
Intermediate,
Destination
};
// enum class TurnType : unsigned char // enum class TurnType : unsigned char
enum TurnType // at the moment we can support 32 turn types, without increasing memory consumption enum TurnType // at the moment we can support 32 turn types, without increasing memory consumption
{ {
@ -71,42 +60,7 @@ enum TurnType // at the moment we can support 32 turn types, without increasing
Notification // Travel Mode Changes` Notification // Travel Mode Changes`
}; };
inline bool isValidModifier( const TurnType type, const DirectionModifier modifier )
{
if( type == TurnType::Location &&
modifier != DirectionModifier::Left
&& modifier != DirectionModifier::Straight
&& modifier != DirectionModifier::Right )
return false;
return true;
}
const constexpr char *turn_type_names[] = {"invalid",
"no turn",
"waypoint",
"invalid",
"new name",
"continue",
"turn",
"merge",
"ramp",
"fork",
"end of road",
"roundabout",
"invalid",
"roundabout",
"invalid",
"traffic circle",
"invalid",
"traffic circle",
"invalid",
"invalid",
"restriction",
"notification"};
// turn angle in 1.40625 degree -> 128 == 180 degree // turn angle in 1.40625 degree -> 128 == 180 degree
typedef uint8_t DiscreteAngle;
struct TurnInstruction struct TurnInstruction
{ {
TurnInstruction(const TurnType type = TurnType::Invalid, TurnInstruction(const TurnType type = TurnType::Invalid,
@ -135,7 +89,7 @@ struct TurnInstruction
static TurnInstruction ENTER_ROUNDABOUT(const DirectionModifier modifier) static TurnInstruction ENTER_ROUNDABOUT(const DirectionModifier modifier)
{ {
return TurnInstruction(TurnType::EnterRoundabout, modifier); return TurnInstruction(TurnType::EnterRoundabout, modifier);
} }
static TurnInstruction EXIT_ROUNDABOUT(const DirectionModifier modifier) static TurnInstruction EXIT_ROUNDABOUT(const DirectionModifier modifier)
@ -145,7 +99,7 @@ struct TurnInstruction
static TurnInstruction SUPPRESSED(const DirectionModifier modifier) static TurnInstruction SUPPRESSED(const DirectionModifier modifier)
{ {
return TurnInstruction{TurnType::Suppressed,modifier}; return TurnInstruction{TurnType::Suppressed, modifier};
} }
}; };
@ -159,15 +113,8 @@ inline bool operator==(const TurnInstruction lhs, const TurnInstruction rhs)
return lhs.type == rhs.type && lhs.direction_modifier == rhs.direction_modifier; return lhs.type == rhs.type && lhs.direction_modifier == rhs.direction_modifier;
} }
// Silent Turn Instructions are not to be mentioned to the outside world
inline bool isSilent(const TurnInstruction instruction)
{
return instruction.type == TurnType::NoTurn || instruction.type == TurnType::Suppressed ||
instruction.type == TurnType::StayOnRoundabout;
}
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace extractor
} // namespace osrm } // namespace osrm
#endif // OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_ #endif // OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_

View File

@ -9,7 +9,7 @@
#include "osrm/coordinate.hpp" #include "osrm/coordinate.hpp"
#include <utility> #include <utility>
#include "engine/guidance/classification_data.hpp" #include "extractor/guidance/classification_data.hpp"
namespace osrm namespace osrm
{ {
@ -52,7 +52,7 @@ struct InternalExtractorEdge
true, true,
TRAVEL_MODE_INACCESSIBLE, TRAVEL_MODE_INACCESSIBLE,
false, false,
engine::guidance::RoadClassificationData::INVALID()) guidance::RoadClassificationData())
{ {
} }
@ -67,7 +67,7 @@ struct InternalExtractorEdge
bool startpoint, bool startpoint,
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
engine::guidance::RoadClassificationData road_classification) guidance::RoadClassificationData road_classification)
: result(OSMNodeID(source), : result(OSMNodeID(source),
OSMNodeID(target), OSMNodeID(target),
name_id, name_id,
@ -96,13 +96,13 @@ struct InternalExtractorEdge
{ {
return InternalExtractorEdge(MIN_OSM_NODEID, MIN_OSM_NODEID, 0, WeightData(), false, false, return InternalExtractorEdge(MIN_OSM_NODEID, MIN_OSM_NODEID, 0, WeightData(), false, false,
false, false, true, TRAVEL_MODE_INACCESSIBLE, false, false, false, true, TRAVEL_MODE_INACCESSIBLE, false,
engine::guidance::RoadClassificationData::INVALID()); guidance::RoadClassificationData());
} }
static InternalExtractorEdge max_osm_value() static InternalExtractorEdge max_osm_value()
{ {
return InternalExtractorEdge(MAX_OSM_NODEID, MAX_OSM_NODEID, 0, WeightData(), false, false, return InternalExtractorEdge(MAX_OSM_NODEID, MAX_OSM_NODEID, 0, WeightData(), false, false,
false, false, true, TRAVEL_MODE_INACCESSIBLE, false, false, false, true, TRAVEL_MODE_INACCESSIBLE, false,
engine::guidance::RoadClassificationData::INVALID()); guidance::RoadClassificationData());
} }
static InternalExtractorEdge min_internal_value() static InternalExtractorEdge min_internal_value()

View File

@ -4,7 +4,7 @@
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "engine/guidance/classification_data.hpp" #include "extractor/guidance/classification_data.hpp"
namespace osrm namespace osrm
{ {
@ -26,7 +26,7 @@ struct NodeBasedEdge
bool startpoint, bool startpoint,
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
engine::guidance::RoadClassificationData road_classification); guidance::RoadClassificationData road_classification);
bool operator<(const NodeBasedEdge &other) const; bool operator<(const NodeBasedEdge &other) const;
@ -41,7 +41,7 @@ struct NodeBasedEdge
bool startpoint : 1; bool startpoint : 1;
bool is_split : 1; bool is_split : 1;
TravelMode travel_mode : 4; TravelMode travel_mode : 4;
engine::guidance::RoadClassificationData road_classification; guidance::RoadClassificationData road_classification;
}; };
struct NodeBasedEdgeWithOSM : NodeBasedEdge struct NodeBasedEdgeWithOSM : NodeBasedEdge
@ -57,7 +57,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
bool startpoint, bool startpoint,
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
engine::guidance::RoadClassificationData road_classification); guidance::RoadClassificationData road_classification);
OSMNodeID osm_source_id; OSMNodeID osm_source_id;
OSMNodeID osm_target_id; OSMNodeID osm_target_id;
@ -70,7 +70,6 @@ inline NodeBasedEdge::NodeBasedEdge()
backward(false), roundabout(false), access_restricted(false), startpoint(true), backward(false), roundabout(false), access_restricted(false), startpoint(true),
is_split(false), travel_mode(false) is_split(false), travel_mode(false)
{ {
road_classification.invalidate();
} }
inline NodeBasedEdge::NodeBasedEdge(NodeID source, inline NodeBasedEdge::NodeBasedEdge(NodeID source,
@ -84,7 +83,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
bool startpoint, bool startpoint,
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
engine::guidance::RoadClassificationData road_classification) guidance::RoadClassificationData road_classification)
: source(source), target(target), name_id(name_id), weight(weight), forward(forward), : source(source), target(target), name_id(name_id), weight(weight), forward(forward),
backward(backward), roundabout(roundabout), access_restricted(access_restricted), backward(backward), roundabout(roundabout), access_restricted(access_restricted),
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode), startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
@ -121,7 +120,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(
bool startpoint, bool startpoint,
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
engine::guidance::RoadClassificationData road_classification) guidance::RoadClassificationData road_classification)
: NodeBasedEdge(SPECIAL_NODEID, : NodeBasedEdge(SPECIAL_NODEID,
SPECIAL_NODEID, SPECIAL_NODEID,
name_id, name_id,

View File

@ -2,7 +2,7 @@
#define ORIGINAL_EDGE_DATA_HPP #define ORIGINAL_EDGE_DATA_HPP
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <limits> #include <limits>
@ -16,7 +16,7 @@ struct OriginalEdgeData
{ {
explicit OriginalEdgeData(NodeID via_node, explicit OriginalEdgeData(NodeID via_node,
unsigned name_id, unsigned name_id,
engine::guidance::TurnInstruction turn_instruction, guidance::TurnInstruction turn_instruction,
TravelMode travel_mode) TravelMode travel_mode)
: via_node(via_node), name_id(name_id), turn_instruction(turn_instruction), : via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
travel_mode(travel_mode) travel_mode(travel_mode)
@ -26,14 +26,14 @@ struct OriginalEdgeData
OriginalEdgeData() OriginalEdgeData()
: via_node(std::numeric_limits<unsigned>::max()), : via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()),
turn_instruction(engine::guidance::TurnInstruction::INVALID()), turn_instruction(guidance::TurnInstruction::INVALID()),
travel_mode(TRAVEL_MODE_INACCESSIBLE) travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ {
} }
NodeID via_node; NodeID via_node;
unsigned name_id; unsigned name_id;
engine::guidance::TurnInstruction turn_instruction; guidance::TurnInstruction turn_instruction;
TravelMode travel_mode; TravelMode travel_mode;
}; };
} }

View File

@ -58,7 +58,9 @@ double bearing(const Coordinate first_coordinate, const Coordinate second_coordi
// Get angle of line segment (A,C)->(C,B) // Get angle of line segment (A,C)->(C,B)
double computeAngle(const Coordinate first, const Coordinate second, const Coordinate third); double computeAngle(const Coordinate first, const Coordinate second, const Coordinate third);
Coordinate interpolateLinear( double factor, const Coordinate from, const Coordinate to ); // factor in [0,1]. Returns point along the straight line between from and to. 0 returns from, 1
// returns to
Coordinate interpolateLinear(double factor, const Coordinate from, const Coordinate to);
namespace mercator namespace mercator
{ {

View File

@ -4,7 +4,7 @@
#include "util/dynamic_graph.hpp" #include "util/dynamic_graph.hpp"
#include "extractor/node_based_edge.hpp" #include "extractor/node_based_edge.hpp"
#include "util/graph_utils.hpp" #include "util/graph_utils.hpp"
#include "engine/guidance/classification_data.hpp" #include "extractor/guidance/classification_data.hpp"
#include <tbb/parallel_sort.h> #include <tbb/parallel_sort.h>
@ -46,13 +46,15 @@ struct NodeBasedEdgeData
bool roundabout : 1; bool roundabout : 1;
bool startpoint : 1; bool startpoint : 1;
extractor::TravelMode travel_mode : 4; extractor::TravelMode travel_mode : 4;
engine::guidance::RoadClassificationData road_classification; extractor::guidance::RoadClassificationData road_classification;
bool IsCompatibleTo(const NodeBasedEdgeData &other) const bool IsCompatibleTo(const NodeBasedEdgeData &other) const
{ {
//TODO roundabout/startpoint/access_restricted should all be part of this?? return (name_id == other.name_id) && (reversed == other.reversed) &&
return (reversed == other.reversed) && (name_id == other.name_id) && (roundabout == other.roundabout) && (startpoint == other.startpoint) &&
(travel_mode == other.travel_mode && road_classification == other.road_classification); (access_restricted == other.access_restricted) &&
(travel_mode == other.travel_mode) &&
(road_classification == other.road_classification);
} }
}; };

View File

@ -52,7 +52,7 @@ int Contractor::Run()
#ifdef WIN32 #ifdef WIN32
#pragma message("Memory consumption on Windows can be higher due to different bit packing") #pragma message("Memory consumption on Windows can be higher due to different bit packing")
#else #else
static_assert(sizeof(extractor::NodeBasedEdge) == 24, static_assert(sizeof(extractor::NodeBasedEdge) == 20,
"changing extractor::NodeBasedEdge type has influence on memory consumption!"); "changing extractor::NodeBasedEdge type has influence on memory consumption!");
static_assert(sizeof(extractor::EdgeBasedEdge) == 16, static_assert(sizeof(extractor::EdgeBasedEdge) == 16,
"changing EdgeBasedEdge type has influence on memory consumption!"); "changing EdgeBasedEdge type has influence on memory consumption!");

View File

@ -13,6 +13,10 @@
#include <iterator> #include <iterator>
#include <vector> #include <vector>
using TurnType = osrm::extractor::guidance::TurnType;
using DirectionModifier = osrm::extractor::guidance::DirectionModifier;
using TurnInstruction = osrm::extractor::guidance::TurnInstruction;
namespace osrm namespace osrm
{ {
namespace engine namespace engine
@ -24,14 +28,36 @@ namespace json
namespace detail namespace detail
{ {
std::string instructionTypeToString(guidance::TurnType type) const constexpr char *modifier_names[] = {"uturn", "sharp right", "right", "slight right",
"straight", "slight left", "left", "sharp left"};
// translations of TurnTypes. Not all types are exposed to the outside world.
// invalid types should never be returned as part of the API
const constexpr char *turn_type_names[] = {
"invalid", "no turn", "waypoint", "invalid", "new name", "continue",
"turn", "merge", "ramp", "fork", "end of road", "roundabout",
"invalid", "roundabout", "invalid", "traffic circle", "invalid", "traffic circle",
"invalid", "invalid", "restriction", "notification"};
// Check whether to include a modifier in the result of the API
inline bool isValidModifier(const TurnType type,
const DirectionModifier modifier)
{ {
return guidance::turn_type_names[static_cast<std::size_t>(type)]; if (type == TurnType::Location && modifier != DirectionModifier::Left &&
modifier != DirectionModifier::Straight &&
modifier != DirectionModifier::Right)
return false;
return true;
} }
std::string instructionModifierToString(guidance::DirectionModifier modifier) std::string instructionTypeToString(TurnType type)
{ {
return guidance::modifier_names[static_cast<std::size_t>(modifier)]; return turn_type_names[static_cast<std::size_t>(type)];
}
std::string instructionModifierToString(DirectionModifier modifier)
{
return modifier_names[static_cast<std::size_t>(modifier)];
} }
util::json::Array coordinateToLonLat(const util::Coordinate coordinate) util::json::Array coordinateToLonLat(const util::Coordinate coordinate)
@ -100,9 +126,9 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
{ {
util::json::Object step_maneuver; util::json::Object step_maneuver;
step_maneuver.values["type"] = detail::instructionTypeToString(maneuver.instruction.type); step_maneuver.values["type"] = detail::instructionTypeToString(maneuver.instruction.type);
if( guidance::isValidModifier( maneuver.instruction.type, maneuver.instruction.direction_modifier ) ) if (detail::isValidModifier(maneuver.instruction.type, maneuver.instruction.direction_modifier))
step_maneuver.values["modifier"] = step_maneuver.values["modifier"] =
detail::instructionModifierToString(maneuver.instruction.direction_modifier); detail::instructionModifierToString(maneuver.instruction.direction_modifier);
step_maneuver.values["location"] = detail::coordinateToLonLat(maneuver.location); step_maneuver.values["location"] = detail::coordinateToLonLat(maneuver.location);
step_maneuver.values["bearing_before"] = maneuver.bearing_before; step_maneuver.values["bearing_before"] = maneuver.bearing_before;
step_maneuver.values["bearing_after"] = maneuver.bearing_after; step_maneuver.values["bearing_after"] = maneuver.bearing_after;

View File

@ -1,23 +0,0 @@
#include "engine/guidance/classification_data.hpp"
#include <osmium/osm.hpp>
#include <iostream>
namespace osrm
{
namespace engine
{
namespace guidance
{
void RoadClassificationData::invalidate() { road_class = FunctionalRoadClass::UNKNOWN; }
void RoadClassificationData::augment(const osmium::Way &way)
{
const char *data = way.get_value_by_key("highway");
if (data)
road_class = functionalRoadClassFromTag(data);
}
} // namespace guidance
} // namespace engine
} // namespace osrm

View File

@ -1,10 +1,15 @@
#include "engine/guidance/post_processing.hpp" #include "engine/guidance/post_processing.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "engine/guidance/guidance_toolkit.hpp"
#include "engine/guidance/toolkit.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <iostream> #include <iostream>
using TurnInstruction = osrm::extractor::guidance::TurnInstruction;
using TurnType = osrm::extractor::guidance::TurnType;
using DirectionModifier = osrm::extractor::guidance::DirectionModifier;
namespace osrm namespace osrm
{ {
namespace engine namespace engine
@ -118,10 +123,11 @@ std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>
{ {
if (!on_roundabout) if (!on_roundabout)
{ {
BOOST_ASSERT(leg_data[0][0].turn_instruction.type == TurnInstruction::NO_TURN()); BOOST_ASSERT(leg_data[0][0].turn_instruction.type ==
if (path_data[data_index].turn_instruction.type == ExitRoundabout) TurnInstruction::NO_TURN());
if (path_data[data_index].turn_instruction.type == TurnType::ExitRoundabout)
leg_data[0][0].turn_instruction.type = TurnType::EnterRoundabout; leg_data[0][0].turn_instruction.type = TurnType::EnterRoundabout;
if (path_data[data_index].turn_instruction.type == ExitRotary) if (path_data[data_index].turn_instruction.type == TurnType::ExitRotary)
leg_data[0][0].turn_instruction.type = TurnType::EnterRotary; leg_data[0][0].turn_instruction.type = TurnType::EnterRotary;
path_data[data_index].exit += 1; path_data[data_index].exit += 1;
} }

View File

@ -140,9 +140,9 @@ InternalRouteResult TripPlugin::ComputeRoute(const std::vector<PhantomNode> &sna
{ {
uturns.resize(trip.size() + 1); uturns.resize(trip.size() + 1);
std::transform(trip.begin(), trip.end(), uturns.begin(), [&parameters](const NodeID idx) std::transform(trip.begin(), trip.end(), uturns.begin(), [&parameters](const NodeID idx)
{ {
return parameters.uturns[idx]; return parameters.uturns[idx];
}); });
BOOST_ASSERT(uturns.size() > 0); BOOST_ASSERT(uturns.size() > 0);
uturns.back() = parameters.uturns[trip.front()]; uturns.back() = parameters.uturns[trip.front()];
} }
@ -248,9 +248,9 @@ Status TripPlugin::HandleRequest(const api::TripParameters &parameters,
for (const auto &trip : trips) for (const auto &trip : trips)
{ {
routes.push_back(ComputeRoute(snapped_phantoms, parameters, trip)); routes.push_back(ComputeRoute(snapped_phantoms, parameters, trip));
ordered_coordinates.push_back( std::vector<util::Coordinate>() ); ordered_coordinates.push_back(std::vector<util::Coordinate>());
for( const auto nid : trip ) for (const auto nid : trip)
ordered_coordinates.back().push_back( parameters.coordinates[nid] ); ordered_coordinates.back().push_back(parameters.coordinates[nid]);
} }
api::TripAPI trip_api{BasePlugin::facade, parameters}; api::TripAPI trip_api{BasePlugin::facade, parameters};

View File

@ -1,6 +1,5 @@
#include "extractor/edge_based_edge.hpp" #include "extractor/edge_based_edge.hpp"
#include "extractor/edge_based_graph_factory.hpp" #include "extractor/edge_based_graph_factory.hpp"
#include "extractor/turn_analysis.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include "util/percent.hpp" #include "util/percent.hpp"
@ -10,8 +9,7 @@
#include "util/timing_util.hpp" #include "util/timing_util.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "engine/guidance/turn_classification.hpp" #include "extractor/guidance/toolkit.hpp"
#include "engine/guidance/guidance_toolkit.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
@ -307,56 +305,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
// Three nested loop look super-linear, but we are dealing with a (kind of) // Three nested loop look super-linear, but we are dealing with a (kind of)
// linear number of turns only. // linear number of turns only.
util::Percent progress(m_node_based_graph->GetNumberOfNodes()); util::Percent progress(m_node_based_graph->GetNumberOfNodes());
struct CompareTurnPossibilities
{
bool operator()(const std::vector<engine::guidance::TurnPossibility> &left,
const std::vector<engine::guidance::TurnPossibility> &right) const
{
if (left.size() < right.size())
return true;
if (left.size() > right.size())
return false;
for (std::size_t i = 0; i < left.size(); ++i)
{
if ((((int)left[i].angle + 16) % 256) / 32 <
(((int)right[i].angle + 16) % 256) / 32)
return true;
if ((((int)left[i].angle + 16) % 256) / 32 >
(((int)right[i].angle + 16) % 256) / 32)
return false;
}
return false;
}
};
// temporary switch to allow display of turn types
#define SHOW_TURN_TYPES 0
#if SHOW_TURN_TYPES
std::map<std::vector<engine::guidance::TurnPossibility>,
std::vector<util::FixedPointCoordinate>, CompareTurnPossibilities> turn_types;
#endif
for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes())) for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{ {
#if SHOW_TURN_TYPES
auto turn_possibilities = classifyIntersection(
node_u, *m_node_based_graph, m_compressed_edge_container, m_node_info_list);
if (turn_possibilities.empty())
continue;
auto set = turn_types.find(turn_possibilities);
if (set != turn_types.end())
{
if (set->second.size() < 5)
set->second.emplace_back(m_node_info_list[node_u].lat,
m_node_info_list[node_u].lon);
}
else
{
turn_types[turn_possibilities] = std::vector<util::FixedPointCoordinate>(
1, {m_node_info_list[node_u].lat, m_node_info_list[node_u].lon});
}
#endif
// progress.printStatus(node_u); // progress.printStatus(node_u);
for (const EdgeID edge_from_u : m_node_based_graph->GetAdjacentEdgeRange(node_u)) for (const EdgeID edge_from_u : m_node_based_graph->GetAdjacentEdgeRange(node_u))
{ {
@ -366,8 +316,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
} }
++node_based_edge_counter; ++node_based_edge_counter;
auto turn_candidates = turn_analysis::getTurns(node_u, edge_from_u, m_node_based_graph, m_node_info_list, m_restriction_map, m_barrier_nodes, auto turn_candidates = guidance::getTurns(
m_compressed_edge_container); node_u, edge_from_u, m_node_based_graph, m_node_info_list, m_restriction_map,
m_barrier_nodes, m_compressed_edge_container);
const NodeID node_v = m_node_based_graph->GetTarget(edge_from_u); const NodeID node_v = m_node_based_graph->GetTarget(edge_from_u);
@ -396,7 +347,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const int turn_penalty = GetTurnPenalty(turn_angle, lua_state); const int turn_penalty = GetTurnPenalty(turn_angle, lua_state);
const auto turn_instruction = turn.instruction; const auto turn_instruction = turn.instruction;
if (isUturn(turn_instruction)) if (guidance::isUturn(turn_instruction))
{ {
distance += speed_profile.u_turn_penalty; distance += speed_profile.u_turn_penalty;
} }
@ -471,21 +422,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
} }
} }
} }
#if SHOW_TURN_TYPES
std::cout << "[info] found " << turn_types.size() << " turn types." << std::endl;
for (const auto &tt : turn_types)
{
std::cout << tt.second.size();
for (auto coord : tt.second)
std::cout << " " << coord.lat << " " << coord.lon;
std::cout << " " << tt.first.size();
for (auto tte : tt.first)
std::cout << " " << (int)tte.angle;
std::cout << std::endl;
}
#endif
FlushVectorToStream(edge_data_file, original_edge_data_vector); FlushVectorToStream(edge_data_file, original_edge_data_vector);

View File

@ -188,7 +188,6 @@ int Extractor::run()
local_state, "way_function", local_state, "way_function",
boost::cref(static_cast<const osmium::Way &>(*entity)), boost::cref(static_cast<const osmium::Way &>(*entity)),
boost::ref(result_way)); boost::ref(result_way));
result_way.road_classification_data.augment(static_cast<const osmium::Way &>(*entity));
resulting_ways.push_back(std::make_pair(x, result_way)); resulting_ways.push_back(std::make_pair(x, result_way));
break; break;
case osmium::item_type::relation: case osmium::item_type::relation:

View File

@ -128,6 +128,14 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
return; return;
} }
// FIXME this need to be moved into the profiles
const char *data = input_way.get_value_by_key("highway");
guidance::RoadClassificationData road_classification;
if (data)
{
road_classification.road_class = guidance::functionalRoadClassFromTag(data);
}
// Get the unique identifier for the street name // Get the unique identifier for the street name
const auto &string_map_iterator = string_map.find(parsed_way.name); const auto &string_map_iterator = string_map.find(parsed_way.name);
unsigned name_id = external_memory.name_lengths.size(); unsigned name_id = external_memory.name_lengths.size();
@ -173,7 +181,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
name_id, backward_weight_data, true, false, name_id, backward_weight_data, true, false,
parsed_way.roundabout, parsed_way.is_access_restricted, parsed_way.roundabout, parsed_way.is_access_restricted,
parsed_way.is_startpoint, parsed_way.backward_travel_mode, parsed_way.is_startpoint, parsed_way.backward_travel_mode,
false,parsed_way.road_classification_data)); false, road_classification));
}); });
external_memory.way_start_end_id_list.push_back( external_memory.way_start_end_id_list.push_back(
@ -193,7 +201,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
name_id, forward_weight_data, true, !forward_only, name_id, forward_weight_data, true, !forward_only,
parsed_way.roundabout, parsed_way.is_access_restricted, parsed_way.roundabout, parsed_way.is_access_restricted,
parsed_way.is_startpoint, parsed_way.forward_travel_mode, parsed_way.is_startpoint, parsed_way.forward_travel_mode,
split_edge,parsed_way.road_classification_data)); split_edge, road_classification));
}); });
if (split_edge) if (split_edge)
{ {
@ -206,7 +214,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
OSMNodeID(first_node.ref()), OSMNodeID(last_node.ref()), name_id, OSMNodeID(first_node.ref()), OSMNodeID(last_node.ref()), name_id,
backward_weight_data, false, true, parsed_way.roundabout, backward_weight_data, false, true, parsed_way.roundabout,
parsed_way.is_access_restricted, parsed_way.is_startpoint, parsed_way.is_access_restricted, parsed_way.is_startpoint,
parsed_way.backward_travel_mode, true,parsed_way.road_classification_data)); parsed_way.backward_travel_mode, true, road_classification));
}); });
} }

View File

@ -1,4 +1,4 @@
#include "extractor/turn_analysis.hpp" #include "extractor/guidance/turn_analysis.hpp"
#include "util/simple_logger.hpp" #include "util/simple_logger.hpp"
@ -8,8 +8,7 @@ namespace osrm
{ {
namespace extractor namespace extractor
{ {
namespace guidance
namespace turn_analysis
{ {
// configuration of turn classification // configuration of turn classification
const bool constexpr INVERT = true; const bool constexpr INVERT = true;
@ -29,26 +28,6 @@ const unsigned constexpr INVALID_NAME_ID = 0;
using EdgeData = util::NodeBasedDynamicGraph::EdgeData; using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
using engine::guidance::TurnPossibility;
using engine::guidance::TurnInstruction;
using engine::guidance::DirectionModifier;
using engine::guidance::TurnType;
using engine::guidance::FunctionalRoadClass;
using engine::guidance::classifyIntersection;
using engine::guidance::isLowPriorityRoadClass;
using engine::guidance::angularDeviation;
using engine::guidance::getTurnDirection;
using engine::guidance::getRepresentativeCoordinate;
using engine::guidance::isBasic;
using engine::guidance::isRampClass;
using engine::guidance::isUturn;
using engine::guidance::isConflict;
using engine::guidance::isSlightTurn;
using engine::guidance::isSlightModifier;
using engine::guidance::mirrorDirectionModifier;
using engine::guidance::canBeSuppressed;
#define PRINT_DEBUG_CANDIDATES 0 #define PRINT_DEBUG_CANDIDATES 0
std::vector<TurnCandidate> std::vector<TurnCandidate>
getTurns(const NodeID from, getTurns(const NodeID from,
@ -419,7 +398,8 @@ handleFromMotorway(const NodeID from,
if (candidate.valid) if (candidate.valid)
{ {
BOOST_ASSERT(isRampClass(candidate.eid, node_based_graph)); BOOST_ASSERT(isRampClass(candidate.eid, node_based_graph));
candidate.instruction = TurnInstruction::SUPPRESSED(getTurnDirection(candidate.angle)); candidate.instruction =
TurnInstruction::SUPPRESSED(getTurnDirection(candidate.angle));
} }
} }
} }
@ -447,27 +427,26 @@ handleFromMotorway(const NodeID from,
if (candidate.angle == continue_angle) if (candidate.angle == continue_angle)
{ {
if (continues) if (continues)
candidate.instruction = TurnInstruction::SUPPRESSED(DirectionModifier::Straight); candidate.instruction =
TurnInstruction::SUPPRESSED(DirectionModifier::Straight);
else // TODO handle turn direction correctly else // TODO handle turn direction correctly
candidate.instruction = {TurnType::Merge, DirectionModifier::Straight}; candidate.instruction = {TurnType::Merge, DirectionModifier::Straight};
} }
else if (candidate.angle < continue_angle) else if (candidate.angle < continue_angle)
{ {
BOOST_ASSERT(isRampClass(node_based_graph->GetEdgeData(candidate.eid) candidate.instruction = {
.road_classification.road_class)); isRampClass(candidate.eid, node_based_graph) ? TurnType::Ramp
candidate.instruction = {TurnType::Ramp, : TurnType::Turn,
(candidate.angle < 145) (candidate.angle < 145) ? DirectionModifier::Right
? DirectionModifier::Right : DirectionModifier::SlightRight};
: DirectionModifier::SlightRight};
} }
else if (candidate.angle > continue_angle) else if (candidate.angle > continue_angle)
{ {
BOOST_ASSERT(isRampClass(node_based_graph->GetEdgeData(candidate.eid) candidate.instruction = {
.road_classification.road_class)); isRampClass(candidate.eid, node_based_graph) ? TurnType::Ramp
candidate.instruction = {TurnType::Ramp, : TurnType::Turn,
(candidate.angle > 215) (candidate.angle > 215) ? DirectionModifier::Left
? DirectionModifier::Left : DirectionModifier::SlightLeft};
: DirectionModifier::SlightLeft};
} }
} }
} }
@ -633,7 +612,8 @@ handleMotorwayJunction(const NodeID from,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
{ {
(void)from; (void)from;
BOOST_ASSERT(!turn_candidates[0].valid); // BOOST_ASSERT(!turn_candidates[0].valid); //This fails due to @themarex handling of dead end
// streets
const auto &in_data = node_based_graph->GetEdgeData(via_edge); const auto &in_data = node_based_graph->GetEdgeData(via_edge);
// coming from motorway // coming from motorway
@ -766,6 +746,7 @@ handleOneWayTurn(const NodeID from,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
{ {
BOOST_ASSERT(turn_candidates[0].angle < 0.001);
(void)from, (void)via_edge, (void)node_based_graph; (void)from, (void)via_edge, (void)node_based_graph;
if (!turn_candidates[0].valid) if (!turn_candidates[0].valid)
{ {
@ -773,8 +754,6 @@ handleOneWayTurn(const NodeID from,
<< "Graph Broken. Dead end without exit found or missing reverse edge."; << "Graph Broken. Dead end without exit found or missing reverse edge.";
} }
BOOST_ASSERT(turn_candidates[0].instruction.type == TurnType::Turn &&
turn_candidates[0].instruction.direction_modifier == DirectionModifier::UTurn);
#if PRINT_DEBUG_CANDIDATES #if PRINT_DEBUG_CANDIDATES
std::cout << "Basic (one) Turn Candidates:\n"; std::cout << "Basic (one) Turn Candidates:\n";
for (auto tc : turn_candidates) for (auto tc : turn_candidates)
@ -791,8 +770,7 @@ handleTwoWayTurn(const NodeID from,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
{ {
BOOST_ASSERT(turn_candidates[0].instruction.type == TurnType::Turn && BOOST_ASSERT(turn_candidates[0].angle < 0.001);
turn_candidates[0].instruction.direction_modifier == DirectionModifier::UTurn);
turn_candidates[1].instruction = turn_candidates[1].instruction =
getInstructionForObvious(from, via_edge, turn_candidates[1], node_based_graph); getInstructionForObvious(from, via_edge, turn_candidates[1], node_based_graph);
@ -813,6 +791,7 @@ handleThreeWayTurn(const NodeID from,
std::vector<TurnCandidate> turn_candidates, std::vector<TurnCandidate> turn_candidates,
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph) const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
{ {
BOOST_ASSERT(turn_candidates[0].angle < 0.001);
const auto isObviousOfTwo = [](const TurnCandidate turn, const TurnCandidate other) const auto isObviousOfTwo = [](const TurnCandidate turn, const TurnCandidate other)
{ {
return (angularDeviation(turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE && return (angularDeviation(turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
@ -971,7 +950,8 @@ handleThreeWayTurn(const NodeID from,
{ {
if (isObviousOfTwo(turn_candidates[1], turn_candidates[2])) if (isObviousOfTwo(turn_candidates[1], turn_candidates[2]))
{ {
turn_candidates[1].instruction = TurnInstruction::SUPPRESSED(DirectionModifier::Straight); turn_candidates[1].instruction =
TurnInstruction::SUPPRESSED(DirectionModifier::Straight);
} }
else else
{ {
@ -988,7 +968,8 @@ handleThreeWayTurn(const NodeID from,
{ {
if (isObviousOfTwo(turn_candidates[2], turn_candidates[1])) if (isObviousOfTwo(turn_candidates[2], turn_candidates[1]))
{ {
turn_candidates[2].instruction = TurnInstruction::SUPPRESSED(DirectionModifier::Straight); turn_candidates[2].instruction =
TurnInstruction::SUPPRESSED(DirectionModifier::Straight);
} }
else else
{ {
@ -1199,8 +1180,7 @@ optimizeCandidates(const EdgeID via_eid,
for (std::size_t turn_index = 0; turn_index < turn_candidates.size(); ++turn_index) for (std::size_t turn_index = 0; turn_index < turn_candidates.size(); ++turn_index)
{ {
auto &turn = turn_candidates[turn_index]; auto &turn = turn_candidates[turn_index];
if (!isBasic(turn.instruction.type) || isUturn(turn.instruction) || if (!isBasic(turn.instruction.type) || isUturn(turn.instruction))
isOnRoundabout(turn.instruction))
continue; continue;
auto &left = turn_candidates[getLeft(turn_index)]; auto &left = turn_candidates[getLeft(turn_index)];
if (turn.angle == left.angle) if (turn.angle == left.angle)
@ -1393,8 +1373,7 @@ bool isObviousChoice(const EdgeID via_eid,
node_based_graph->GetEdgeData(candidate.eid).road_classification.road_class)) node_based_graph->GetEdgeData(candidate.eid).road_classification.road_class))
{ {
bool is_only_normal_road = true; bool is_only_normal_road = true;
BOOST_ASSERT(turn_candidates[0].instruction.type == TurnType::Turn && // TODO find out why this can also be reached for non-u-turns
turn_candidates[0].instruction.direction_modifier == DirectionModifier::UTurn);
for (size_t i = 0; i < turn_candidates.size(); ++i) for (size_t i = 0; i < turn_candidates.size(); ++i)
{ {
if (i == turn_index || turn_candidates[i].angle == 0) // skip self and u-turn if (i == turn_index || turn_candidates[i].angle == 0) // skip self and u-turn
@ -1554,7 +1533,7 @@ suppressTurns(const EdgeID via_eid,
} }
else else
{ {
if (engine::guidance::canBeSuppressed(candidate.instruction.type)) if (canBeSuppressed(candidate.instruction.type))
candidate.instruction.type = TurnType::NewName; candidate.instruction.type = TurnType::NewName;
} }
} }
@ -1841,21 +1820,20 @@ handleConflicts(const NodeID from,
(void)from; (void)from;
(void)via_edge; (void)via_edge;
(void)node_based_graph; (void)node_based_graph;
const auto isConflict = []( const TurnCandidate &left, const TurnCandidate &right ) const auto isConflict = [](const TurnCandidate &left, const TurnCandidate &right)
{ {
// most obvious, same instructions conflict // most obvious, same instructions conflict
if( left.instruction == right.instruction ) if (left.instruction == right.instruction)
return true; return true;
return left.instruction.direction_modifier != DirectionModifier::UTurn && return left.instruction.direction_modifier != DirectionModifier::UTurn &&
left.instruction.direction_modifier == right.instruction.direction_modifier; left.instruction.direction_modifier == right.instruction.direction_modifier;
}; };
return turn_candidates; return turn_candidates;
} }
} // anemspace detail } // anemspace detail
} // namespace turn_analysis } // namespace guidance
} // namespace extractor } // namespace extractor
} // namespace osrm } // namespace osrm

View File

@ -8,7 +8,7 @@
#include "util/static_rtree.hpp" #include "util/static_rtree.hpp"
#include "engine/datafacade/datafacade_base.hpp" #include "engine/datafacade/datafacade_base.hpp"
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "engine/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "storage/storage.hpp" #include "storage/storage.hpp"
#include "storage/shared_datatype.hpp" #include "storage/shared_datatype.hpp"
#include "storage/shared_barriers.hpp" #include "storage/shared_barriers.hpp"
@ -225,7 +225,7 @@ int Storage::Run()
number_of_original_edges); number_of_original_edges);
shared_layout_ptr->SetBlockSize<extractor::TravelMode>(SharedDataLayout::TRAVEL_MODE, shared_layout_ptr->SetBlockSize<extractor::TravelMode>(SharedDataLayout::TRAVEL_MODE,
number_of_original_edges); number_of_original_edges);
shared_layout_ptr->SetBlockSize<engine::guidance::TurnInstruction>( shared_layout_ptr->SetBlockSize<extractor::guidance::TurnInstruction>(
SharedDataLayout::TURN_INSTRUCTION, number_of_original_edges); SharedDataLayout::TURN_INSTRUCTION, number_of_original_edges);
boost::filesystem::ifstream hsgr_input_stream(hsgr_path, std::ios::binary); boost::filesystem::ifstream hsgr_input_stream(hsgr_path, std::ios::binary);
@ -390,8 +390,8 @@ int Storage::Run()
shared_layout_ptr->GetBlockPtr<extractor::TravelMode, true>(shared_memory_ptr, shared_layout_ptr->GetBlockPtr<extractor::TravelMode, true>(shared_memory_ptr,
SharedDataLayout::TRAVEL_MODE); SharedDataLayout::TRAVEL_MODE);
engine::guidance::TurnInstruction *turn_instructions_ptr = extractor::guidance::TurnInstruction *turn_instructions_ptr =
shared_layout_ptr->GetBlockPtr<engine::guidance::TurnInstruction, true>( shared_layout_ptr->GetBlockPtr<extractor::guidance::TurnInstruction, true>(
shared_memory_ptr, SharedDataLayout::TURN_INSTRUCTION); shared_memory_ptr, SharedDataLayout::TURN_INSTRUCTION);
extractor::OriginalEdgeData current_edge_data; extractor::OriginalEdgeData current_edge_data;

View File

@ -260,10 +260,11 @@ double computeAngle(const Coordinate first, const Coordinate second, const Coord
Coordinate interpolateLinear(double factor, const Coordinate from, const Coordinate to) Coordinate interpolateLinear(double factor, const Coordinate from, const Coordinate to)
{ {
BOOST_ASSERT(0 <= factor && factor <= 1.0); BOOST_ASSERT(0 <= factor && factor <= 1.0);
return {from.lon + toFixed(FloatLongitude( return {
factor * static_cast<double>(toFloating(to.lon - from.lon)))), from.lon +
from.lat + toFixed(FloatLatitude( toFixed(FloatLongitude(factor * static_cast<double>(toFloating(to.lon - from.lon)))),
factor * static_cast<double>(toFloating(to.lat - from.lat))))}; from.lat +
toFixed(FloatLatitude(factor * static_cast<double>(toFloating(to.lat - from.lat))))};
} }
namespace mercator namespace mercator