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:
parent
a28a20a1ba
commit
df3c39cef5
@ -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"
|
||||||
|
@ -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,
|
||||||
|
53
include/engine/guidance/postprocessing_toolkit.hpp
Normal file
53
include/engine/guidance/postprocessing_toolkit.hpp
Normal 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_ */
|
@ -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()
|
||||||
|
@ -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_ */
|
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
112
include/extractor/guidance/parsing_toolkit.hpp
Normal file
112
include/extractor/guidance/parsing_toolkit.hpp
Normal 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_
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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_
|
|
@ -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"
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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_ */
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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>
|
||||||
|
@ -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); //
|
||||||
|
@ -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)))
|
||||||
|
@ -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,
|
||||||
|
@ -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>
|
||||||
|
@ -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())
|
||||||
|
@ -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
|
||||||
|
@ -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 =
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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));
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user