Make intersection backwards compatible
For `depart` and `arrive` `step.intersections[0].{bearings|entry}` will have
only one entry.
This commit is contained in:
@@ -28,12 +28,10 @@ namespace guidance
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
Intersection intersectionFromGeometry(const WaypointType waypoint_type,
|
||||
const double segment_duration,
|
||||
const LegGeometry &leg_geometry,
|
||||
const std::size_t segment_index);
|
||||
|
||||
std::pair<short, short> getDepartBearings(const LegGeometry &leg_geometry);
|
||||
std::pair<short, short> getArriveBearings(const LegGeometry &leg_geometry);
|
||||
std::pair<short, short> getIntermediateBearings(const LegGeometry &leg_geometry,
|
||||
const std::size_t segment_index);
|
||||
} // ns detail
|
||||
|
||||
template <typename DataFacadeT>
|
||||
@@ -65,16 +63,19 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
std::size_t segment_index = 0;
|
||||
BOOST_ASSERT(leg_geometry.locations.size() >= 2);
|
||||
|
||||
auto bearings = detail::getDepartBearings(leg_geometry);
|
||||
std::cout << "depart bearings: " << bearings.first << "->" << bearings.second << std::endl;
|
||||
|
||||
StepManeuver maneuver{source_node.location, bearings.first,
|
||||
bearings.second, extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart, 0};
|
||||
Intersection intersection{
|
||||
source_node.location,
|
||||
std::vector<short>({bearings.second}),
|
||||
std::vector<bool>({true}), Intersection::NO_INDEX, 0};
|
||||
|
||||
if (leg_data.size() > 0)
|
||||
{
|
||||
StepManeuver maneuver = {extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart, 0};
|
||||
|
||||
auto intersection =
|
||||
detail::intersectionFromGeometry(WaypointType::Depart, 0, leg_geometry, 0);
|
||||
intersection = util::guidance::setIntersectionClasses(std::move(intersection), source_node);
|
||||
// maneuver.location = source_node.location;
|
||||
|
||||
// PathData saves the information we need of the segment _before_ the turn,
|
||||
// but a RouteStep is with regard to the segment after the turn.
|
||||
// We need to skip the first segment because it is already covered by the
|
||||
@@ -95,16 +96,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
BOOST_ASSERT(segment_duration >= 0);
|
||||
const auto name = facade.GetNameForID(step_name_id);
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
std::vector<Intersection> intersections(1, intersection);
|
||||
intersection = detail::intersectionFromGeometry(
|
||||
WaypointType::None, segment_duration / 10., leg_geometry, segment_index);
|
||||
intersection.entry_class = facade.GetEntryClass(path_point.entry_classid);
|
||||
intersection.bearing_class =
|
||||
facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
|
||||
steps.push_back(RouteStep{
|
||||
step_name_id, name, NO_ROTARY_NAME, segment_duration / 10.0, distance,
|
||||
path_point.travel_mode, maneuver, leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1, std::move(intersections)});
|
||||
|
||||
if (leg_data_index + 1 < leg_data.size())
|
||||
{
|
||||
step_name_id = leg_data[leg_data_index + 1].name_id;
|
||||
@@ -113,7 +105,26 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
{
|
||||
step_name_id = target_node.name_id;
|
||||
}
|
||||
maneuver = {path_point.turn_instruction, WaypointType::None, 0};
|
||||
steps.push_back(RouteStep{
|
||||
step_name_id, name, NO_ROTARY_NAME, segment_duration / 10.0, distance,
|
||||
path_point.travel_mode, maneuver, leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
|
||||
|
||||
bearings = detail::getIntermediateBearings(leg_geometry, segment_index);
|
||||
const auto entry_class = facade.GetEntryClass(path_point.entry_classid);
|
||||
const auto bearing_class = facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
|
||||
intersection.in = bearing_class.findMatchingBearing(util::bearing::reverseBearing(bearings.first));
|
||||
intersection.out = bearing_class.findMatchingBearing(bearings.second);
|
||||
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
|
||||
intersection.bearings.clear();
|
||||
std::copy(bearing_class.getAvailableBearings().begin(), bearing_class.getAvailableBearings().end(),
|
||||
std::back_inserter(intersection.bearings));
|
||||
intersection.entry.clear();
|
||||
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
|
||||
{
|
||||
intersection.entry.push_back(entry_class.allowsEntry(idx));
|
||||
}
|
||||
maneuver = {intersection.location, bearings.first, bearings.second, path_point.turn_instruction, WaypointType::None, 0};
|
||||
segment_index++;
|
||||
segment_duration = 0;
|
||||
}
|
||||
@@ -124,7 +135,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
steps.push_back(RouteStep{
|
||||
step_name_id, facade.GetNameForID(step_name_id), NO_ROTARY_NAME, duration / 10.,
|
||||
distance, target_mode, maneuver, leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1, std::vector<Intersection>(1, intersection)});
|
||||
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
|
||||
}
|
||||
// In this case the source + target are on the same edge segment
|
||||
else
|
||||
@@ -135,38 +146,42 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
// |---| source_duration
|
||||
// |---------| target_duration
|
||||
|
||||
StepManeuver maneuver = {extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart, 0};
|
||||
int duration = target_duration - source_duration;
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
|
||||
auto intersection = detail::intersectionFromGeometry(WaypointType::Depart, duration / 10.,
|
||||
leg_geometry, segment_index);
|
||||
intersection = util::guidance::setIntersectionClasses(std::move(intersection), source_node);
|
||||
|
||||
steps.push_back(RouteStep{
|
||||
source_node.name_id, facade.GetNameForID(source_node.name_id), NO_ROTARY_NAME,
|
||||
duration / 10., leg_geometry.segment_distances[segment_index], source_mode,
|
||||
std::move(maneuver), leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1, std::vector<Intersection>(1, intersection)});
|
||||
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
|
||||
}
|
||||
|
||||
BOOST_ASSERT(segment_index == number_of_segments - 1);
|
||||
bearings = detail::getArriveBearings(leg_geometry);
|
||||
// This step has length zero, the only reason we need it is the target location
|
||||
StepManeuver final_maneuver = {extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Arrive, 0};
|
||||
|
||||
auto intersection =
|
||||
detail::intersectionFromGeometry(WaypointType::Arrive, 0, leg_geometry, segment_index);
|
||||
intersection = util::guidance::setIntersectionClasses(std::move(intersection), target_node);
|
||||
maneuver = {intersection.location, bearings.first, bearings.second, extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Arrive, 0};
|
||||
intersection = {
|
||||
target_node.location,
|
||||
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
|
||||
std::vector<bool>({true}), 0, Intersection::NO_INDEX};
|
||||
|
||||
BOOST_ASSERT(!leg_geometry.locations.empty());
|
||||
steps.push_back(RouteStep{target_node.name_id, facade.GetNameForID(target_node.name_id),
|
||||
NO_ROTARY_NAME, ZERO_DURATION, ZERO_DISTANCE, target_mode,
|
||||
std::move(final_maneuver), leg_geometry.locations.size() - 1,
|
||||
std::move(maneuver), leg_geometry.locations.size() - 1,
|
||||
leg_geometry.locations.size(),
|
||||
std::vector<Intersection>(1, intersection)});
|
||||
{intersection}});
|
||||
|
||||
|
||||
BOOST_ASSERT(steps.front().intersections.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().entry.size() == 1);
|
||||
BOOST_ASSERT(steps.front().maneuver.waypoint_type == WaypointType::Depart);
|
||||
|
||||
BOOST_ASSERT(steps.back().intersections.size() == 1);
|
||||
BOOST_ASSERT(steps.back().intersections.front().bearings.size() == 1);
|
||||
BOOST_ASSERT(steps.back().intersections.front().entry.size() == 1);
|
||||
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
|
||||
return steps;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,24 +28,21 @@ namespace guidance
|
||||
// A represenetation of intermediate intersections
|
||||
struct Intersection
|
||||
{
|
||||
double duration;
|
||||
double distance;
|
||||
static const constexpr std::size_t NO_INDEX = std::numeric_limits<std::size_t>::max();
|
||||
util::Coordinate location;
|
||||
double bearing_before;
|
||||
double bearing_after;
|
||||
util::guidance::EntryClass entry_class;
|
||||
util::guidance::BearingClass bearing_class;
|
||||
std::vector<short> bearings;
|
||||
std::vector<bool> entry;
|
||||
std::size_t in;
|
||||
std::size_t out;
|
||||
};
|
||||
|
||||
inline Intersection getInvalidIntersection()
|
||||
{
|
||||
return {0,
|
||||
0,
|
||||
util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
|
||||
0,
|
||||
0,
|
||||
util::guidance::EntryClass(),
|
||||
util::guidance::BearingClass()};
|
||||
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
|
||||
{},
|
||||
{},
|
||||
Intersection::NO_INDEX,
|
||||
Intersection::NO_INDEX};
|
||||
}
|
||||
|
||||
struct RouteStep
|
||||
@@ -74,7 +71,7 @@ inline RouteStep getInvalidRouteStep()
|
||||
getInvalidStepManeuver(),
|
||||
0,
|
||||
0,
|
||||
std::vector<Intersection>(1, getInvalidIntersection())};
|
||||
{getInvalidIntersection()}};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ enum class WaypointType : std::uint8_t
|
||||
|
||||
struct StepManeuver
|
||||
{
|
||||
util::Coordinate location;
|
||||
short bearing_before;
|
||||
short bearing_after;
|
||||
extractor::guidance::TurnInstruction instruction;
|
||||
WaypointType waypoint_type;
|
||||
unsigned exit;
|
||||
@@ -30,7 +33,12 @@ struct StepManeuver
|
||||
|
||||
inline StepManeuver getInvalidStepManeuver()
|
||||
{
|
||||
return {extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::None, 0};
|
||||
return {util::Coordinate{util::FloatLongitude{0.0}, util::FloatLatitude{0.0}},
|
||||
0,
|
||||
0,
|
||||
extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::None,
|
||||
0};
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -89,6 +89,14 @@ inline bool CheckInBounds(const int A, const int B, const int range)
|
||||
return normalized_B - range <= normalized_A && normalized_A <= normalized_B + range;
|
||||
}
|
||||
}
|
||||
|
||||
inline double reverseBearing(const double bearing)
|
||||
{
|
||||
if (bearing >= 180)
|
||||
return bearing - 180.;
|
||||
return bearing + 180;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,36 +49,6 @@ inline extractor::guidance::DirectionModifier getTurnDirection(const double angl
|
||||
return extractor::guidance::DirectionModifier::UTurn;
|
||||
}
|
||||
|
||||
inline engine::guidance::Intersection
|
||||
setIntersectionClasses(engine::guidance::Intersection intersection,
|
||||
const engine::PhantomNode &phantom)
|
||||
{
|
||||
BOOST_ASSERT(intersection.bearing_before == 0 || intersection.bearing_after == 0);
|
||||
const double bearing = std::max(intersection.bearing_before, intersection.bearing_after);
|
||||
|
||||
intersection.bearing_class = {};
|
||||
intersection.entry_class = {};
|
||||
if (bearing >= 180.)
|
||||
{
|
||||
intersection.bearing_class.add(std::round(bearing - 180.));
|
||||
if (phantom.forward_segment_id.id != SPECIAL_SEGMENTID &&
|
||||
phantom.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
||||
intersection.entry_class.activate(0);
|
||||
intersection.bearing_class.add(std::round(bearing));
|
||||
intersection.entry_class.activate(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection.bearing_class.add(std::round(bearing));
|
||||
intersection.entry_class.activate(0);
|
||||
intersection.bearing_class.add(std::round(bearing + 180.));
|
||||
if (phantom.forward_segment_id.id != SPECIAL_SEGMENTID &&
|
||||
phantom.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
||||
intersection.entry_class.activate(1);
|
||||
}
|
||||
return intersection;
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
|
||||
Reference in New Issue
Block a user