clean-up guidance code/code in general

removes duplicated includes
removes unused includes
eliminates dedicated toolkits that resulted in circular dependencies
moves functionality close to data, where possible
This commit is contained in:
Moritz Kobitzsch 2016-12-02 10:53:22 +01:00
parent a28a20a1ba
commit df3c39cef5
54 changed files with 607 additions and 692 deletions

View File

@ -6,7 +6,6 @@
#include "engine/datafacade/datafacade_base.hpp" #include "engine/datafacade/datafacade_base.hpp"
#include "engine/guidance/leg_geometry.hpp" #include "engine/guidance/leg_geometry.hpp"
#include "engine/guidance/route_step.hpp" #include "engine/guidance/route_step.hpp"
#include "engine/guidance/toolkit.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.hpp" #include "util/coordinate.hpp"

View File

@ -8,14 +8,12 @@
#include "engine/guidance/leg_geometry.hpp" #include "engine/guidance/leg_geometry.hpp"
#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/toolkit.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/bearing.hpp" #include "util/bearing.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include "util/guidance/entry_class.hpp" #include "util/guidance/entry_class.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@ -156,7 +154,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
intersection.entry.push_back(entry_class.allowsEntry(idx)); intersection.entry.push_back(entry_class.allowsEntry(idx));
} }
std::int16_t bearing_in_driving_direction = std::int16_t bearing_in_driving_direction =
util::bearing::reverseBearing(std::round(bearings.first)); util::reverseBearing(std::round(bearings.first));
maneuver = {intersection.location, maneuver = {intersection.location,
bearing_in_driving_direction, bearing_in_driving_direction,
bearings.second, bearings.second,
@ -216,14 +214,13 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
BOOST_ASSERT(segment_index == number_of_segments - 1); BOOST_ASSERT(segment_index == number_of_segments - 1);
bearings = detail::getArriveBearings(leg_geometry); bearings = detail::getArriveBearings(leg_geometry);
intersection = { intersection = {target_node.location,
target_node.location, std::vector<short>({static_cast<short>(util::reverseBearing(bearings.first))}),
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}), std::vector<bool>({true}),
std::vector<bool>({true}), 0,
0, Intersection::NO_INDEX,
Intersection::NO_INDEX, util::guidance::LaneTuple(),
util::guidance::LaneTuple(), {}};
{}};
// 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
maneuver = {intersection.location, maneuver = {intersection.location,

View File

@ -0,0 +1,53 @@
#ifndef OSRM_ENGINE_GUIDANCE_POSTPROCESSING_TOOLKIT_HPP_
#define OSRM_ENGINE_GUIDANCE_POSTPROCESSING_TOOLKIT_HPP_
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/guidance/route_step.hpp"
#include <iterator>
#include <utility>
namespace osrm
{
namespace engine
{
namespace guidance
{
// Runs fn on RouteStep sub-ranges determined to be roundabouts.
// The function fn is getting called with a roundabout range as in: [enter, .., leave].
//
// The following situations are taken care for (i.e. we discard them):
// - partial roundabout: enter without exit or exit without enter
// - data issues: no roundabout, exit before enter
template <typename Iter, typename Fn> inline Fn forEachRoundabout(Iter first, Iter last, Fn fn)
{
while (first != last)
{
const auto enter = std::find_if(first, last, [](const RouteStep &step) {
return entersRoundabout(step.maneuver.instruction);
});
// enter has to come before leave, otherwise: faulty data / partial roundabout, skip those
const auto leave = std::find_if(enter, last, [](const RouteStep &step) {
return leavesRoundabout(step.maneuver.instruction);
});
// No roundabouts, or partial one (like start / end inside a roundabout)
if (enter == last || leave == last)
break;
(void)fn(std::make_pair(enter, leave));
// Skip to first step after the currently handled enter / leave pair
first = std::next(leave);
}
return fn;
}
} // namespace guidance
} // namespace engine
} // namespace osrm
#endif /* OSRM_ENGINE_GUIDANCE_POSTPROCESSING_TOOLKIT_HPP_ */

View File

@ -11,10 +11,11 @@
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/range/iterator_range.hpp>
namespace osrm namespace osrm
{ {
namespace engine namespace engine
@ -71,6 +72,33 @@ struct RouteStep
std::size_t geometry_begin; std::size_t geometry_begin;
std::size_t geometry_end; std::size_t geometry_end;
std::vector<Intersection> intersections; std::vector<Intersection> intersections;
LaneID numLanesToTheRight() const
{
return intersections.front().lanes.first_lane_from_the_right;
}
LaneID numLanesToTheLeft() const
{
LaneID const total = intersections.front().lane_description.size();
return total - (intersections.front().lanes.lanes_in_turn +
intersections.front().lanes.first_lane_from_the_right);
}
auto lanesToTheLeft() const
{
const auto &description = intersections.front().lane_description;
LaneID num_lanes_left = numLanesToTheLeft();
return boost::make_iterator_range(description.begin(),
description.begin() + num_lanes_left);
}
auto lanesToTheRight() const
{
const auto &description = intersections.front().lane_description;
LaneID num_lanes_right = numLanesToTheRight();
return boost::make_iterator_range(description.end() - num_lanes_right, description.end());
}
}; };
inline RouteStep getInvalidRouteStep() inline RouteStep getInvalidRouteStep()

View File

@ -1,108 +0,0 @@
#ifndef OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_
#define OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_
#include "extractor/guidance/turn_instruction.hpp"
#include "engine/guidance/route_step.hpp"
#include "util/bearing.hpp"
#include "util/guidance/toolkit.hpp"
#include <algorithm>
#include <iterator>
#include <utility>
namespace osrm
{
namespace engine
{
namespace guidance
{
using util::guidance::entersRoundabout;
using util::guidance::leavesRoundabout;
using util::guidance::staysOnRoundabout;
// 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 extractor::guidance::DirectionModifier::Enum 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;
}
// Runs fn on RouteStep sub-ranges determined to be roundabouts.
// The function fn is getting called with a roundabout range as in: [enter, .., leave].
//
// The following situations are taken care for (i.e. we discard them):
// - partial roundabout: enter without exit or exit without enter
// - data issues: no roundabout, exit before enter
template <typename Iter, typename Fn> inline Fn forEachRoundabout(Iter first, Iter last, Fn fn)
{
while (first != last)
{
const auto enter = std::find_if(first, last, [](const RouteStep &step) {
return entersRoundabout(step.maneuver.instruction);
});
// enter has to come before leave, otherwise: faulty data / partial roundabout, skip those
const auto leave = std::find_if(enter, last, [](const RouteStep &step) {
return leavesRoundabout(step.maneuver.instruction);
});
// No roundabouts, or partial one (like start / end inside a roundabout)
if (enter == last || leave == last)
break;
(void)fn(std::make_pair(enter, leave));
// Skip to first step after the currently handled enter / leave pair
first = std::next(leave);
}
return fn;
}
LaneID inline numLanesToTheRight(const engine::guidance::RouteStep &step)
{
return step.intersections.front().lanes.first_lane_from_the_right;
}
LaneID inline numLanesToTheLeft(const engine::guidance::RouteStep &step)
{
LaneID const total = step.intersections.front().lane_description.size();
return total - (step.intersections.front().lanes.lanes_in_turn +
step.intersections.front().lanes.first_lane_from_the_right);
}
auto inline lanesToTheLeft(const engine::guidance::RouteStep &step)
{
const auto &description = step.intersections.front().lane_description;
LaneID num_lanes_left = numLanesToTheLeft(step);
return boost::make_iterator_range(description.begin(), description.begin() + num_lanes_left);
}
auto inline lanesToTheRight(const engine::guidance::RouteStep &step)
{
const auto &description = step.intersections.front().lane_description;
LaneID num_lanes_right = numLanesToTheRight(step);
return boost::make_iterator_range(description.end() - num_lanes_right, description.end());
}
} // namespace guidance
} // namespace engine
} // namespace osrm
#endif /* OSRM_ENGINE_GUIDANCE_TOOLKIT_HPP_ */

View File

@ -3,7 +3,6 @@
#include "util/dist_table_wrapper.hpp" #include "util/dist_table_wrapper.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "util/typedefs.hpp"
#include "osrm/json_container.hpp" #include "osrm/json_container.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>

View File

@ -29,7 +29,6 @@
#include <memory> #include <memory>
#include <queue> #include <queue>
#include <string> #include <string>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>

View File

@ -12,7 +12,7 @@
#include <limits> #include <limits>
#include <string> #include <string>
#include "extractor/guidance/toolkit.hpp" #include "extractor/guidance/parsing_toolkit.hpp"
namespace osrm namespace osrm
{ {
@ -109,13 +109,13 @@ inline unsigned parseDuration(const std::string &s)
inline std::string inline std::string
trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right) trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right)
{ {
return extractor::guidance::trimLaneString(std::move(lane_string), count_left, count_right); return guidance::trimLaneString(std::move(lane_string), count_left, count_right);
} }
inline std::string applyAccessTokens(const std::string &lane_string, inline std::string applyAccessTokens(const std::string &lane_string,
const std::string &access_tokens) const std::string &access_tokens)
{ {
return extractor::guidance::applyAccessTokens(lane_string, access_tokens); return guidance::applyAccessTokens(lane_string, access_tokens);
} }
// Takes a string representing a list separated by delim and canonicalizes containing spaces. // Takes a string representing a list separated by delim and canonicalizes containing spaces.

View File

@ -11,7 +11,8 @@
#include "extractor/guidance/coordinate_extractor.hpp" #include "extractor/guidance/coordinate_extractor.hpp"
#include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include <boost/optional.hpp>
namespace osrm namespace osrm
{ {

View File

@ -9,7 +9,6 @@
#include "util/attributes.hpp" #include "util/attributes.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
namespace osrm namespace osrm

View File

@ -7,7 +7,6 @@
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" // EdgeID #include "util/typedefs.hpp" // EdgeID
@ -29,16 +28,15 @@ struct IntersectionShapeData
inline auto makeCompareShapeDataByBearing(const double base_bearing) inline auto makeCompareShapeDataByBearing(const double base_bearing)
{ {
return [base_bearing](const auto &lhs, const auto &rhs) { return [base_bearing](const auto &lhs, const auto &rhs) {
return util::bearing::angleBetweenBearings(base_bearing, lhs.bearing) < return util::angleBetweenBearings(base_bearing, lhs.bearing) <
util::bearing::angleBetweenBearings(base_bearing, rhs.bearing); util::angleBetweenBearings(base_bearing, rhs.bearing);
}; };
} }
inline auto makeCompareAngularDeviation(const double angle) inline auto makeCompareAngularDeviation(const double angle)
{ {
return [angle](const auto &lhs, const auto &rhs) { return [angle](const auto &lhs, const auto &rhs) {
return util::guidance::angularDeviation(lhs.angle, angle) < return util::angularDeviation(lhs.angle, angle) < util::angularDeviation(rhs.angle, angle);
util::guidance::angularDeviation(rhs.angle, angle);
}; };
} }

View File

@ -43,6 +43,7 @@ class IntersectionGenerator
* The shape also only comes with turn bearings, not with turn angles. All turn angles will be * The shape also only comes with turn bearings, not with turn angles. All turn angles will be
* set to zero * set to zero
*/ */
OSRM_ATTR_WARN_UNUSED
IntersectionShape IntersectionShape
ComputeIntersectionShape(const NodeID center_node, ComputeIntersectionShape(const NodeID center_node,
const boost::optional<NodeID> sorting_base = boost::none, const boost::optional<NodeID> sorting_base = boost::none,
@ -53,11 +54,11 @@ class IntersectionGenerator
// intermediate intersection, if there is a traffic light in between. If we want to look farther // intermediate intersection, if there is a traffic light in between. If we want to look farther
// down a road, finding the next actual decision requires the look at multiple intersections. // down a road, finding the next actual decision requires the look at multiple intersections.
// Here we follow the road until we either reach a dead end or find the next intersection with // Here we follow the road until we either reach a dead end or find the next intersection with
// more than a single next road. // more than a single next road. This function skips over degree two nodes to find coorect input
IntersectionView GetActualNextIntersection(const NodeID starting_node, // for GetConnectedRoads.
const EdgeID via_edge, OSRM_ATTR_WARN_UNUSED
NodeID *resulting_from_node, std::pair<NodeID, EdgeID> SkipDegreeTwoNodes(const NodeID starting_node,
EdgeID *resulting_via_edge) const; const EdgeID via_edge) const;
// Allow access to the coordinate extractor for all owners // Allow access to the coordinate extractor for all owners
const CoordinateExtractor &GetCoordinateExtractor() const; const CoordinateExtractor &GetCoordinateExtractor() const;

View File

@ -3,8 +3,6 @@
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"

View File

@ -0,0 +1,112 @@
#ifndef OSRM_GUIDANCE_PARSING_TOOLKIT_HPP_
#define OSRM_GUIDANCE_PARSING_TOOLKIT_HPP_
#include <cstdint>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>
#include "util/attributes.hpp"
namespace osrm
{
namespace extractor
{
namespace guidance
{
// Public service vehicle lanes and similar can introduce additional lanes into the lane string that
// are not specifically marked for left/right turns. This function can be used from the profile to
// trim the lane string appropriately
//
// left|throught|
// in combination with lanes:psv:forward=1
// will be corrected to left|throught, since the final lane is not drivable.
// This is in contrast to a situation with lanes:psv:forward=0 (or not set) where left|through|
// represents left|through|through
OSRM_ATTR_WARN_UNUSED
inline std::string
trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right)
{
if (count_left)
{
bool sane = count_left < static_cast<std::int32_t>(lane_string.size());
for (std::int32_t i = 0; i < count_left; ++i)
// this is adjusted for our fake pipe. The moment cucumber can handle multiple escaped
// pipes, the '&' part can be removed
if (lane_string[i] != '|')
{
sane = false;
break;
}
if (sane)
{
lane_string.erase(lane_string.begin(), lane_string.begin() + count_left);
}
}
if (count_right)
{
bool sane = count_right < static_cast<std::int32_t>(lane_string.size());
for (auto itr = lane_string.rbegin();
itr != lane_string.rend() && itr != lane_string.rbegin() + count_right;
++itr)
{
if (*itr != '|')
{
sane = false;
break;
}
}
if (sane)
lane_string.resize(lane_string.size() - count_right);
}
return lane_string;
}
// https://github.com/Project-OSRM/osrm-backend/issues/2638
// It can happen that some lanes are not drivable by car. Here we handle this tagging scheme
// (vehicle:lanes) to filter out not-allowed roads
// lanes=3
// turn:lanes=left|through|through|right
// vehicle:lanes=yes|yes|no|yes
// bicycle:lanes=yes|no|designated|yes
OSRM_ATTR_WARN_UNUSED
inline std::string applyAccessTokens(std::string lane_string, const std::string &access_tokens)
{
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
tokenizer tokens(lane_string, sep);
tokenizer access(access_tokens, sep);
// strings don't match, don't do anything
if (std::distance(std::begin(tokens), std::end(tokens)) !=
std::distance(std::begin(access), std::end(access)))
return lane_string;
std::string result_string = "";
const static std::string yes = "yes";
for (auto token_itr = std::begin(tokens), access_itr = std::begin(access);
token_itr != std::end(tokens);
++token_itr, ++access_itr)
{
if (*access_itr == yes)
{
// we have to add this in front, because the next token could be invalid. Doing this on
// non-empty strings makes sure that the token string will be valid in the end
if (!result_string.empty())
result_string += '|';
result_string += *token_itr;
}
}
return result_string;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm
#endif // OSRM_GUIDANCE_PARSING_TOOLKIT_HPP_

View File

@ -4,9 +4,8 @@
#include <cmath> #include <cmath>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <unordered_map>
#include <osmium/osm.hpp> #include "extractor/guidance/constants.hpp"
namespace osrm namespace osrm
{ {
@ -126,6 +125,22 @@ inline bool canBeSeenAsFork(const RoadClassification first, const RoadClassifica
return std::abs(static_cast<int>(first.GetPriority()) - return std::abs(static_cast<int>(first.GetPriority()) -
static_cast<int>(second.GetPriority())) <= 1; static_cast<int>(second.GetPriority())) <= 1;
} }
inline bool obviousByRoadClass(const RoadClassification in_classification,
const RoadClassification obvious_candidate,
const RoadClassification compare_candidate)
{
// lower numbers are of higher priority
const bool has_high_priority = PRIORITY_DISTINCTION_FACTOR * obvious_candidate.GetPriority() <
compare_candidate.GetPriority();
const bool continues_on_same_class = in_classification == obvious_candidate;
return (has_high_priority && continues_on_same_class) ||
(!obvious_candidate.IsLowPriorityRoadClass() &&
!in_classification.IsLowPriorityRoadClass() &&
compare_candidate.IsLowPriorityRoadClass());
}
} // namespace guidance } // namespace guidance
} // namespace extractor } // namespace extractor
} // namespace osrm } // namespace osrm

View File

@ -15,7 +15,6 @@
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <unordered_set> #include <unordered_set>
#include <utility>
#include <vector> #include <vector>
namespace osrm namespace osrm

View File

@ -9,8 +9,6 @@
#include "util/name_table.hpp" #include "util/name_table.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include <cstddef>
#include <utility>
#include <vector> #include <vector>
namespace osrm namespace osrm

View File

@ -1,241 +0,0 @@
#ifndef OSRM_GUIDANCE_TOOLKIT_HPP_
#define OSRM_GUIDANCE_TOOLKIT_HPP_
#include "util/attributes.hpp"
#include "util/bearing.hpp"
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/guidance/turn_lanes.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/query_node.hpp"
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/road_classification.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/functional/hash.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/tokenizer.hpp>
namespace osrm
{
namespace extractor
{
namespace guidance
{
using util::guidance::LaneTupleIdPair;
using LaneDataIdMap = std::unordered_map<LaneTupleIdPair, LaneDataID, boost::hash<LaneTupleIdPair>>;
using util::guidance::angularDeviation;
using util::guidance::entersRoundabout;
using util::guidance::leavesRoundabout;
// To simplify handling of Left/Right hand turns, we can mirror turns and write an intersection
// handler only for one side. The mirror function turns a left-hand turn in a equivalent right-hand
// turn and vice versa.
inline bool hasRoundaboutType(const TurnInstruction instruction)
{
using namespace extractor::guidance::TurnType;
const constexpr TurnType::Enum valid_types[] = {TurnType::EnterRoundabout,
TurnType::EnterAndExitRoundabout,
TurnType::EnterRotary,
TurnType::EnterAndExitRotary,
TurnType::EnterRoundaboutIntersection,
TurnType::EnterAndExitRoundaboutIntersection,
TurnType::EnterRoundaboutAtExit,
TurnType::ExitRoundabout,
TurnType::EnterRotaryAtExit,
TurnType::ExitRotary,
TurnType::EnterRoundaboutIntersectionAtExit,
TurnType::ExitRoundaboutIntersection,
TurnType::StayOnRoundabout};
const auto *first = valid_types;
const auto *last = first + sizeof(valid_types) / sizeof(valid_types[0]);
return std::find(first, last, instruction.type) != last;
}
// Public service vehicle lanes and similar can introduce additional lanes into the lane string that
// are not specifically marked for left/right turns. This function can be used from the profile to
// trim the lane string appropriately
//
// left|throught|
// in combination with lanes:psv:forward=1
// will be corrected to left|throught, since the final lane is not drivable.
// This is in contrast to a situation with lanes:psv:forward=0 (or not set) where left|through|
// represents left|through|through
OSRM_ATTR_WARN_UNUSED
inline std::string
trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t count_right)
{
if (count_left)
{
bool sane = count_left < static_cast<std::int32_t>(lane_string.size());
for (std::int32_t i = 0; i < count_left; ++i)
// this is adjusted for our fake pipe. The moment cucumber can handle multiple escaped
// pipes, the '&' part can be removed
if (lane_string[i] != '|')
{
sane = false;
break;
}
if (sane)
{
lane_string.erase(lane_string.begin(), lane_string.begin() + count_left);
}
}
if (count_right)
{
bool sane = count_right < static_cast<std::int32_t>(lane_string.size());
for (auto itr = lane_string.rbegin();
itr != lane_string.rend() && itr != lane_string.rbegin() + count_right;
++itr)
{
if (*itr != '|')
{
sane = false;
break;
}
}
if (sane)
lane_string.resize(lane_string.size() - count_right);
}
return lane_string;
}
// https://github.com/Project-OSRM/osrm-backend/issues/2638
// It can happen that some lanes are not drivable by car. Here we handle this tagging scheme
// (vehicle:lanes) to filter out not-allowed roads
// lanes=3
// turn:lanes=left|through|through|right
// vehicle:lanes=yes|yes|no|yes
// bicycle:lanes=yes|no|designated|yes
OSRM_ATTR_WARN_UNUSED
inline std::string applyAccessTokens(std::string lane_string, const std::string &access_tokens)
{
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
tokenizer tokens(lane_string, sep);
tokenizer access(access_tokens, sep);
// strings don't match, don't do anything
if (std::distance(std::begin(tokens), std::end(tokens)) !=
std::distance(std::begin(access), std::end(access)))
return lane_string;
std::string result_string = "";
const static std::string yes = "yes";
for (auto token_itr = std::begin(tokens), access_itr = std::begin(access);
token_itr != std::end(tokens);
++token_itr, ++access_itr)
{
if (*access_itr == yes)
{
// we have to add this in front, because the next token could be invalid. Doing this on
// non-empty strings makes sure that the token string will be valid in the end
if (!result_string.empty())
result_string += '|';
result_string += *token_itr;
}
}
return result_string;
}
inline bool obviousByRoadClass(const RoadClassification in_classification,
const RoadClassification obvious_candidate,
const RoadClassification compare_candidate)
{
// lower numbers are of higher priority
const bool has_high_priority = PRIORITY_DISTINCTION_FACTOR * obvious_candidate.GetPriority() <
compare_candidate.GetPriority();
const bool continues_on_same_class = in_classification == obvious_candidate;
return (has_high_priority && continues_on_same_class) ||
(!obvious_candidate.IsLowPriorityRoadClass() &&
!in_classification.IsLowPriorityRoadClass() &&
compare_candidate.IsLowPriorityRoadClass());
}
/* We use the sum of least squares to calculate a linear regression through our
* coordinates.
* This regression gives a good idea of how the road can be perceived and corrects for
* initial and final corrections
*/
inline std::pair<util::Coordinate, util::Coordinate>
leastSquareRegression(const std::vector<util::Coordinate> &coordinates)
{
BOOST_ASSERT(coordinates.size() >= 2);
double sum_lon = 0, sum_lat = 0, sum_lon_lat = 0, sum_lon_lon = 0;
double min_lon = static_cast<double>(toFloating(coordinates.front().lon));
double max_lon = static_cast<double>(toFloating(coordinates.front().lon));
for (const auto coord : coordinates)
{
min_lon = std::min(min_lon, static_cast<double>(toFloating(coord.lon)));
max_lon = std::max(max_lon, static_cast<double>(toFloating(coord.lon)));
sum_lon += static_cast<double>(toFloating(coord.lon));
sum_lon_lon +=
static_cast<double>(toFloating(coord.lon)) * static_cast<double>(toFloating(coord.lon));
sum_lat += static_cast<double>(toFloating(coord.lat));
sum_lon_lat +=
static_cast<double>(toFloating(coord.lon)) * static_cast<double>(toFloating(coord.lat));
}
const auto dividend = coordinates.size() * sum_lon_lat - sum_lon * sum_lat;
const auto divisor = coordinates.size() * sum_lon_lon - sum_lon * sum_lon;
if (std::abs(divisor) < std::numeric_limits<double>::epsilon())
return std::make_pair(coordinates.front(), coordinates.back());
// slope of the regression line
const auto slope = dividend / divisor;
const auto intercept = (sum_lat - slope * sum_lon) / coordinates.size();
const auto GetLatAtLon = [intercept,
slope](const util::FloatLongitude longitude) -> util::FloatLatitude {
return {intercept + slope * static_cast<double>((longitude))};
};
const util::Coordinate regression_first = {
toFixed(util::FloatLongitude{min_lon - 1}),
toFixed(util::FloatLatitude(GetLatAtLon(util::FloatLongitude{min_lon - 1})))};
const util::Coordinate regression_end = {
toFixed(util::FloatLongitude{max_lon + 1}),
toFixed(util::FloatLatitude(GetLatAtLon(util::FloatLongitude{max_lon + 1})))};
return {regression_first, regression_end};
}
inline std::uint8_t getLaneCountAtIntersection(const NodeID intersection_node,
const util::NodeBasedDynamicGraph &node_based_graph)
{
std::uint8_t lanes = 0;
for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(intersection_node))
lanes = std::max(
lanes, node_based_graph.GetEdgeData(onto_edge).road_classification.GetNumberOfLanes());
return lanes;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm
#endif // OSRM_GUIDANCE_TOOLKIT_HPP_

View File

@ -8,7 +8,6 @@
#include "extractor/guidance/motorway_handler.hpp" #include "extractor/guidance/motorway_handler.hpp"
#include "extractor/guidance/roundabout_handler.hpp" #include "extractor/guidance/roundabout_handler.hpp"
#include "extractor/guidance/sliproad_handler.hpp" #include "extractor/guidance/sliproad_handler.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_classification.hpp" #include "extractor/guidance/turn_classification.hpp"
#include "extractor/guidance/turn_handler.hpp" #include "extractor/guidance/turn_handler.hpp"
#include "extractor/query_node.hpp" #include "extractor/query_node.hpp"

View File

@ -1,21 +1,12 @@
#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 "extractor/compressed_edge_container.hpp"
#include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/query_node.hpp"
#include "util/coordinate.hpp"
#include "util/guidance/bearing_class.hpp" #include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp" #include "util/guidance/entry_class.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
#include <algorithm>
#include <cstddef>
#include <utility> #include <utility>
#include <vector>
namespace osrm namespace osrm
{ {

View File

@ -5,8 +5,6 @@
#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_generator.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <string>
namespace osrm namespace osrm
{ {
namespace extractor namespace extractor

View File

@ -1,11 +1,11 @@
#ifndef OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_ #ifndef OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_
#define OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_ #define OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_
#include <algorithm>
#include <cstdint> #include <cstdint>
#include <boost/assert.hpp>
#include "extractor/guidance/roundabout_type.hpp" #include "extractor/guidance/roundabout_type.hpp"
#include "util/attributes.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
namespace osrm namespace osrm
@ -150,6 +150,162 @@ 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;
} }
// check if a instruction is associated in any form with a roundabout
inline bool hasRoundaboutType(const TurnInstruction instruction)
{
using namespace extractor::guidance::TurnType;
const constexpr TurnType::Enum valid_types[] = {TurnType::EnterRoundabout,
TurnType::EnterAndExitRoundabout,
TurnType::EnterRotary,
TurnType::EnterAndExitRotary,
TurnType::EnterRoundaboutIntersection,
TurnType::EnterAndExitRoundaboutIntersection,
TurnType::EnterRoundaboutAtExit,
TurnType::ExitRoundabout,
TurnType::EnterRotaryAtExit,
TurnType::ExitRotary,
TurnType::EnterRoundaboutIntersectionAtExit,
TurnType::ExitRoundaboutIntersection,
TurnType::StayOnRoundabout};
const auto *first = valid_types;
const auto *last = first + sizeof(valid_types) / sizeof(valid_types[0]);
return std::find(first, last, instruction.type) != last;
}
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::EnterRoundaboutIntersection ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRotaryAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersectionAtExit ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundaboutIntersection);
}
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::ExitRoundaboutIntersection ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundaboutIntersection);
}
inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruction)
{
return instruction.type == extractor::guidance::TurnType::StayOnRoundabout;
}
// 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 hasRampType(const extractor::guidance::TurnInstruction instruction)
{
return instruction.type == extractor::guidance::TurnType::OffRamp ||
instruction.type == extractor::guidance::TurnType::OnRamp;
}
inline extractor::guidance::DirectionModifier::Enum getTurnDirection(const double angle)
{
// An angle of zero is a u-turn
// 180 goes perfectly straight
// 0-180 are right turns
// 180-360 are left turns
if (angle > 0 && angle < 60)
return extractor::guidance::DirectionModifier::SharpRight;
if (angle >= 60 && angle < 140)
return extractor::guidance::DirectionModifier::Right;
if (angle >= 140 && angle < 160)
return extractor::guidance::DirectionModifier::SlightRight;
if (angle >= 160 && angle <= 200)
return extractor::guidance::DirectionModifier::Straight;
if (angle > 200 && angle <= 220)
return extractor::guidance::DirectionModifier::SlightLeft;
if (angle > 220 && angle <= 300)
return extractor::guidance::DirectionModifier::Left;
if (angle > 300 && angle < 360)
return extractor::guidance::DirectionModifier::SharpLeft;
return extractor::guidance::DirectionModifier::UTurn;
}
// swaps left <-> right modifier types
OSRM_ATTR_WARN_UNUSED
inline extractor::guidance::DirectionModifier::Enum
mirrorDirectionModifier(const extractor::guidance::DirectionModifier::Enum modifier)
{
const constexpr extractor::guidance::DirectionModifier::Enum results[] = {
extractor::guidance::DirectionModifier::UTurn,
extractor::guidance::DirectionModifier::SharpLeft,
extractor::guidance::DirectionModifier::Left,
extractor::guidance::DirectionModifier::SlightLeft,
extractor::guidance::DirectionModifier::Straight,
extractor::guidance::DirectionModifier::SlightRight,
extractor::guidance::DirectionModifier::Right,
extractor::guidance::DirectionModifier::SharpRight};
return results[modifier];
}
inline bool hasLeftModifier(const extractor::guidance::TurnInstruction instruction)
{
return instruction.direction_modifier == extractor::guidance::DirectionModifier::SharpLeft ||
instruction.direction_modifier == extractor::guidance::DirectionModifier::Left ||
instruction.direction_modifier == extractor::guidance::DirectionModifier::SlightLeft;
}
inline bool hasRightModifier(const extractor::guidance::TurnInstruction instruction)
{
return instruction.direction_modifier == extractor::guidance::DirectionModifier::SharpRight ||
instruction.direction_modifier == extractor::guidance::DirectionModifier::Right ||
instruction.direction_modifier == extractor::guidance::DirectionModifier::SlightRight;
}
inline bool isLeftTurn(const extractor::guidance::TurnInstruction instruction)
{
switch (instruction.type)
{
case TurnType::Merge:
return hasRightModifier(instruction);
default:
return hasLeftModifier(instruction);
}
}
inline bool isRightTurn(const extractor::guidance::TurnInstruction instruction)
{
switch (instruction.type)
{
case TurnType::Merge:
return hasLeftModifier(instruction);
default:
return hasRightModifier(instruction);
}
}
inline DirectionModifier::Enum bearingToDirectionModifier(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 guidance
} // namespace extractor } // namespace extractor
} // namespace osrm } // namespace osrm

View File

@ -4,7 +4,6 @@
#include "extractor/guidance/turn_lane_types.hpp" #include "extractor/guidance/turn_lane_types.hpp"
#include "util/attributes.hpp" #include "util/attributes.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <string>
#include <vector> #include <vector>
namespace osrm namespace osrm

View File

@ -2,7 +2,6 @@
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_HANDLER_HPP_ #define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_HANDLER_HPP_
#include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_analysis.hpp" #include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/turn_lane_data.hpp" #include "extractor/guidance/turn_lane_data.hpp"
#include "extractor/guidance/turn_lane_types.hpp" #include "extractor/guidance/turn_lane_types.hpp"
@ -74,7 +73,7 @@ class TurnLaneHandler
std::vector<TurnLaneType::Mask> &turn_lane_masks, std::vector<TurnLaneType::Mask> &turn_lane_masks,
LaneDescriptionMap &lane_description_map, LaneDescriptionMap &lane_description_map,
const TurnAnalysis &turn_analysis, const TurnAnalysis &turn_analysis,
LaneDataIdMap &id_map); util::guidance::LaneDataIdMap &id_map);
~TurnLaneHandler(); ~TurnLaneHandler();
@ -91,7 +90,7 @@ class TurnLaneHandler
std::vector<TurnLaneType::Mask> &turn_lane_masks; std::vector<TurnLaneType::Mask> &turn_lane_masks;
LaneDescriptionMap &lane_description_map; LaneDescriptionMap &lane_description_map;
const TurnAnalysis &turn_analysis; const TurnAnalysis &turn_analysis;
LaneDataIdMap &id_map; util::guidance::LaneDataIdMap &id_map;
// Find out which scenario we have to handle // Find out which scenario we have to handle
TurnLaneScenario deduceScenario(const NodeID at, TurnLaneScenario deduceScenario(const NodeID at,

View File

@ -2,7 +2,6 @@
#define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_MATCHER_HPP_ #define OSRM_EXTRACTOR_GUIDANCE_TURN_LANE_MATCHER_HPP_
#include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "extractor/guidance/turn_lane_data.hpp" #include "extractor/guidance/turn_lane_data.hpp"
@ -10,8 +9,6 @@
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include <unordered_map>
namespace osrm namespace osrm
{ {
namespace extractor namespace extractor
@ -47,7 +44,7 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
const LaneDataVector &lane_data, const LaneDataVector &lane_data,
const util::NodeBasedDynamicGraph &node_based_graph, const util::NodeBasedDynamicGraph &node_based_graph,
const LaneDescriptionID lane_string_id, const LaneDescriptionID lane_string_id,
LaneDataIdMap &lane_data_to_id); util::guidance::LaneDataIdMap &lane_data_to_id);
} // namespace lanes } // namespace lanes
} // namespace guidance } // namespace guidance

View File

@ -8,11 +8,9 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <boost/assert.hpp>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include "util/json_container.hpp" #include "util/json_container.hpp"
#include "util/log.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
namespace osrm namespace osrm

View File

@ -1,7 +1,9 @@
#ifndef BEARING_HPP #ifndef BEARING_HPP
#define BEARING_HPP #define BEARING_HPP
#include <algorithm>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <cmath>
#include <string> #include <string>
namespace osrm namespace osrm
@ -89,6 +91,7 @@ inline bool CheckInBounds(const int A, const int B, const int range)
return normalized_B - range <= normalized_A && normalized_A <= normalized_B + range; return normalized_B - range <= normalized_A && normalized_A <= normalized_B + range;
} }
} }
} // namespace bearing
inline double reverseBearing(const double bearing) inline double reverseBearing(const double bearing)
{ {
@ -128,7 +131,13 @@ inline double angleBetweenBearings(const double entry_bearing, const double exit
return angle >= 360 ? angle - 360 : angle; return angle >= 360 ? angle - 360 : angle;
} }
} // namespace bearing // minimal difference between two angles/bearings going left or right
inline double angularDeviation(const double angle, const double from)
{
const double deviation = std::abs(angle - from);
return std::min(360 - deviation, deviation);
}
} // namespace util } // namespace util
} // namespace osrm } // namespace osrm

View File

@ -136,6 +136,9 @@ bool isCCW(const Coordinate first_coordinate,
const Coordinate second_coordinate, const Coordinate second_coordinate,
const Coordinate third_coordinate); const Coordinate third_coordinate);
std::pair<util::Coordinate, util::Coordinate>
leastSquareRegression(const std::vector<util::Coordinate> &coordinates);
} // ns coordinate_calculation } // ns coordinate_calculation
} // ns util } // ns util
} // ns osrm } // ns osrm

View File

@ -1,26 +1,20 @@
#ifndef OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ #ifndef OSRM_UTIL_GUIDANCE_NAME_ANNOUNCEMENT_HPP_
#define OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ #define OSRM_UTIL_GUIDANCE_NAME_ANNOUNCEMENT_HPP_
/* A set of tools required for guidance in both pre and post-processing */ /* A set of tools required for guidance in both pre and post-processing */
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/suffix_table.hpp" #include "extractor/suffix_table.hpp"
#include "engine/guidance/route_step.hpp"
#include "engine/phantom_node.hpp"
#include "util/attributes.hpp" #include "util/attributes.hpp"
#include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp"
#include "util/log.hpp"
#include "util/name_table.hpp" #include "util/name_table.hpp"
#include "util/typedefs.hpp"
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/functional/hash.hpp>
namespace osrm namespace osrm
{ {
@ -29,122 +23,6 @@ namespace util
namespace guidance namespace guidance
{ {
inline double angularDeviation(const double angle, const double from)
{
const double deviation = std::abs(angle - from);
return std::min(360 - deviation, deviation);
}
inline bool hasRampType(const extractor::guidance::TurnInstruction instruction)
{
return instruction.type == extractor::guidance::TurnType::OffRamp ||
instruction.type == extractor::guidance::TurnType::OnRamp;
}
inline extractor::guidance::DirectionModifier::Enum getTurnDirection(const double angle)
{
// An angle of zero is a u-turn
// 180 goes perfectly straight
// 0-180 are right turns
// 180-360 are left turns
if (angle > 0 && angle < 60)
return extractor::guidance::DirectionModifier::SharpRight;
if (angle >= 60 && angle < 140)
return extractor::guidance::DirectionModifier::Right;
if (angle >= 140 && angle < 160)
return extractor::guidance::DirectionModifier::SlightRight;
if (angle >= 160 && angle <= 200)
return extractor::guidance::DirectionModifier::Straight;
if (angle > 200 && angle <= 220)
return extractor::guidance::DirectionModifier::SlightLeft;
if (angle > 220 && angle <= 300)
return extractor::guidance::DirectionModifier::Left;
if (angle > 300 && angle < 360)
return extractor::guidance::DirectionModifier::SharpLeft;
return extractor::guidance::DirectionModifier::UTurn;
}
// swaps left <-> right modifier types
OSRM_ATTR_WARN_UNUSED
inline extractor::guidance::DirectionModifier::Enum
mirrorDirectionModifier(const extractor::guidance::DirectionModifier::Enum modifier)
{
const constexpr extractor::guidance::DirectionModifier::Enum results[] = {
extractor::guidance::DirectionModifier::UTurn,
extractor::guidance::DirectionModifier::SharpLeft,
extractor::guidance::DirectionModifier::Left,
extractor::guidance::DirectionModifier::SlightLeft,
extractor::guidance::DirectionModifier::Straight,
extractor::guidance::DirectionModifier::SlightRight,
extractor::guidance::DirectionModifier::Right,
extractor::guidance::DirectionModifier::SharpRight};
return results[modifier];
}
inline bool hasLeftModifier(const extractor::guidance::TurnInstruction instruction)
{
return instruction.direction_modifier == extractor::guidance::DirectionModifier::SharpLeft ||
instruction.direction_modifier == extractor::guidance::DirectionModifier::Left ||
instruction.direction_modifier == extractor::guidance::DirectionModifier::SlightLeft;
}
inline bool hasRightModifier(const extractor::guidance::TurnInstruction instruction)
{
return instruction.direction_modifier == extractor::guidance::DirectionModifier::SharpRight ||
instruction.direction_modifier == extractor::guidance::DirectionModifier::Right ||
instruction.direction_modifier == extractor::guidance::DirectionModifier::SlightRight;
}
inline bool isLeftTurn(const extractor::guidance::TurnInstruction instruction)
{
switch (instruction.type)
{
case extractor::guidance::TurnType::Merge:
return hasRightModifier(instruction);
default:
return hasLeftModifier(instruction);
}
}
inline bool isRightTurn(const extractor::guidance::TurnInstruction instruction)
{
switch (instruction.type)
{
case extractor::guidance::TurnType::Merge:
return hasLeftModifier(instruction);
default:
return hasRightModifier(instruction);
}
}
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::EnterRoundaboutIntersection ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRotaryAtExit ||
instruction.type == extractor::guidance::TurnType::EnterRoundaboutIntersectionAtExit ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundaboutIntersection);
}
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::ExitRoundaboutIntersection ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRotary ||
instruction.type == extractor::guidance::TurnType::EnterAndExitRoundaboutIntersection);
}
inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruction)
{
return instruction.type == extractor::guidance::TurnType::StayOnRoundabout;
}
// Name Change Logic // Name Change Logic
// Used both during Extraction as well as during Post-Processing // Used both during Extraction as well as during Post-Processing
@ -304,4 +182,4 @@ inline bool requiresNameAnnounced(const NameID from_name_id,
} // namespace util } // namespace util
} // namespace osrm } // namespace osrm
#endif /* OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ */ #endif /* OSRM_UTIL_GUIDANCE_NAME_ANNOUNCEMENT_HPP_ */

View File

@ -4,6 +4,7 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <unordered_map>
#include <vector> #include <vector>
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@ -96,6 +97,8 @@ class LaneTupleIdPair
} }
}; };
using LaneDataIdMap = std::unordered_map<LaneTupleIdPair, LaneDataID, boost::hash<LaneTupleIdPair>>;
} // namespace guidance } // namespace guidance
} // namespace util } // namespace util
} // namespace osrm } // namespace osrm

View File

@ -6,7 +6,6 @@
#include "extractor/edge_based_graph_factory.hpp" #include "extractor/edge_based_graph_factory.hpp"
#include "extractor/node_based_edge.hpp" #include "extractor/node_based_edge.hpp"
#include "storage/io.hpp"
#include "storage/io.hpp" #include "storage/io.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "util/exception_utils.hpp" #include "util/exception_utils.hpp"

View File

@ -6,7 +6,6 @@
#include "util/guidance/bearing_class.hpp" #include "util/guidance/bearing_class.hpp"
#include "util/guidance/entry_class.hpp" #include "util/guidance/entry_class.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>

View File

@ -1,10 +1,8 @@
#include "util/for_each_pair.hpp" #include "util/for_each_pair.hpp"
#include "util/group_by.hpp" #include "util/group_by.hpp"
#include "util/guidance/toolkit.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "engine/guidance/post_processing.hpp" #include "engine/guidance/post_processing.hpp"
#include "engine/guidance/toolkit.hpp"
#include <iterator> #include <iterator>
#include <unordered_set> #include <unordered_set>
@ -14,8 +12,8 @@ using TurnInstruction = osrm::extractor::guidance::TurnInstruction;
namespace TurnType = osrm::extractor::guidance::TurnType; namespace TurnType = osrm::extractor::guidance::TurnType;
namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier; namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier;
using osrm::util::guidance::isLeftTurn; using osrm::extractor::guidance::isLeftTurn;
using osrm::util::guidance::isRightTurn; using osrm::extractor::guidance::isRightTurn;
namespace osrm namespace osrm
{ {
@ -80,8 +78,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// where lanes in the turn fan in but for example the overall lanes at that location // where lanes in the turn fan in but for example the overall lanes at that location
// fan out, we would have to know the asymmetric mapping of lanes. This is currently // fan out, we would have to know the asymmetric mapping of lanes. This is currently
// not possible at the moment. In the following we implement a heuristic instead. // not possible at the moment. In the following we implement a heuristic instead.
const LaneID current_num_lanes_right_of_turn = numLanesToTheRight(current); const LaneID current_num_lanes_right_of_turn = current.numLanesToTheRight();
const LaneID current_num_lanes_left_of_turn = numLanesToTheLeft(current); const LaneID current_num_lanes_left_of_turn = current.numLanesToTheLeft();
const LaneID num_shared_lanes = std::min(current_lanes.lanes_in_turn, // const LaneID num_shared_lanes = std::min(current_lanes.lanes_in_turn, //
previous_lanes.lanes_in_turn); // previous_lanes.lanes_in_turn); //

View File

@ -1,14 +1,12 @@
#include "engine/guidance/post_processing.hpp" #include "engine/guidance/post_processing.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
#include "engine/guidance/toolkit.hpp"
#include "engine/guidance/assemble_steps.hpp" #include "engine/guidance/assemble_steps.hpp"
#include "engine/guidance/lane_processing.hpp" #include "engine/guidance/lane_processing.hpp"
#include "engine/guidance/toolkit.hpp"
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/guidance/toolkit.hpp" #include "util/guidance/name_announcements.hpp"
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -25,8 +23,11 @@
using TurnInstruction = osrm::extractor::guidance::TurnInstruction; using TurnInstruction = osrm::extractor::guidance::TurnInstruction;
namespace TurnType = osrm::extractor::guidance::TurnType; namespace TurnType = osrm::extractor::guidance::TurnType;
namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier; namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier;
using osrm::util::guidance::angularDeviation; using osrm::util::angularDeviation;
using osrm::util::guidance::getTurnDirection; using osrm::extractor::guidance::getTurnDirection;
using osrm::extractor::guidance::hasRampType;
using osrm::extractor::guidance::mirrorDirectionModifier;
using osrm::extractor::guidance::bearingToDirectionModifier;
namespace osrm namespace osrm
{ {
@ -299,14 +300,13 @@ void closeOffRoundabout(const bool on_roundabout,
TurnType::EnterRoundaboutIntersectionAtExit) TurnType::EnterRoundaboutIntersectionAtExit)
{ {
BOOST_ASSERT(!propagation_step.intersections.empty()); BOOST_ASSERT(!propagation_step.intersections.empty());
const double angle = util::bearing::angleBetweenBearings( const double angle = util::angleBetweenBearings(
util::bearing::reverseBearing( util::reverseBearing(entry_intersection.bearings[entry_intersection.in]),
entry_intersection.bearings[entry_intersection.in]),
exit_bearing); exit_bearing);
auto bearings = propagation_step.intersections.front().bearings; auto bearings = propagation_step.intersections.front().bearings;
propagation_step.maneuver.instruction.direction_modifier = propagation_step.maneuver.instruction.direction_modifier =
util::guidance::getTurnDirection(angle); getTurnDirection(angle);
} }
forwardStepSignage(propagation_step, destination_copy); forwardStepSignage(propagation_step, destination_copy);
@ -346,7 +346,7 @@ bool isUTurn(const RouteStep &in_step, const RouteStep &out_step, const RouteSte
(isLinkroad(in_step) && out_step.name_id != EMPTY_NAMEID && (isLinkroad(in_step) && out_step.name_id != EMPTY_NAMEID &&
pre_in_step.name_id != EMPTY_NAMEID && !isNoticeableNameChange(pre_in_step, out_step)); pre_in_step.name_id != EMPTY_NAMEID && !isNoticeableNameChange(pre_in_step, out_step));
const bool takes_u_turn = bearingsAreReversed( const bool takes_u_turn = bearingsAreReversed(
util::bearing::reverseBearing( util::reverseBearing(
in_step.intersections.front().bearings[in_step.intersections.front().in]), in_step.intersections.front().bearings[in_step.intersections.front().in]),
out_step.intersections.front().bearings[out_step.intersections.front().out]); out_step.intersections.front().bearings[out_step.intersections.front().out]);
@ -358,20 +358,20 @@ double findTotalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_ste
const auto exit_intersection = exit_step.intersections.front(); const auto exit_intersection = exit_step.intersections.front();
const auto exit_step_exit_bearing = exit_intersection.bearings[exit_intersection.out]; const auto exit_step_exit_bearing = exit_intersection.bearings[exit_intersection.out];
const auto exit_step_entry_bearing = const auto exit_step_entry_bearing =
util::bearing::reverseBearing(exit_intersection.bearings[exit_intersection.in]); util::reverseBearing(exit_intersection.bearings[exit_intersection.in]);
const auto entry_intersection = entry_step.intersections.front(); const auto entry_intersection = entry_step.intersections.front();
const auto entry_step_entry_bearing = const auto entry_step_entry_bearing =
util::bearing::reverseBearing(entry_intersection.bearings[entry_intersection.in]); util::reverseBearing(entry_intersection.bearings[entry_intersection.in]);
const auto entry_step_exit_bearing = entry_intersection.bearings[entry_intersection.out]; const auto entry_step_exit_bearing = entry_intersection.bearings[entry_intersection.out];
const auto exit_angle = const auto exit_angle =
util::bearing::angleBetweenBearings(exit_step_entry_bearing, exit_step_exit_bearing); util::angleBetweenBearings(exit_step_entry_bearing, exit_step_exit_bearing);
const auto entry_angle = const auto entry_angle =
util::bearing::angleBetweenBearings(entry_step_entry_bearing, entry_step_exit_bearing); util::angleBetweenBearings(entry_step_entry_bearing, entry_step_exit_bearing);
const double total_angle = const double total_angle =
util::bearing::angleBetweenBearings(entry_step_entry_bearing, exit_step_exit_bearing); util::angleBetweenBearings(entry_step_entry_bearing, exit_step_exit_bearing);
// We allow for minor deviations from a straight line // We allow for minor deviations from a straight line
if (((entry_step.distance < MAX_COLLAPSE_DISTANCE && exit_step.intersections.size() == 1) || if (((entry_step.distance < MAX_COLLAPSE_DISTANCE && exit_step.intersections.size() == 1) ||
(entry_angle <= 185 && exit_angle <= 185) || (entry_angle >= 175 && exit_angle >= 175)) && (entry_angle <= 185 && exit_angle <= 185) || (entry_angle >= 175 && exit_angle >= 175)) &&
@ -521,8 +521,8 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
// tagged late // tagged late
const auto is_delayed_turn_onto_a_ramp = const auto is_delayed_turn_onto_a_ramp =
opening_turn.distance <= 4 * MAX_COLLAPSE_DISTANCE && without_choice && opening_turn.distance <= 4 * MAX_COLLAPSE_DISTANCE && without_choice &&
util::guidance::hasRampType(finishing_turn.maneuver.instruction); hasRampType(finishing_turn.maneuver.instruction);
return !util::guidance::hasRampType(opening_turn.maneuver.instruction) && return !hasRampType(opening_turn.maneuver.instruction) &&
(is_short_and_collapsable || is_not_too_long_and_choiceless || (is_short_and_collapsable || is_not_too_long_and_choiceless ||
isLinkroad(opening_turn) || is_delayed_turn_onto_a_ramp); isLinkroad(opening_turn) || is_delayed_turn_onto_a_ramp);
} }
@ -539,8 +539,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
if (TurnType::Merge == current_step.maneuver.instruction.type) if (TurnType::Merge == current_step.maneuver.instruction.type)
{ {
steps[step_index].maneuver.instruction.direction_modifier = steps[step_index].maneuver.instruction.direction_modifier =
util::guidance::mirrorDirectionModifier( mirrorDirectionModifier(steps[step_index].maneuver.instruction.direction_modifier);
steps[step_index].maneuver.instruction.direction_modifier);
steps[step_index].maneuver.instruction.type = TurnType::Turn; steps[step_index].maneuver.instruction.type = TurnType::Turn;
} }
else else
@ -573,18 +572,18 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
if (continue_or_suppressed || turning_name) if (continue_or_suppressed || turning_name)
{ {
const auto in_bearing = [](const RouteStep &step) { const auto in_bearing = [](const RouteStep &step) {
return util::bearing::reverseBearing( return util::reverseBearing(
step.intersections.front().bearings[step.intersections.front().in]); step.intersections.front().bearings[step.intersections.front().in]);
}; };
const auto out_bearing = [](const RouteStep &step) { const auto out_bearing = [](const RouteStep &step) {
return step.intersections.front().bearings[step.intersections.front().out]; return step.intersections.front().bearings[step.intersections.front().out];
}; };
const auto first_angle = util::bearing::angleBetweenBearings( const auto first_angle = util::angleBetweenBearings(in_bearing(one_back_step),
in_bearing(one_back_step), out_bearing(one_back_step)); out_bearing(one_back_step));
const auto second_angle = util::bearing::angleBetweenBearings( const auto second_angle =
in_bearing(current_step), out_bearing(current_step)); util::angleBetweenBearings(in_bearing(current_step), out_bearing(current_step));
const auto bearing_turn_angle = util::bearing::angleBetweenBearings( const auto bearing_turn_angle = util::angleBetweenBearings(
in_bearing(one_back_step), out_bearing(current_step)); in_bearing(one_back_step), out_bearing(current_step));
// When looking at an intersection, some angles, even though present, feel more like // When looking at an intersection, some angles, even though present, feel more like
@ -669,7 +668,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
DirectionModifier::Straight; DirectionModifier::Straight;
else else
steps[step_index].maneuver.instruction.direction_modifier = steps[step_index].maneuver.instruction.direction_modifier =
util::guidance::getTurnDirection(bearing_turn_angle); getTurnDirection(bearing_turn_angle);
// if the total direction of this turn is now straight, we can keep it suppressed/as // if the total direction of this turn is now straight, we can keep it suppressed/as
// a new name. Else we have to interpret it as a turn. // a new name. Else we have to interpret it as a turn.
@ -718,7 +717,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
}; };
// If we Merge onto the same street, we end up with a u-turn in some cases // If we Merge onto the same street, we end up with a u-turn in some cases
if (bearingsAreReversed(util::bearing::reverseBearing(getBearing(true, one_back_step)), if (bearingsAreReversed(util::reverseBearing(getBearing(true, one_back_step)),
getBearing(false, current_step))) getBearing(false, current_step)))
{ {
steps[one_back_index].maneuver.instruction.direction_modifier = steps[one_back_index].maneuver.instruction.direction_modifier =
@ -737,9 +736,8 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
// need a highway-suppressed to get the turn onto a // need a highway-suppressed to get the turn onto a
// highway... // highway...
{ {
steps[one_back_index].maneuver.instruction.direction_modifier = steps[one_back_index].maneuver.instruction.direction_modifier = mirrorDirectionModifier(
util::guidance::mirrorDirectionModifier( steps[one_back_index].maneuver.instruction.direction_modifier);
steps[one_back_index].maneuver.instruction.direction_modifier);
} }
// on non merge-types, we check for a combined turn angle // on non merge-types, we check for a combined turn angle
else if (TurnType::Merge != one_back_step.maneuver.instruction.type) else if (TurnType::Merge != one_back_step.maneuver.instruction.type)
@ -759,8 +757,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
{ {
steps[one_back_index] = elongate(std::move(steps[one_back_index]), current_step); steps[one_back_index] = elongate(std::move(steps[one_back_index]), current_step);
const auto angle = findTotalTurnAngle(one_back_step, current_step); const auto angle = findTotalTurnAngle(one_back_step, current_step);
steps[one_back_index].maneuver.instruction.direction_modifier = steps[one_back_index].maneuver.instruction.direction_modifier = getTurnDirection(angle);
util::guidance::getTurnDirection(angle);
invalidateStep(steps[step_index]); invalidateStep(steps[step_index]);
} }
@ -772,8 +769,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
steps[one_back_index] = elongate(std::move(steps[one_back_index]), current_step); steps[one_back_index] = elongate(std::move(steps[one_back_index]), current_step);
steps[one_back_index].maneuver.instruction.type = TurnType::OnRamp; steps[one_back_index].maneuver.instruction.type = TurnType::OnRamp;
const auto angle = findTotalTurnAngle(one_back_step, current_step); const auto angle = findTotalTurnAngle(one_back_step, current_step);
steps[one_back_index].maneuver.instruction.direction_modifier = steps[one_back_index].maneuver.instruction.direction_modifier = getTurnDirection(angle);
util::guidance::getTurnDirection(angle);
forwardStepSignage(steps[one_back_index], current_step); forwardStepSignage(steps[one_back_index], current_step);
invalidateStep(steps[step_index]); invalidateStep(steps[step_index]);
@ -806,7 +802,7 @@ bool isStaggeredIntersection(const std::vector<RouteStep> &steps,
const auto &intersection = step.intersections.front(); const auto &intersection = step.intersections.front();
const auto entry_bearing = intersection.bearings[intersection.in]; const auto entry_bearing = intersection.bearings[intersection.in];
const auto exit_bearing = intersection.bearings[intersection.out]; const auto exit_bearing = intersection.bearings[intersection.out];
return util::bearing::angleBetweenBearings(entry_bearing, exit_bearing); return util::angleBetweenBearings(entry_bearing, exit_bearing);
}; };
// Instead of using turn modifiers (e.g. as in isRightTurn) we want to be more strict here. // Instead of using turn modifiers (e.g. as in isRightTurn) we want to be more strict here.
@ -1123,7 +1119,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
const auto angle = findTotalTurnAngle(one_back_step, current_step); const auto angle = findTotalTurnAngle(one_back_step, current_step);
steps[one_back_index].maneuver.instruction.direction_modifier = steps[one_back_index].maneuver.instruction.direction_modifier =
util::guidance::getTurnDirection(angle); getTurnDirection(angle);
invalidateStep(steps[step_index]); invalidateStep(steps[step_index]);
} }
else else
@ -1462,7 +1458,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
geometry.locations[next_to_last_step.geometry_end - 2], geometry.locations[next_to_last_step.geometry_end - 2],
geometry.locations[last_step.geometry_begin])); geometry.locations[last_step.geometry_begin]));
last_step.maneuver.bearing_before = bearing; last_step.maneuver.bearing_before = bearing;
last_step.intersections.front().bearings.front() = util::bearing::reverseBearing(bearing); last_step.intersections.front().bearings.front() = util::reverseBearing(bearing);
} }
BOOST_ASSERT(steps.back().geometry_end == geometry.locations.size()); BOOST_ASSERT(steps.back().geometry_end == geometry.locations.size());
@ -1494,7 +1490,7 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
const auto initial_modifier = const auto initial_modifier =
distance_to_start >= MINIMAL_RELATIVE_DISTANCE && distance_to_start >= MINIMAL_RELATIVE_DISTANCE &&
distance_to_start <= MAXIMAL_RELATIVE_DISTANCE distance_to_start <= MAXIMAL_RELATIVE_DISTANCE
? angleToDirectionModifier(util::coordinate_calculation::computeAngle( ? bearingToDirectionModifier(util::coordinate_calculation::computeAngle(
source_node.input_location, leg_geometry.locations[0], leg_geometry.locations[1])) source_node.input_location, leg_geometry.locations[0], leg_geometry.locations[1]))
: extractor::guidance::DirectionModifier::UTurn; : extractor::guidance::DirectionModifier::UTurn;
@ -1505,7 +1501,7 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
const auto final_modifier = const auto final_modifier =
distance_from_end >= MINIMAL_RELATIVE_DISTANCE && distance_from_end >= MINIMAL_RELATIVE_DISTANCE &&
distance_from_end <= MAXIMAL_RELATIVE_DISTANCE distance_from_end <= MAXIMAL_RELATIVE_DISTANCE
? angleToDirectionModifier(util::coordinate_calculation::computeAngle( ? bearingToDirectionModifier(util::coordinate_calculation::computeAngle(
leg_geometry.locations[leg_geometry.locations.size() - 2], leg_geometry.locations[leg_geometry.locations.size() - 2],
leg_geometry.locations[leg_geometry.locations.size() - 1], leg_geometry.locations[leg_geometry.locations.size() - 1],
target_node.input_location)) target_node.input_location))
@ -1604,13 +1600,13 @@ std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps)
// the lane description is given left to right, lanes are counted from the right. // the lane description is given left to right, lanes are counted from the right.
// Therefore we access the lane description using the reverse iterator // Therefore we access the lane description using the reverse iterator
auto right_most_lanes = lanesToTheRight(step); auto right_most_lanes = step.lanesToTheRight();
if (!right_most_lanes.empty() && containsTag(right_most_lanes.front(), if (!right_most_lanes.empty() && containsTag(right_most_lanes.front(),
(extractor::guidance::TurnLaneType::straight | (extractor::guidance::TurnLaneType::straight |
extractor::guidance::TurnLaneType::none))) extractor::guidance::TurnLaneType::none)))
return false; return false;
auto left_most_lanes = lanesToTheLeft(step); auto left_most_lanes = step.lanesToTheLeft();
if (!left_most_lanes.empty() && containsTag(left_most_lanes.back(), if (!left_most_lanes.empty() && containsTag(left_most_lanes.back(),
(extractor::guidance::TurnLaneType::straight | (extractor::guidance::TurnLaneType::straight |
extractor::guidance::TurnLaneType::none))) extractor::guidance::TurnLaneType::none)))

View File

@ -10,7 +10,6 @@
#include "util/percent.hpp" #include "util/percent.hpp"
#include "util/timing_util.hpp" #include "util/timing_util.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_analysis.hpp" #include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/turn_lane_handler.hpp" #include "extractor/guidance/turn_lane_handler.hpp"
#include "extractor/scripting_environment.hpp" #include "extractor/scripting_environment.hpp"
@ -354,7 +353,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
street_name_suffix_table, street_name_suffix_table,
profile_properties); profile_properties);
guidance::LaneDataIdMap lane_data_map; util::guidance::LaneDataIdMap lane_data_map;
guidance::lanes::TurnLaneHandler turn_lane_handler(*m_node_based_graph, guidance::lanes::TurnLaneHandler turn_lane_handler(*m_node_based_graph,
turn_lane_offsets, turn_lane_offsets,
turn_lane_masks, turn_lane_masks,

View File

@ -10,7 +10,6 @@
#include "extractor/raster_source.hpp" #include "extractor/raster_source.hpp"
#include "storage/io.hpp" #include "storage/io.hpp"
#include "storage/io.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "util/exception_utils.hpp" #include "util/exception_utils.hpp"
#include "util/graph_loader.hpp" #include "util/graph_loader.hpp"
@ -45,7 +44,6 @@
#include <atomic> #include <atomic>
#include <bitset> #include <bitset>
#include <chrono> #include <chrono>
#include <chrono>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>

View File

@ -1,17 +1,17 @@
#include "extractor/guidance/coordinate_extractor.hpp" #include "extractor/guidance/coordinate_extractor.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp"
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <iomanip>
#include <limits>
#include <numeric> #include <numeric>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
#include <boost/range/algorithm/transform.hpp> #include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp"
using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {
@ -1153,7 +1153,8 @@ CoordinateExtractor::RegressionLine(const std::vector<util::Coordinate> &coordin
return {coordinates.front(), coordinates.back()}; return {coordinates.front(), coordinates.back()};
// compute the regression vector based on the sum of least squares // compute the regression vector based on the sum of least squares
const auto regression_line = leastSquareRegression(sampled_coordinates); const auto regression_line =
util::coordinate_calculation::leastSquareRegression(sampled_coordinates);
const auto coord_between_front = const auto coord_between_front =
util::coordinate_calculation::projectPointOnSegment( util::coordinate_calculation::projectPointOnSegment(
regression_line.first, regression_line.second, coordinates.front()) regression_line.first, regression_line.second, coordinates.front())

View File

@ -1,5 +1,4 @@
#include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/toolkit.hpp"
#include <boost/range/adaptor/transformed.hpp> #include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/find_if.hpp> #include <boost/range/algorithm/find_if.hpp>
@ -10,6 +9,8 @@
#include <functional> #include <functional>
#include <limits> #include <limits>
using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {
namespace extractor namespace extractor

View File

@ -1,16 +1,12 @@
#include "extractor/guidance/intersection_generator.hpp" #include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/guidance/toolkit.hpp" #include "util/coordinate_calculation.hpp"
#include <algorithm> #include <algorithm>
#include <functional> #include <functional> // mem_fn
#include <iomanip>
#include <iterator>
#include <limits> #include <limits>
#include <unordered_set> #include <numeric>
#include <utility> #include <utility>
#include <boost/range/algorithm/count_if.hpp> #include <boost/range/algorithm/count_if.hpp>
@ -58,8 +54,16 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
const util::Coordinate turn_coordinate = node_info_list[node_at_center_of_intersection]; const util::Coordinate turn_coordinate = node_info_list[node_at_center_of_intersection];
// number of lanes at the intersection changes how far we look down the road // number of lanes at the intersection changes how far we look down the road
const auto intersection_lanes = const auto edge_range = node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection);
getLaneCountAtIntersection(node_at_center_of_intersection, node_based_graph); const auto max_lanes_intersection = std::accumulate(
edge_range.begin(),
edge_range.end(),
std::uint8_t{0},
[this](const auto current_max, const auto current_eid) {
return std::max(
current_max,
node_based_graph.GetEdgeData(current_eid).road_classification.GetNumberOfLanes());
});
for (const EdgeID edge_connected_to_intersection : for (const EdgeID edge_connected_to_intersection :
node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection)) node_based_graph.GetAdjacentEdgeRange(node_at_center_of_intersection))
@ -86,7 +90,7 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
via_eid, via_eid,
traversed_in_reverse, traversed_in_reverse,
to_node, to_node,
intersection_lanes, max_lanes_intersection,
std::move(coordinates)); std::move(coordinates));
}; };
@ -112,9 +116,9 @@ IntersectionGenerator::ComputeIntersectionShape(const NodeID node_at_center_of_i
return node_based_graph.GetTarget(data.eid) == *sorting_base; return node_based_graph.GetTarget(data.eid) == *sorting_base;
}); });
if (itr != intersection.end()) if (itr != intersection.end())
return util::bearing::reverseBearing(itr->bearing); return util::reverseBearing(itr->bearing);
} }
return util::bearing::reverseBearing(intersection.begin()->bearing); return util::reverseBearing(intersection.begin()->bearing);
}(); }();
std::sort( std::sort(
intersection.begin(), intersection.end(), makeCompareShapeDataByBearing(base_bearing)); intersection.begin(), intersection.end(), makeCompareShapeDataByBearing(base_bearing));
@ -150,11 +154,8 @@ IntersectionView IntersectionGenerator::GetConnectedRoads(const NodeID from_node
return TransformIntersectionShapeIntoView(from_node, via_eid, std::move(intersection)); return TransformIntersectionShapeIntoView(from_node, via_eid, std::move(intersection));
} }
IntersectionView std::pair<NodeID, EdgeID> IntersectionGenerator::SkipDegreeTwoNodes(const NodeID starting_node,
IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node, const EdgeID via_edge) const
const EdgeID via_edge,
NodeID *resulting_from_node = nullptr,
EdgeID *resulting_via_edge = nullptr) const
{ {
NodeID query_node = starting_node; NodeID query_node = starting_node;
EdgeID query_edge = via_edge; EdgeID query_edge = via_edge;
@ -185,12 +186,7 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node,
query_edge = next_edge; query_edge = next_edge;
} }
if (resulting_from_node) return std::make_pair(query_node, query_edge);
*resulting_from_node = query_node;
if (resulting_via_edge)
*resulting_via_edge = query_edge;
return GetConnectedRoads(query_node, query_edge);
} }
IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView( IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView(
@ -273,7 +269,7 @@ IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView(
normalised_intersection.end(), normalised_intersection.end(),
[&](const IntersectionShapeData &road) { return road.eid == merged_into_id; }); [&](const IntersectionShapeData &road) { return road.eid == merged_into_id; });
BOOST_ASSERT(merged_u_turn != normalised_intersection.end()); BOOST_ASSERT(merged_u_turn != normalised_intersection.end());
return util::bearing::reverseBearing(merged_u_turn->bearing); return util::reverseBearing(merged_u_turn->bearing);
} }
else else
{ {
@ -283,8 +279,7 @@ IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView(
connect_to_previous_node); connect_to_previous_node);
BOOST_ASSERT(uturn_edge_at_normalised_intersection_itr != BOOST_ASSERT(uturn_edge_at_normalised_intersection_itr !=
normalised_intersection.end()); normalised_intersection.end());
return util::bearing::reverseBearing( return util::reverseBearing(uturn_edge_at_normalised_intersection_itr->bearing);
uturn_edge_at_normalised_intersection_itr->bearing);
} }
}(); }();
@ -297,7 +292,7 @@ IntersectionView IntersectionGenerator::TransformIntersectionShapeIntoView(
return IntersectionViewData( return IntersectionViewData(
road, road,
is_allowed_turn(road), is_allowed_turn(road),
util::bearing::angleBetweenBearings(uturn_bearing, road.bearing)); util::angleBetweenBearings(uturn_bearing, road.bearing));
}); });
const auto uturn_edge_at_intersection_view_itr = const auto uturn_edge_at_intersection_view_itr =

View File

@ -1,16 +1,15 @@
#include "extractor/guidance/intersection_handler.hpp" #include "extractor/guidance/intersection_handler.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/log.hpp" #include "util/log.hpp"
#include "util/guidance/name_announcements.hpp"
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
using EdgeData = osrm::util::NodeBasedDynamicGraph::EdgeData; using EdgeData = osrm::util::NodeBasedDynamicGraph::EdgeData;
using osrm::util::guidance::getTurnDirection; using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {
@ -759,8 +758,12 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
// try to find whether there is a turn going to the opposite direction of our obvious // try to find whether there is a turn going to the opposite direction of our obvious
// turn, this should be alright. // turn, this should be alright.
NodeID new_node; NodeID new_node;
const auto previous_intersection = intersection_generator.GetActualNextIntersection( const auto previous_intersection = [&]() {
node_at_intersection, intersection[0].eid, &new_node, nullptr); EdgeID turn_edge;
std::tie(new_node, turn_edge) = intersection_generator.SkipDegreeTwoNodes(
node_at_intersection, intersection[0].eid);
return intersection_generator.GetConnectedRoads(new_node, turn_edge);
}();
if (new_node != node_at_intersection) if (new_node != node_at_intersection)
{ {

View File

@ -1,7 +1,12 @@
#include "extractor/guidance/intersection_normalizer.hpp" #include "extractor/guidance/intersection_normalizer.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/bearing.hpp" #include "util/bearing.hpp"
#include "util/guidance/toolkit.hpp" #include "util/coordinate_calculation.hpp"
#include "util/guidance/name_announcements.hpp"
#include <tuple>
#include <utility>
using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {
@ -115,10 +120,10 @@ bool IntersectionNormalizer::InnerCanMerge(const NodeID node_at_intersection,
const auto isValidYArm = [this, intersection, coordinate_at_intersection, node_at_intersection]( const auto isValidYArm = [this, intersection, coordinate_at_intersection, node_at_intersection](
const std::size_t index, const std::size_t other_index) { const std::size_t index, const std::size_t other_index) {
const auto GetActualTarget = [&](const std::size_t index) { const auto GetActualTarget = [&](const std::size_t index) {
EdgeID last_in_edge_id; EdgeID edge_id;
intersection_generator.GetActualNextIntersection( std::tie(std::ignore, edge_id) = intersection_generator.SkipDegreeTwoNodes(
node_at_intersection, intersection[index].eid, nullptr, &last_in_edge_id); node_at_intersection, intersection[index].eid);
return node_based_graph.GetTarget(last_in_edge_id); return node_based_graph.GetTarget(edge_id);
}; };
const auto target_id = GetActualTarget(index); const auto target_id = GetActualTarget(index);

View File

@ -1,18 +1,17 @@
#include "extractor/guidance/motorway_handler.hpp" #include "extractor/guidance/motorway_handler.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/road_classification.hpp" #include "extractor/guidance/road_classification.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/guidance/toolkit.hpp" #include "util/bearing.hpp"
#include "util/log.hpp" #include "util/guidance/name_announcements.hpp"
#include <limits> #include <limits>
#include <utility> #include <utility>
#include <boost/assert.hpp> #include <boost/assert.hpp>
using osrm::util::guidance::angularDeviation; using osrm::util::angularDeviation;
using osrm::util::guidance::getTurnDirection; using osrm::extractor::guidance::getTurnDirection;
namespace osrm namespace osrm
{ {
@ -197,9 +196,6 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
else if (countValid(intersection) > 0) // check whether turns exist at all else if (countValid(intersection) > 0) // check whether turns exist at all
{ {
// FALLBACK, this should hopefully never be reached // FALLBACK, this should hopefully never be reached
util::Log(logDEBUG) << "Fallback reached from motorway, no continue angle, "
<< intersection.size() << " roads, " << countValid(intersection)
<< " valid ones.";
return fallback(std::move(intersection)); return fallback(std::move(intersection));
} }
} }
@ -275,7 +271,6 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
via_eid, via_eid,
isThroughStreet(1, intersection), isThroughStreet(1, intersection),
intersection[1]); intersection[1]);
util::Log(logDEBUG) << "Disabled U-Turn on a freeway";
intersection[0].entry_allowed = false; // UTURN on the freeway intersection[0].entry_allowed = false; // UTURN on the freeway
} }
else if (exiting_motorways == 2) else if (exiting_motorways == 2)
@ -334,8 +329,6 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
} }
else else
{ {
util::Log(logDEBUG) << "Found motorway junction with more than "
"2 exiting motorways or additional ramps";
return fallback(std::move(intersection)); return fallback(std::move(intersection));
} }
} // done for more than one highway exit } // done for more than one highway exit
@ -488,9 +481,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
} }
} }
else else
{ // FALLBACK, hopefully this should never been reached {
util::Log(logDEBUG) << "Reached fallback on motorway ramp with " << intersection.size()
<< " roads and " << countValid(intersection) << " valid turns.";
return fallback(std::move(intersection)); return fallback(std::move(intersection));
} }
return intersection; return intersection;

View File

@ -1,5 +1,8 @@
#include "extractor/guidance/node_based_graph_walker.hpp" #include "extractor/guidance/node_based_graph_walker.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include <utility>
using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {

View File

@ -1,17 +1,19 @@
#include "extractor/guidance/roundabout_handler.hpp" #include "extractor/guidance/roundabout_handler.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/log.hpp" #include "util/log.hpp"
#include "util/guidance/name_announcements.hpp"
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <numeric>
#include <utility>
#include <boost/assert.hpp> #include <boost/assert.hpp>
using osrm::util::guidance::getTurnDirection; using osrm::extractor::guidance::getTurnDirection;
namespace osrm namespace osrm
{ {
@ -182,12 +184,23 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
// there is a single non-roundabout edge // there is a single non-roundabout edge
const auto src_coordinate = getCoordinate(node); const auto src_coordinate = getCoordinate(node);
const auto next_coordinate = coordinate_extractor.GetCoordinateAlongRoad( const auto edge_range = node_based_graph.GetAdjacentEdgeRange(node);
node, const auto number_of_lanes_at_intersection = std::accumulate(
edge, edge_range.begin(),
edge_data.reversed, edge_range.end(),
node_based_graph.GetTarget(edge), std::uint8_t{0},
getLaneCountAtIntersection(node, node_based_graph)); [this](const auto current_max, const auto current_eid) {
return std::max(current_max,
node_based_graph.GetEdgeData(current_eid)
.road_classification.GetNumberOfLanes());
});
const auto next_coordinate =
coordinate_extractor.GetCoordinateAlongRoad(node,
edge,
false,
node_based_graph.GetTarget(edge),
number_of_lanes_at_intersection);
result.push_back( result.push_back(
util::coordinate_calculation::bearing(src_coordinate, next_coordinate)); util::coordinate_calculation::bearing(src_coordinate, next_coordinate));

View File

@ -1,17 +1,16 @@
#include "extractor/guidance/sliproad_handler.hpp" #include "extractor/guidance/sliproad_handler.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp" #include "util/bearing.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/guidance/toolkit.hpp" #include "util/guidance/name_announcements.hpp"
#include <limits> #include <limits>
#include <utility>
#include <boost/assert.hpp> #include <boost/assert.hpp>
using EdgeData = osrm::util::NodeBasedDynamicGraph::EdgeData; using EdgeData = osrm::util::NodeBasedDynamicGraph::EdgeData;
using osrm::util::guidance::getTurnDirection; using osrm::extractor::guidance::getTurnDirection;
using osrm::util::guidance::angularDeviation; using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {

View File

@ -4,19 +4,13 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include "util/guidance/toolkit.hpp"
#include "util/log.hpp"
#include <cstddef> #include <cstddef>
#include <iomanip>
#include <iterator>
#include <limits>
#include <map>
#include <set> #include <set>
#include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <utility>
using osrm::util::guidance::getTurnDirection; using osrm::extractor::guidance::getTurnDirection;
namespace osrm namespace osrm
{ {

View File

@ -1,10 +1,8 @@
#include "extractor/guidance/turn_classification.hpp" #include "extractor/guidance/turn_classification.hpp"
#include "util/log.hpp" #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <iomanip>
namespace osrm namespace osrm
{ {

View File

@ -1,7 +1,8 @@
#include "extractor/guidance/turn_discovery.hpp" #include "extractor/guidance/turn_discovery.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include "util/guidance/toolkit.hpp"
using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {
@ -73,8 +74,7 @@ bool findPreviousIntersection(const NodeID node_v,
// TODO evaluate if narrow turn is the right criterion here... Might be that other angles are // TODO evaluate if narrow turn is the right criterion here... Might be that other angles are
// valid // valid
if (util::guidance::angularDeviation(straightmost_at_v_in_reverse->angle, STRAIGHT_ANGLE) > if (angularDeviation(straightmost_at_v_in_reverse->angle, STRAIGHT_ANGLE) > GROUP_ANGLE)
GROUP_ANGLE)
return false; return false;
const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid); const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid);

View File

@ -1,8 +1,8 @@
#include "extractor/guidance/turn_handler.hpp" #include "extractor/guidance/turn_handler.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/guidance/toolkit.hpp" #include "util/bearing.hpp"
#include "util/guidance/name_announcements.hpp"
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
@ -11,8 +11,8 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
using EdgeData = osrm::util::NodeBasedDynamicGraph::EdgeData; using EdgeData = osrm::util::NodeBasedDynamicGraph::EdgeData;
using osrm::util::guidance::getTurnDirection; using osrm::extractor::guidance::getTurnDirection;
using osrm::util::guidance::angularDeviation; using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {

View File

@ -5,7 +5,6 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>

View File

@ -4,14 +4,16 @@
#include "extractor/guidance/turn_lane_augmentation.hpp" #include "extractor/guidance/turn_lane_augmentation.hpp"
#include "extractor/guidance/turn_lane_matcher.hpp" #include "extractor/guidance/turn_lane_matcher.hpp"
#include "util/log.hpp" #include "util/log.hpp"
#include "util/bearing.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {
namespace extractor namespace extractor
@ -36,7 +38,7 @@ TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_g
std::vector<TurnLaneType::Mask> &turn_lane_masks, std::vector<TurnLaneType::Mask> &turn_lane_masks,
LaneDescriptionMap &lane_description_map, LaneDescriptionMap &lane_description_map,
const TurnAnalysis &turn_analysis, const TurnAnalysis &turn_analysis,
LaneDataIdMap &id_map) util::guidance::LaneDataIdMap &id_map)
: node_based_graph(node_based_graph), turn_lane_offsets(turn_lane_offsets), : node_based_graph(node_based_graph), turn_lane_offsets(turn_lane_offsets),
turn_lane_masks(turn_lane_masks), lane_description_map(lane_description_map), turn_lane_masks(turn_lane_masks), lane_description_map(lane_description_map),
turn_analysis(turn_analysis), id_map(id_map) turn_analysis(turn_analysis), id_map(id_map)

View File

@ -1,12 +1,13 @@
#include "extractor/guidance/turn_lane_matcher.hpp" #include "extractor/guidance/turn_lane_matcher.hpp"
#include "extractor/guidance/toolkit.hpp" #include "util/bearing.hpp"
#include "util/guidance/toolkit.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/numeric/conversion/cast.hpp> #include <boost/numeric/conversion/cast.hpp>
#include <functional> #include <functional>
using osrm::util::angularDeviation;
namespace osrm namespace osrm
{ {
namespace extractor namespace extractor
@ -53,8 +54,8 @@ DirectionModifier::Enum getMatchingModifier(const TurnLaneType::Mask tag)
// check whether a match of a given tag and a turn instruction can be seen as valid // check whether a match of a given tag and a turn instruction can be seen as valid
bool isValidMatch(const TurnLaneType::Mask tag, const TurnInstruction instruction) bool isValidMatch(const TurnLaneType::Mask tag, const TurnInstruction instruction)
{ {
using util::guidance::hasLeftModifier; using extractor::guidance::hasLeftModifier;
using util::guidance::hasRightModifier; using extractor::guidance::hasRightModifier;
const auto isMirroredModifier = [](const TurnInstruction instruction) { const auto isMirroredModifier = [](const TurnInstruction instruction) {
return instruction.type == TurnType::Merge; return instruction.type == TurnType::Merge;
}; };
@ -200,12 +201,13 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
const LaneDataVector &lane_data, const LaneDataVector &lane_data,
const util::NodeBasedDynamicGraph &node_based_graph, const util::NodeBasedDynamicGraph &node_based_graph,
const LaneDescriptionID lane_string_id, const LaneDescriptionID lane_string_id,
LaneDataIdMap &lane_data_to_id) util::guidance::LaneDataIdMap &lane_data_to_id)
{ {
std::size_t road_index = 1, lane = 0; std::size_t road_index = 1, lane = 0;
const auto matchRoad = [&](ConnectedRoad &road, const TurnLaneData &data) { const auto matchRoad = [&](ConnectedRoad &road, const TurnLaneData &data) {
LaneTupleIdPair key{{LaneID(data.to - data.from + 1), data.from}, lane_string_id}; util::guidance::LaneTupleIdPair key{{LaneID(data.to - data.from + 1), data.from},
lane_string_id};
auto lane_data_id = boost::numeric_cast<LaneDataID>(lane_data_to_id.size()); auto lane_data_id = boost::numeric_cast<LaneDataID>(lane_data_to_id.size());
const auto it = lane_data_to_id.find(key); const auto it = lane_data_to_id.find(key);

View File

@ -315,6 +315,49 @@ bool isCCW(const Coordinate first_coordinate,
return signedArea(first_coordinate, second_coordinate, third_coordinate) > 0; return signedArea(first_coordinate, second_coordinate, third_coordinate) > 0;
} }
std::pair<util::Coordinate, util::Coordinate>
leastSquareRegression(const std::vector<util::Coordinate> &coordinates)
{
BOOST_ASSERT(coordinates.size() >= 2);
double sum_lon = 0, sum_lat = 0, sum_lon_lat = 0, sum_lon_lon = 0;
double min_lon = static_cast<double>(toFloating(coordinates.front().lon));
double max_lon = static_cast<double>(toFloating(coordinates.front().lon));
for (const auto coord : coordinates)
{
min_lon = std::min(min_lon, static_cast<double>(toFloating(coord.lon)));
max_lon = std::max(max_lon, static_cast<double>(toFloating(coord.lon)));
sum_lon += static_cast<double>(toFloating(coord.lon));
sum_lon_lon +=
static_cast<double>(toFloating(coord.lon)) * static_cast<double>(toFloating(coord.lon));
sum_lat += static_cast<double>(toFloating(coord.lat));
sum_lon_lat +=
static_cast<double>(toFloating(coord.lon)) * static_cast<double>(toFloating(coord.lat));
}
const auto dividend = coordinates.size() * sum_lon_lat - sum_lon * sum_lat;
const auto divisor = coordinates.size() * sum_lon_lon - sum_lon * sum_lon;
if (std::abs(divisor) < std::numeric_limits<double>::epsilon())
return std::make_pair(coordinates.front(), coordinates.back());
// slope of the regression line
const auto slope = dividend / divisor;
const auto intercept = (sum_lat - slope * sum_lon) / coordinates.size();
const auto GetLatAtLon = [intercept,
slope](const util::FloatLongitude longitude) -> util::FloatLatitude {
return {intercept + slope * static_cast<double>((longitude))};
};
const util::Coordinate regression_first = {
toFixed(util::FloatLongitude{min_lon - 1}),
toFixed(util::FloatLatitude(GetLatAtLon(util::FloatLongitude{min_lon - 1})))};
const util::Coordinate regression_end = {
toFixed(util::FloatLongitude{max_lon + 1}),
toFixed(util::FloatLatitude(GetLatAtLon(util::FloatLongitude{max_lon + 1})))};
return {regression_first, regression_end};
}
} // ns coordinate_calculation } // ns coordinate_calculation
} // ns util } // ns util
} // ns osrm } // ns osrm

View File

@ -1,5 +1,5 @@
#include "util/guidance/bearing_class.hpp" #include "util/guidance/bearing_class.hpp"
#include "util/guidance/toolkit.hpp" #include "util/bearing.hpp"
#include <algorithm> #include <algorithm>
#include <boost/assert.hpp> #include <boost/assert.hpp>