add a toolkit function to find lanes to the left/right of turn lanes
This commit is contained in:
committed by
Moritz Kobitzsch
parent
17eb664597
commit
72fa35da10
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "engine/guidance/post_processing.hpp"
|
||||
#include "engine/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include <iterator>
|
||||
#include <unordered_set>
|
||||
@@ -16,6 +16,8 @@ namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier;
|
||||
|
||||
using osrm::util::guidance::isLeftTurn;
|
||||
using osrm::util::guidance::isRightTurn;
|
||||
using osrm::extractor::guidance::numLanesToTheRight;
|
||||
using osrm::extractor::guidance::numLanesToTheLeft;
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -80,12 +82,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
|
||||
// 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.
|
||||
const LaneID current_num_all_lanes =
|
||||
current.intersections.front().lane_description.size();
|
||||
const LaneID current_num_lanes_right_of_turn = current_lanes.first_lane_from_the_right;
|
||||
const LaneID current_num_lanes_left_of_turn =
|
||||
current_num_all_lanes -
|
||||
(current_lanes.lanes_in_turn + current_num_lanes_right_of_turn);
|
||||
const LaneID current_num_lanes_right_of_turn = numLanesToTheRight(current);
|
||||
const LaneID current_num_lanes_left_of_turn = numLanesToTheLeft(current);
|
||||
|
||||
const LaneID num_shared_lanes = std::min(current_lanes.lanes_in_turn, //
|
||||
previous_lanes.lanes_in_turn); //
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "engine/guidance/post_processing.hpp"
|
||||
|
||||
@@ -12,6 +13,7 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/range/algorithm_ext/erase.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
@@ -1040,7 +1042,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
||||
designated_depart.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
// we need to make this conform with the intersection format for the first intersection
|
||||
auto &first_intersection = designated_depart.intersections.front();
|
||||
designated_depart.intersections.front().lanes = util::guidance::LaneTupel();
|
||||
designated_depart.intersections.front().lanes = util::guidance::LaneTuple();
|
||||
designated_depart.intersections.front().lane_description.clear();
|
||||
first_intersection.bearings = {first_intersection.bearings[first_intersection.out]};
|
||||
first_intersection.entry = {true};
|
||||
@@ -1110,7 +1112,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
||||
next_to_last_step.maneuver.waypoint_type = WaypointType::Arrive;
|
||||
next_to_last_step.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
next_to_last_step.maneuver.bearing_after = 0;
|
||||
next_to_last_step.intersections.front().lanes = util::guidance::LaneTupel();
|
||||
next_to_last_step.intersections.front().lanes = util::guidance::LaneTuple();
|
||||
next_to_last_step.intersections.front().lane_description.clear();
|
||||
next_to_last_step.geometry_end = next_to_last_step.geometry_begin + 1;
|
||||
BOOST_ASSERT(next_to_last_step.intersections.size() == 1);
|
||||
@@ -1282,6 +1284,9 @@ std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps)
|
||||
return removeNoTurnInstructions(std::move(steps));
|
||||
}
|
||||
|
||||
// `useLane` steps are only returned on `straight` maneuvers when there
|
||||
// are surrounding lanes also tagged as `straight`. If there are no other `straight`
|
||||
// lanes, it is not an ambiguous maneuver, and we can collapse the `useLane` step.
|
||||
std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps)
|
||||
{
|
||||
const auto containsTag = [](const extractor::guidance::TurnLaneType::Mask mask,
|
||||
@@ -1299,33 +1304,30 @@ std::vector<RouteStep> collapseUseLane(std::vector<RouteStep> steps)
|
||||
return index;
|
||||
};
|
||||
|
||||
const auto canCollapeUseLane =
|
||||
[containsTag](const util::guidance::LaneTupel lanes,
|
||||
extractor::guidance::TurnLaneDescription lane_description) {
|
||||
// the lane description is given left to right, lanes are counted from the right.
|
||||
// Therefore we access the lane description using the reverse iterator
|
||||
if (lanes.first_lane_from_the_right > 0 &&
|
||||
containsTag(*(lane_description.rbegin() + (lanes.first_lane_from_the_right - 1)),
|
||||
(extractor::guidance::TurnLaneType::straight |
|
||||
extractor::guidance::TurnLaneType::none)))
|
||||
return false;
|
||||
const auto canCollapseUseLane = [containsTag](const RouteStep &step) {
|
||||
// the lane description is given left to right, lanes are counted from the right.
|
||||
// Therefore we access the lane description using the reverse iterator
|
||||
|
||||
const auto lane_to_the_right = lanes.first_lane_from_the_right + lanes.lanes_in_turn;
|
||||
if (lane_to_the_right < boost::numeric_cast<int>(lane_description.size()) &&
|
||||
containsTag(*(lane_description.rbegin() + lane_to_the_right),
|
||||
(extractor::guidance::TurnLaneType::straight |
|
||||
extractor::guidance::TurnLaneType::none)))
|
||||
return false;
|
||||
auto right_most_lanes = extractor::guidance::lanesToTheRight(step);
|
||||
if (!right_most_lanes.empty() && containsTag(right_most_lanes.front(),
|
||||
(extractor::guidance::TurnLaneType::straight |
|
||||
extractor::guidance::TurnLaneType::none)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
auto left_most_lanes = extractor::guidance::lanesToTheLeft(step);
|
||||
if (!left_most_lanes.empty() && containsTag(left_most_lanes.back(),
|
||||
(extractor::guidance::TurnLaneType::straight |
|
||||
extractor::guidance::TurnLaneType::none)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
for (std::size_t step_index = 1; step_index < steps.size(); ++step_index)
|
||||
{
|
||||
const auto &step = steps[step_index];
|
||||
if (step.maneuver.instruction.type == TurnType::UseLane &&
|
||||
canCollapeUseLane(step.intersections.front().lanes,
|
||||
step.intersections.front().lane_description))
|
||||
canCollapseUseLane(step))
|
||||
{
|
||||
const auto previous = getPreviousIndex(step_index);
|
||||
steps[previous] = elongate(std::move(steps[previous]), steps[step_index]);
|
||||
|
||||
@@ -564,7 +564,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
util::SimpleLogger().Write() << "Writing Turn Lane Data to File...";
|
||||
std::ofstream turn_lane_data_file(turn_lane_data_filename.c_str(), std::ios::binary);
|
||||
std::vector<util::guidance::LaneTupelIdPair> lane_data(lane_data_map.size());
|
||||
std::vector<util::guidance::LaneTupleIdPair> lane_data(lane_data_map.size());
|
||||
// extract lane data sorted by ID
|
||||
for (auto itr : lane_data_map)
|
||||
lane_data[itr.second] = itr.first;
|
||||
@@ -574,7 +574,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
if (!lane_data.empty())
|
||||
turn_lane_data_file.write(reinterpret_cast<const char *>(&lane_data[0]),
|
||||
sizeof(util::guidance::LaneTupelIdPair) * lane_data.size());
|
||||
sizeof(util::guidance::LaneTupleIdPair) * lane_data.size());
|
||||
|
||||
util::SimpleLogger().Write() << "done.";
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
|
||||
std::size_t road_index = 1, lane = 0;
|
||||
|
||||
const auto matchRoad = [&](ConnectedRoad &road, const TurnLaneData &data) {
|
||||
LaneTupelIdPair key{{LaneID(data.to - data.from + 1), data.from}, lane_string_id};
|
||||
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());
|
||||
const auto it = lane_data_to_id.find(key);
|
||||
|
||||
@@ -388,7 +388,7 @@ int Storage::Run()
|
||||
boost::filesystem::ifstream lane_data_stream(config.turn_lane_data_path, std::ios::binary);
|
||||
std::uint64_t lane_tupel_count = 0;
|
||||
lane_data_stream.read(reinterpret_cast<char *>(&lane_tupel_count), sizeof(lane_tupel_count));
|
||||
shared_layout_ptr->SetBlockSize<util::guidance::LaneTupelIdPair>(
|
||||
shared_layout_ptr->SetBlockSize<util::guidance::LaneTupleIdPair>(
|
||||
SharedDataLayout::TURN_LANE_DATA, lane_tupel_count);
|
||||
|
||||
if (!static_cast<bool>(intersection_stream))
|
||||
@@ -463,7 +463,7 @@ int Storage::Run()
|
||||
|
||||
// make sure do write canary...
|
||||
auto *turn_lane_data_ptr =
|
||||
shared_layout_ptr->GetBlockPtr<util::guidance::LaneTupelIdPair, true>(
|
||||
shared_layout_ptr->GetBlockPtr<util::guidance::LaneTupleIdPair, true>(
|
||||
shared_memory_ptr, SharedDataLayout::TURN_LANE_DATA);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::TURN_LANE_DATA) > 0)
|
||||
{
|
||||
|
||||
@@ -12,24 +12,24 @@ namespace util
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
LaneTupel::LaneTupel() : lanes_in_turn(0), first_lane_from_the_right(INVALID_LANEID)
|
||||
LaneTuple::LaneTuple() : lanes_in_turn(0), first_lane_from_the_right(INVALID_LANEID)
|
||||
{
|
||||
// basic constructor, set everything to zero
|
||||
}
|
||||
|
||||
LaneTupel::LaneTupel(const LaneID lanes_in_turn, const LaneID first_lane_from_the_right)
|
||||
LaneTuple::LaneTuple(const LaneID lanes_in_turn, const LaneID first_lane_from_the_right)
|
||||
: lanes_in_turn(lanes_in_turn), first_lane_from_the_right(first_lane_from_the_right)
|
||||
{
|
||||
}
|
||||
|
||||
// comparation based on interpretation as unsigned 32bit integer
|
||||
bool LaneTupel::operator==(const LaneTupel other) const
|
||||
bool LaneTuple::operator==(const LaneTuple other) const
|
||||
{
|
||||
return std::tie(lanes_in_turn, first_lane_from_the_right) ==
|
||||
std::tie(other.lanes_in_turn, other.first_lane_from_the_right);
|
||||
}
|
||||
|
||||
bool LaneTupel::operator!=(const LaneTupel other) const { return !(*this == other); }
|
||||
bool LaneTuple::operator!=(const LaneTuple other) const { return !(*this == other); }
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace util
|
||||
|
||||
Reference in New Issue
Block a user