Make intersection backwards compatible

For `depart` and `arrive` `step.intersections[0].{bearings|entry}` will have
only one entry.
This commit is contained in:
Patrick Niklaus
2016-05-18 17:53:05 +02:00
parent 3b37769624
commit 95af72c70c
10 changed files with 272 additions and 235 deletions
+56 -41
View File
@@ -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;
}
+11 -14
View File
@@ -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()}};
}
}
}
+9 -1
View File
@@ -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
+8
View File
@@ -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;
}
}
}
}
-30
View File
@@ -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